On Thu, Mar 27, 2014 at 07:36:56PM +0100, Matthias Klose wrote: > seen when entering q!, then leaving the shell with ^D > > $ gdb bash > (gdb) run > Starting program: /bin/bash > doko@gb:~$ q! > q!: Befehl nicht gefunden. > doko@gb:~$ > malloc: .././parse.y:2314: assertion botched > realloc: start and end chunk sizes differ > last command: q! > Aborting... > Program received signal SIGABRT, Aborted. > 0x00007ffff761df79 in raise () from /lib/x86_64-linux-gnu/libc.so.6 > (gdb) bt > #0 0x00007ffff761df79 in raise () from /lib/x86_64-linux-gnu/libc.so.6 > #1 0x00007ffff7621388 in abort () from /lib/x86_64-linux-gnu/libc.so.6 > #2 0x000000000044054f in programming_error () > #3 0x00000000004b4bc0 in ?? () > #4 0x0000000000472bb6 in sh_xrealloc () > #5 0x0000000000423879 in ?? () > #6 0x0000000000426612 in ?? () > #7 0x0000000000429c39 in yyparse () > #8 0x0000000000420ebb in parse_command () > #9 0x0000000000420f8c in read_command () > #10 0x0000000000421189 in reader_loop () > #11 0x000000000041f729 in main () > (gdb) quit >
I noticed that this just happens for a single character, followed by the '!', when history expansion is enabled: | dualbus@debian ~ % bash | bash-4.3$ a! | bash: a!: command not found | bash-4.3$ | malloc: ./parse.y:2314: assertion botched | realloc: start and end chunk sizes differ | last command: a! | Aborting...zsh: abort bash | dualbus@debian ~ % bash | bash-4.3$ aa! | bash: aa!: command not found | bash-4.3$ exit | dualbus@debian ~ % bash | bash-4.3$ set +H | bash-4.3$ a! | bash: a!: command not found | bash-4.3$ exit This is the change that introduced the error: | % git show 36eb585cfa52fbb6cd0c324c628593ea856a50a5 -- parse.y And I've attached a patch (well, it's basically just a revert of part of that change), that "fixes" the issue. I blindly reverted, so I don't know what error was that specific patch supposed to fix in the first place. Take my patch just as a pointer of where the issue is. -- Eduardo Alan Bustamante López
diff --git a/parse.y b/parse.y index 83d5b9f..5e3ccde 100644 --- a/parse.y +++ b/parse.y @@ -2288,30 +2288,7 @@ shell_getc (remove_quoted_newline) continue; } - /* Theoretical overflow */ - /* If we can't put 256 bytes more into the buffer, allocate - everything we can and fill it as full as we can. */ - /* XXX - we ignore rest of line using `truncating' flag */ - if (shell_input_line_size > (SIZE_MAX - 256)) - { - size_t n; - - n = SIZE_MAX - i; /* how much more can we put into the buffer? */ - if (n <= 2) /* we have to save 1 for the newline added below */ - { - if (truncating == 0) - internal_warning("shell_getc: shell_input_line_size (%zu) exceeds SIZE_MAX (%llu): line truncated", shell_input_line_size, SIZE_MAX); - shell_input_line[i] = '\0'; - truncating = 1; - } - if (shell_input_line_size < SIZE_MAX) - { - shell_input_line_size = SIZE_MAX; - shell_input_line = xrealloc (shell_input_line, shell_input_line_size); - } - } - else - RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256); + RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256); if (c == EOF) { @@ -2424,7 +2401,7 @@ shell_getc (remove_quoted_newline) not already end in an EOF character. */ if (shell_input_line_terminator != EOF) { - if (shell_input_line_size < SIZE_MAX && shell_input_line_len > shell_input_line_size - 3) + if (shell_input_line_len + 3 > shell_input_line_size) shell_input_line = (char *)xrealloc (shell_input_line, 1 + (shell_input_line_size += 2));