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