Blame SOURCES/bash42-003

ff19ae
			     BASH PATCH REPORT
ff19ae
			     =================
ff19ae
ff19ae
Bash-Release:	4.2
ff19ae
Patch-ID:	bash42-003
ff19ae
ff19ae
Bug-Reported-by:	Clark J. Wang <dearvoid@gmail.com>
ff19ae
Bug-Reference-ID:	<AANLkTikZ_rVV-frR8Fh0PzhXnMKnm5XsUR-F3qtPPs5G@mail.gmail.com>
ff19ae
Bug-Reference-URL:	http://lists.gnu.org/archive/html/bug-bash/2011-02/msg00136.html
ff19ae
ff19ae
Bug-Description:
ff19ae
ff19ae
When using the pattern replacement and pattern removal word expansions, bash
ff19ae
miscalculates the possible match length in the presence of an unescaped left
ff19ae
bracket without a closing right bracket, resulting in a failure to match
ff19ae
the pattern.
ff19ae
ff19ae
Patch (apply with `patch -p0'):
ff19ae
ff19ae
*** ../bash-4.2-patched/lib/glob/gmisc.c	2011-02-05 16:11:17.000000000 -0500
ff19ae
--- lib/glob/gmisc.c	2011-02-18 23:53:42.000000000 -0500
ff19ae
***************
ff19ae
*** 78,83 ****
ff19ae
       size_t wmax;
ff19ae
  {
ff19ae
!   wchar_t wc, *wbrack;
ff19ae
!   int matlen, t, in_cclass, in_collsym, in_equiv;
ff19ae
  
ff19ae
    if (*wpat == 0)
ff19ae
--- 78,83 ----
ff19ae
       size_t wmax;
ff19ae
  {
ff19ae
!   wchar_t wc;
ff19ae
!   int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
ff19ae
  
ff19ae
    if (*wpat == 0)
ff19ae
***************
ff19ae
*** 119,123 ****
ff19ae
  	case L'[':
ff19ae
  	  /* scan for ending `]', skipping over embedded [:...:] */
ff19ae
! 	  wbrack = wpat;
ff19ae
  	  wc = *wpat++;
ff19ae
  	  do
ff19ae
--- 119,123 ----
ff19ae
  	case L'[':
ff19ae
  	  /* scan for ending `]', skipping over embedded [:...:] */
ff19ae
! 	  bracklen = 1;
ff19ae
  	  wc = *wpat++;
ff19ae
  	  do
ff19ae
***************
ff19ae
*** 125,140 ****
ff19ae
  	      if (wc == 0)
ff19ae
  		{
ff19ae
! 	          matlen += wpat - wbrack - 1;	/* incremented below */
ff19ae
! 	          break;
ff19ae
  	        }
ff19ae
  	      else if (wc == L'\\')
ff19ae
  		{
ff19ae
! 		  wc = *wpat++;
ff19ae
! 		  if (*wpat == 0)
ff19ae
! 		    break;
ff19ae
  		}
ff19ae
  	      else if (wc == L'[' && *wpat == L':')	/* character class */
ff19ae
  		{
ff19ae
  		  wpat++;
ff19ae
  		  in_cclass = 1;
ff19ae
  		}
ff19ae
--- 125,148 ----
ff19ae
  	      if (wc == 0)
ff19ae
  		{
ff19ae
! 		  wpat--;			/* back up to NUL */
ff19ae
! 	          matlen += bracklen;
ff19ae
! 	          goto bad_bracket;
ff19ae
  	        }
ff19ae
  	      else if (wc == L'\\')
ff19ae
  		{
ff19ae
! 		  /* *wpat == backslash-escaped character */
ff19ae
! 		  bracklen++;
ff19ae
! 		  /* If the backslash or backslash-escape ends the string,
ff19ae
! 		     bail.  The ++wpat skips over the backslash escape */
ff19ae
! 		  if (*wpat == 0 || *++wpat == 0)
ff19ae
! 		    {
ff19ae
! 		      matlen += bracklen;
ff19ae
! 		      goto bad_bracket;
ff19ae
! 		    }
ff19ae
  		}
ff19ae
  	      else if (wc == L'[' && *wpat == L':')	/* character class */
ff19ae
  		{
ff19ae
  		  wpat++;
ff19ae
+ 		  bracklen++;
ff19ae
  		  in_cclass = 1;
ff19ae
  		}
ff19ae
***************
ff19ae
*** 142,145 ****
ff19ae
--- 150,154 ----
ff19ae
  		{
ff19ae
  		  wpat++;
ff19ae
+ 		  bracklen++;
ff19ae
  		  in_cclass = 0;
ff19ae
  		}
