Hi,
On Wed, 10 Oct 2018 08:00:14 +0900 (JST)
Masato Asou <[email protected]> wrote:
> When I use /usr/bin/bc command with MALLOC_OPTIONS=UJ, SEGV was
> occurred in libedit.
>
> $ MALLOC_OPTIONS=UJ /usr/bin/bc
> 100000 + 200000 + 300000 + 400000 + 500000 + 600000 + 700000 + 800000 +
> 900000 + Segmentation fault (core dumped)
Yes, it repeats.
- appending chars beyond the terminal width
- then hit <Backspace>
sometime causes SIGSEGV.
I think the root problem is that
- In re_fastputc() case (simply appendding a char)
- The line buffers other than first line is not initialized before
being used.
In re_fastputc():
1068 if (el->el_cursor.h >= el->el_terminal.t_size.h) {
if new line begin,
1069 /* if we must overflow */
1070 el->el_cursor.h = 0;
1071
1072 /*
1073 * If we would overflow (input is longer than terminal
size),
1074 * emulate scroll by dropping first line and shuffling
the rest.
1075 * We do this via pointer shuffling - it's safe in this
case
1076 * and we avoid memcpy().
1077 */
1078 if (el->el_cursor.v + 1 >= el->el_terminal.t_size.v) {
if it was at the last line of the terminal
1079 int i, lins = el->el_terminal.t_size.v;
1080 lastline = el->el_display[0];
1081 for(i = 1; i < lins; i++)
1082 el->el_display[i - 1] =
el->el_display[i];
1083 el->el_display[i - 1] = lastline;
1084 } else {
1085 el->el_cursor.v++;
1086 lastline =
el->el_display[el->el_refresh.r_oldcv++];
1087 }
1088 re__copy_and_pad(lastline, L"",
el->el_terminal.t_size.h);
initialize new line.
See #1086, "lastline" is set to previous lastline. Then new line is not
initialized.
I think the following diff is better since it initializes the line in
the same way for first line.
diff --git a/lib/libedit/refresh.c b/lib/libedit/refresh.c
index f2d001d67cb..9bf46faa777 100644
--- a/lib/libedit/refresh.c
+++ b/lib/libedit/refresh.c
@@ -1083,7 +1083,7 @@ re_fastputc(EditLine *el, wint_t c)
el->el_display[i - 1] = lastline;
} else {
el->el_cursor.v++;
- lastline = el->el_display[el->el_refresh.r_oldcv++];
+ lastline = el->el_display[++el->el_refresh.r_oldcv];
}
re__copy_and_pad(lastline, L"", el->el_terminal.t_size.h);