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