ff19ae
***************
ff19ae
*** 147,152 ****
ff19ae
  		{
ff19ae
  		  wpat++;
ff19ae
  		  if (*wpat == L']')	/* right bracket can appear as collating symbol */
ff19ae
! 		    wpat++;
ff19ae
  		  in_collsym = 1;
ff19ae
  		}
ff19ae
--- 156,165 ----
ff19ae
  		{
ff19ae
  		  wpat++;
ff19ae
+ 		  bracklen++;
ff19ae
  		  if (*wpat == L']')	/* right bracket can appear as collating symbol */
ff19ae
! 		    {
ff19ae
! 		      wpat++;
ff19ae
! 		      bracklen++;
ff19ae
! 		    }
ff19ae
  		  in_collsym = 1;
ff19ae
  		}
ff19ae
***************
ff19ae
*** 154,157 ****
ff19ae
--- 167,171 ----
ff19ae
  		{
ff19ae
  		  wpat++;
ff19ae
+ 		  bracklen++;
ff19ae
  		  in_collsym = 0;
ff19ae
  		}
ff19ae
***************
ff19ae
*** 159,164 ****
ff19ae
  		{
ff19ae
  		  wpat++;
ff19ae
  		  if (*wpat == L']')	/* right bracket can appear as equivalence class */
ff19ae
! 		    wpat++;
ff19ae
  		  in_equiv = 1;
ff19ae
  		}
ff19ae
--- 173,182 ----
ff19ae
  		{
ff19ae
  		  wpat++;
ff19ae
+ 		  bracklen++;
ff19ae
  		  if (*wpat == L']')	/* right bracket can appear as equivalence class */
ff19ae
! 		    {
ff19ae
! 		      wpat++;
ff19ae
! 		      bracklen++;
ff19ae
! 		    }
ff19ae
  		  in_equiv = 1;
ff19ae
  		}
ff19ae
***************
ff19ae
*** 166,174 ****
ff19ae
--- 184,196 ----
ff19ae
  		{
ff19ae
  		  wpat++;
ff19ae
+ 		  bracklen++;
ff19ae
  		  in_equiv = 0;
ff19ae
  		}
ff19ae
+ 	      else
ff19ae
+ 		bracklen++;
ff19ae
  	    }
ff19ae
  	  while ((wc = *wpat++) != L']');
ff19ae
  	  matlen++;		/* bracket expression can only match one char */
ff19ae
+ bad_bracket:
ff19ae
  	  break;
ff19ae
  	}
ff19ae
***************
ff19ae
*** 214,219 ****
ff19ae
       size_t max;
