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));
 

Reply via email to