bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bash-4.0 Official Patch 1


From: Chet Ramey
Subject: Bash-4.0 Official Patch 1
Date: Tue, 10 Mar 2009 09:16:55 -0400

                             BASH PATCH REPORT
                             =================

Bash-Release: 4.0
Patch-ID: bash40-001

Bug-Reported-by:        Mike Frysinger <address@hidden>
Bug-Reference-ID:       <address@hidden>
Bug-Reference-URL:      
http://lists.gnu.org/archive/html/bug-bash/2009-02/msg00147.html

Bug-Description:

Bash has problems parsing certain constructs inside Posix-style $(...)
command substitutions, mostly with backslash-quoting and reserved word
recognition.    This is an issue because the contents are parsed at the
time the word containing the command substitution is read.

Patch:

*** ../bash-4.0/parse.y 2009-01-08 08:29:12.000000000 -0500
--- parse.y     2009-03-06 20:32:35.000000000 -0500
***************
*** 2928,2931 ****
--- 2932,2936 ----
  #define LEX_HEREDELIM 0x100           /* reading here-doc delimiter */
  #define LEX_STRIPDOC  0x200           /* <<- strip tabs from here doc delim */
+ #define LEX_INWORD    0x400
  
  #define COMSUB_META(ch)               ((ch) == ';' || (ch) == '&' || (ch) == 
'|')
***************
*** 3180,3184 ****
       int *lenp, flags;
  {
!   int count, ch, peekc, tflags, lex_rwlen, lex_firstind;
    int nestlen, ttranslen, start_lineno;
    char *ret, *nestret, *ttrans, *heredelim;
--- 3188,3192 ----
       int *lenp, flags;
  {
!   int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
    int nestlen, ttranslen, start_lineno;
    char *ret, *nestret, *ttrans, *heredelim;
***************
*** 3201,3205 ****
  
    start_lineno = line_number;
!   lex_rwlen = 0;
  
    heredelim = 0;
--- 3209,3213 ----
  
    start_lineno = line_number;
!   lex_rwlen = lex_wlen = 0;
  
    heredelim = 0;
***************
*** 3268,3271 ****
--- 3276,3319 ----
        }
  
+       if (tflags & LEX_PASSNEXT)              /* last char was backslash */
+       {
+ /*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, 
ch, __LINE__);*/
+         tflags &= ~LEX_PASSNEXT;
+         if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. 
*/
+           {
+             if (retind > 0)
+               retind--;       /* swallow previously-added backslash */
+             continue;
+           }
+ 
+         RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
+         if MBTEST(ch == CTLESC || ch == CTLNUL)
+           ret[retind++] = CTLESC;
+         ret[retind++] = ch;
+         continue;
+       }
+ 
+       /* If this is a shell break character, we are not in a word.  If not,
+        we either start or continue a word. */
+       if MBTEST(shellbreak (ch))
+       {
+         tflags &= ~LEX_INWORD;
+ /*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, 
__LINE__);*/
+       }
+       else
+       {
+         if (tflags & LEX_INWORD)
+           {
+             lex_wlen++;
+ /*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", 
line_number, ch, lex_wlen, __LINE__);*/
+           }         
+         else
+           {
+ /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, 
__LINE__);*/
+             tflags |= LEX_INWORD;
+             lex_wlen = 0;
+           }
+       }
+ 
        /* Skip whitespace */
        if MBTEST(shellblank (ch) && lex_rwlen == 0)
***************
*** 3400,3428 ****
            }
          else
!           ch = peekc;         /* fall through and continue XXX - this skips 
comments if peekc == '#' */
        }
!       /* Not exactly right yet, should handle shell metacharacters, too.  If
!        any changes are made to this test, make analogous changes to subst.c:
!        extract_delimited_string(). */
!       else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 
0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank 
(ret[retind - 1])))
        tflags |= LEX_INCOMMENT;
  
!       if (tflags & LEX_PASSNEXT)              /* last char was backslash */
!       {
!         tflags &= ~LEX_PASSNEXT;
!         if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. 
*/
!           {
!             if (retind > 0)
!               retind--;       /* swallow previously-added backslash */
!             continue;
!           }
! 
!         RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
!         if MBTEST(ch == CTLESC || ch == CTLNUL)
!           ret[retind++] = CTLESC;
!         ret[retind++] = ch;
!         continue;
!       }
!       else if MBTEST(ch == CTLESC || ch == CTLNUL)    /* special shell 
escapes */
        {
          RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
--- 3442,3454 ----
            }
          else
!           ch = peekc;         /* fall through and continue XXX */
        }
!       else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 
0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & 
LEX_INWORD) && lex_wlen == 0)))
! {
! /*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
        tflags |= LEX_INCOMMENT;
+ }
  
!       if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
        {
          RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
*** ../bash-4.0/patchlevel.h    2009-01-04 14:32:40.000000000 -0500
--- patchlevel.h        2009-02-22 16:11:31.000000000 -0500
***************
*** 26,30 ****
     looks for to find the patch level (for the sccs version string). */
  
! #define PATCHLEVEL 0
  
  #endif /* _PATCHLEVEL_H_ */
--- 26,30 ----
     looks for to find the patch level (for the sccs version string). */
  
! #define PATCHLEVEL 1
  
  #endif /* _PATCHLEVEL_H_ */

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer

Chet Ramey, ITS, CWRU    address@hidden    http://tiswww.tis.case.edu/~chet/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]