ff19ae
  {
ff19ae
!   char c, *brack;
ff19ae
!   int matlen, t, in_cclass, in_collsym, in_equiv;
ff19ae
  
ff19ae
    if (*pat == 0)
ff19ae
--- 236,241 ----
ff19ae
       size_t max;
ff19ae
  {
ff19ae
!   char c;
ff19ae
!   int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
ff19ae
  
ff19ae
    if (*pat == 0)
ff19ae
***************
ff19ae
*** 255,259 ****
ff19ae
  	case '[':
ff19ae
  	  /* scan for ending `]', skipping over embedded [:...:] */
ff19ae
! 	  brack = pat;
ff19ae
  	  c = *pat++;
ff19ae
  	  do
ff19ae
--- 277,281 ----
ff19ae
  	case '[':
ff19ae
  	  /* scan for ending `]', skipping over embedded [:...:] */
ff19ae
! 	  bracklen = 1;
ff19ae
  	  c = *pat++;
ff19ae
  	  do
ff19ae
***************
ff19ae
*** 261,276 ****
ff19ae
  	      if (c == 0)
ff19ae
  		{
ff19ae
! 	          matlen += pat - brack - 1;	/* incremented below */
ff19ae
! 	          break;
ff19ae
  	        }
ff19ae
  	      else if (c == '\\')
ff19ae
  		{
ff19ae
! 		  c = *pat++;
ff19ae
! 		  if (*pat == 0)
ff19ae
! 		    break;
ff19ae
  		}
ff19ae
  	      else if (c == '[' && *pat == ':')	/* character class */
ff19ae
  		{
ff19ae
  		  pat++;
ff19ae
  		  in_cclass = 1;
ff19ae
  		}
ff19ae
--- 283,306 ----
ff19ae
  	      if (c == 0)
ff19ae
  		{
ff19ae
! 		  pat--;			/* back up to NUL */
ff19ae
! 		  matlen += bracklen;
ff19ae
! 		  goto bad_bracket;
ff19ae
  	        }
ff19ae
  	      else if (c == '\\')
ff19ae
  		{
ff19ae
! 		  /* *pat == backslash-escaped character */
ff19ae
! 		  bracklen++;
ff19ae
! 		  /* If the backslash or backslash-escape ends the string,
ff19ae
! 		     bail.  The ++pat skips over the backslash escape */
ff19ae
! 		  if (*pat == 0 || *++pat == 0)
ff19ae
! 		    {
ff19ae
! 		      matlen += bracklen;
ff19ae
! 		      goto bad_bracket;
ff19ae
! 		    }
ff19ae
  		}
ff19ae
  	      else if (c == '[' && *pat == ':')	/* character class */
ff19ae
  		{
ff19ae
  		  pat++;
ff19ae
+ 		  bracklen++;
ff19ae
  		  in_cclass = 1;
ff19ae
  		}
ff19ae
***************
ff19ae
*** 278,281 ****
ff19ae
--- 308,312 ----
ff19ae
  		{
ff19ae
  		  pat++;
ff19ae
+ 		  bracklen++;
ff19ae
  		  in_cclass = 0;
ff19ae
  		}
ff19ae
***************
ff19ae
*** 283,288 ****
ff19ae
  		{
ff19ae
  		  pat++;
ff19ae
  		  if (*pat == ']')	/* right bracket can appear as collating symbol */
ff19ae
! 		    pat++;
ff19ae
  		  in_collsym = 1;
ff19ae
  		}
ff19ae
--- 314,323 ----
ff19ae
  		{
ff19ae
  		  pat++;
ff19ae
+ 		  bracklen++;
ff19ae
  		  if (*pat == ']')	/* right bracket can appear as collating symbol */
ff19ae
! 		    {
ff19ae
! 		      pat++;
ff19ae
! 		      bracklen++;
ff19ae
! 		    }
ff19ae
  		  in_collsym = 1;
ff19ae
  		}
ff19ae
***************
ff19ae
*** 290,293 ****
ff19ae
--- 325,329 ----
ff19ae
  		{
ff19ae
  		  pat++;
ff19ae
+ 		  bracklen++;
ff19ae
  		  in_collsym = 0;
ff19ae
  		}
ff19ae
***************
ff19ae
*** 295,300 ****
ff19ae
  		{
ff19ae
  		  pat++;
ff19ae
  		  if (*pat == ']')	/* right bracket can appear as equivalence class */
ff19ae
! 		    pat++;
ff19ae
  		  in_equiv = 1;
ff19ae
  		}
ff19ae
--- 331,340 ----
ff19ae
  		{
ff19ae
  		  pat++;
ff19ae
+ 		  bracklen++;
ff19ae
  		  if (*pat == ']')	/* right bracket can appear as equivalence class */
ff19ae
! 		    {
ff19ae
! 		      pat++;
ff19ae
! 		      bracklen++;
ff19ae
! 		    }
ff19ae
  		  in_equiv = 1;
ff19ae
  		}
ff19ae
***************
ff19ae
*** 302,310 ****
ff19ae
--- 342,354 ----
ff19ae
  		{
ff19ae
  		  pat++;
ff19ae
+ 		  bracklen++;
ff19ae
  		  in_equiv = 0;
ff19ae
  		}
ff19ae
+ 	      else
ff19ae
+ 		bracklen++;
ff19ae
  	    }
ff19ae
  	  while ((c = *pat++) != ']');
ff19ae
  	  matlen++;		/* bracket expression can only match one char */
ff19ae
+ bad_bracket:
ff19ae
  	  break;
ff19ae
  	}
ff19ae
*** ../bash-4.2-patched/patchlevel.h	Sat Jun 12 20:14:48 2010
ff19ae
--- patchlevel.h	Thu Feb 24 21:41:34 2011
ff19ae
***************
ff19ae
*** 26,30 ****
ff19ae
     looks for to find the patch level (for the sccs version string). */
ff19ae
  
ff19ae
! #define PATCHLEVEL 2
ff19ae
  
ff19ae
  #endif /* _PATCHLEVEL_H_ */
ff19ae
--- 26,30 ----
ff19ae
     looks for to find the patch level (for the sccs version string). */
ff19ae
  
ff19ae
! #define PATCHLEVEL 3
ff19ae
  
ff19ae
  #endif /* _PATCHLEVEL_H_ */