Roman Rakus 7a77b7
			     BASH PATCH REPORT
Roman Rakus 7a77b7
			     =================
Roman Rakus 7a77b7
Roman Rakus 7a77b7
Bash-Release:	4.2
Roman Rakus 7a77b7
Patch-ID:	bash42-012
Roman Rakus 7a77b7
Roman Rakus 7a77b7
Bug-Reported-by:	Rui Santos <rsantos@grupopie.com>
Roman Rakus 7a77b7
Bug-Reference-ID:	<4E04C6D0.2020507@grupopie.com>
Roman Rakus 7a77b7
Bug-Reference-URL:	http://lists.gnu.org/archive/html/bug-bash/2011-06/msg00079.html
Roman Rakus 7a77b7
Roman Rakus 7a77b7
Bug-Description:
Roman Rakus 7a77b7
Roman Rakus 7a77b7
When calling the parser to recursively parse a command substitution within
Roman Rakus 7a77b7
an arithmetic expansion, the shell overwrote the saved shell input line and
Roman Rakus 7a77b7
associated state, resulting in a garbled command.
Roman Rakus 7a77b7
Roman Rakus 7a77b7
Patch (apply with `patch -p0'):
Roman Rakus 7a77b7
Roman Rakus 7a77b7
*** ../bash-4.2-patched/parse.y	2011-02-26 19:19:05.000000000 -0500
Roman Rakus 7a77b7
--- parse.y	2011-06-24 20:08:22.000000000 -0400
Roman Rakus 7a77b7
***************
Roman Rakus 7a77b7
*** 3843,3846 ****
Roman Rakus 7a77b7
--- 3849,3853 ----
Roman Rakus 7a77b7
  {
Roman Rakus 7a77b7
    sh_parser_state_t ps;
Roman Rakus 7a77b7
+   sh_input_line_state_t ls;
Roman Rakus 7a77b7
    int orig_ind, nc, sflags;
Roman Rakus 7a77b7
    char *ret, *s, *ep, *ostring;
Roman Rakus 7a77b7
***************
Roman Rakus 7a77b7
*** 3850,3857 ****
Roman Rakus 7a77b7
--- 3857,3866 ----
Roman Rakus 7a77b7
    ostring = string;
Roman Rakus 7a77b7
  
Roman Rakus 7a77b7
+ /*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/
Roman Rakus 7a77b7
    sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
Roman Rakus 7a77b7
    if (flags & SX_NOLONGJMP)
Roman Rakus 7a77b7
      sflags |= SEVAL_NOLONGJMP;
Roman Rakus 7a77b7
    save_parser_state (&ps);
Roman Rakus 7a77b7
+   save_input_line_state (&ls);
Roman Rakus 7a77b7
  
Roman Rakus 7a77b7
    /*(*/
Roman Rakus 7a77b7
***************
Roman Rakus 7a77b7
*** 3862,3865 ****
Roman Rakus 7a77b7
--- 3871,3876 ----
Roman Rakus 7a77b7
    restore_parser_state (&ps);
Roman Rakus 7a77b7
    reset_parser ();
Roman Rakus 7a77b7
+   /* reset_parser clears shell_input_line and associated variables */
Roman Rakus 7a77b7
+   restore_input_line_state (&ls);
Roman Rakus 7a77b7
    if (interactive)
Roman Rakus 7a77b7
      token_to_read = 0;
Roman Rakus 7a77b7
***************
Roman Rakus 7a77b7
*** 5909,5912 ****
Roman Rakus 7a77b7
--- 5920,5929 ----
Roman Rakus 7a77b7
    ps->echo_input_at_read = echo_input_at_read;
Roman Rakus 7a77b7
  
Roman Rakus 7a77b7
+   ps->token = token;
Roman Rakus 7a77b7
+   ps->token_buffer_size = token_buffer_size;
Roman Rakus 7a77b7
+   /* Force reallocation on next call to read_token_word */
Roman Rakus 7a77b7
+   token = 0;
Roman Rakus 7a77b7
+   token_buffer_size = 0;
Roman Rakus 7a77b7
+ 
Roman Rakus 7a77b7
    return (ps);
Roman Rakus 7a77b7
  }
Roman Rakus 7a77b7
***************
Roman Rakus 7a77b7
*** 5950,5953 ****
Roman Rakus 7a77b7
--- 5967,6006 ----
Roman Rakus 7a77b7
    expand_aliases = ps->expand_aliases;
Roman Rakus 7a77b7
    echo_input_at_read = ps->echo_input_at_read;
Roman Rakus 7a77b7
+ 
Roman Rakus 7a77b7
+   FREE (token);
Roman Rakus 7a77b7
+   token = ps->token;
Roman Rakus 7a77b7
+   token_buffer_size = ps->token_buffer_size;
Roman Rakus 7a77b7
+ }
Roman Rakus 7a77b7
+ 
Roman Rakus 7a77b7
+ sh_input_line_state_t *
Roman Rakus 7a77b7
+ save_input_line_state (ls)
Roman Rakus 7a77b7
+      sh_input_line_state_t *ls;
Roman Rakus 7a77b7
+ {
Roman Rakus 7a77b7
+   if (ls == 0)
Roman Rakus 7a77b7
+     ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t));
Roman Rakus 7a77b7
+   if (ls == 0)
Roman Rakus 7a77b7
+     return ((sh_input_line_state_t *)NULL);
Roman Rakus 7a77b7
+ 
Roman Rakus 7a77b7
+   ls->input_line = shell_input_line;
Roman Rakus 7a77b7
+   ls->input_line_size = shell_input_line_size;
Roman Rakus 7a77b7
+   ls->input_line_len = shell_input_line_len;
Roman Rakus 7a77b7
+   ls->input_line_index = shell_input_line_index;
Roman Rakus 7a77b7
+ 
Roman Rakus 7a77b7
+   /* force reallocation */
Roman Rakus 7a77b7
+   shell_input_line = 0;
Roman Rakus 7a77b7
+   shell_input_line_size = shell_input_line_len = shell_input_line_index = 0;
Roman Rakus 7a77b7
+ }
Roman Rakus 7a77b7
+ 
Roman Rakus 7a77b7
+ void
Roman Rakus 7a77b7
+ restore_input_line_state (ls)
Roman Rakus 7a77b7
+      sh_input_line_state_t *ls;
Roman Rakus 7a77b7
+ {
Roman Rakus 7a77b7
+   FREE (shell_input_line);
Roman Rakus 7a77b7
+   shell_input_line = ls->input_line;
Roman Rakus 7a77b7
+   shell_input_line_size = ls->input_line_size;
Roman Rakus 7a77b7
+   shell_input_line_len = ls->input_line_len;
Roman Rakus 7a77b7
+   shell_input_line_index = ls->input_line_index;
Roman Rakus 7a77b7
+ 
Roman Rakus 7a77b7
+   set_line_mbstate ();
Roman Rakus 7a77b7
  }
Roman Rakus 7a77b7
  
Roman Rakus 7a77b7
*** ../bash-4.2-patched/shell.h	2011-01-06 22:16:55.000000000 -0500
Roman Rakus 7a77b7
--- shell.h	2011-06-24 19:12:25.000000000 -0400
Roman Rakus 7a77b7
***************
Roman Rakus 7a77b7
*** 137,140 ****
Roman Rakus 7a77b7
--- 139,145 ----
Roman Rakus 7a77b7
    int *token_state;
Roman Rakus 7a77b7
  
Roman Rakus 7a77b7
+   char *token;
Roman Rakus 7a77b7
+   int token_buffer_size;
Roman Rakus 7a77b7
+ 
Roman Rakus 7a77b7
    /* input line state -- line number saved elsewhere */
Roman Rakus 7a77b7
    int input_line_terminator;
Roman Rakus 7a77b7
***************
Roman Rakus 7a77b7
*** 167,171 ****
Roman Rakus 7a77b7
--- 172,186 ----
Roman Rakus 7a77b7
  } sh_parser_state_t;
Roman Rakus 7a77b7
  
Roman Rakus 7a77b7
+ typedef struct _sh_input_line_state_t {
Roman Rakus 7a77b7
+   char *input_line;
Roman Rakus 7a77b7
+   int input_line_index;
Roman Rakus 7a77b7
+   int input_line_size;
Roman Rakus 7a77b7
+   int input_line_len;
Roman Rakus 7a77b7
+ } sh_input_line_state_t;
Roman Rakus 7a77b7
+ 
Roman Rakus 7a77b7
  /* Let's try declaring these here. */
Roman Rakus 7a77b7
  extern sh_parser_state_t *save_parser_state __P((sh_parser_state_t *));
Roman Rakus 7a77b7
  extern void restore_parser_state __P((sh_parser_state_t *));
Roman Rakus 7a77b7
+ 
Roman Rakus 7a77b7
+ extern sh_input_line_state_t *save_input_line_state __P((sh_input_line_state_t *));
Roman Rakus 7a77b7
+ extern void restore_input_line_state __P((sh_input_line_state_t *));
Roman Rakus 7a77b7
*** ../bash-4.2-patched/patchlevel.h	Sat Jun 12 20:14:48 2010
Roman Rakus 7a77b7
--- patchlevel.h	Thu Feb 24 21:41:34 2011
Roman Rakus 7a77b7
***************
Roman Rakus 7a77b7
*** 26,30 ****
Roman Rakus 7a77b7
     looks for to find the patch level (for the sccs version string). */
Roman Rakus 7a77b7
  
Roman Rakus 7a77b7
! #define PATCHLEVEL 11
Roman Rakus 7a77b7
  
Roman Rakus 7a77b7
  #endif /* _PATCHLEVEL_H_ */
Roman Rakus 7a77b7
--- 26,30 ----
Roman Rakus 7a77b7
     looks for to find the patch level (for the sccs version string). */
Roman Rakus 7a77b7
  
Roman Rakus 7a77b7
! #define PATCHLEVEL 12
Roman Rakus 7a77b7
  
Roman Rakus 7a77b7
  #endif /* _PATCHLEVEL_H_ */