On 2/15/11 10:16 PM, Clark J. Wang wrote:
> On Wed, Feb 16, 2011 at 9:59 AM, Chet Ramey <chet.ra...@case.edu
> <mailto:chet.ra...@case.edu>> wrote:
> 
>     On 2/15/11 6:18 AM, Clark J. Wang wrote:
>     > For following script:
>     >
>     > var='[hello'
>     > echo "${var//[/}"
>     >
>     > With bash 4.1 it outputs hello but with 4.2 it outputs [hello . And
>     bash 4.2
>     > with compat41 on still outputs [hello . Bug? Or Bug fixed?
> 
>     It's a bug, and I will release a patch.  In the meantime, see if the
>     attached patch does the right thing on your platform.
> 
> The patch fixed this simple example but it does not work for more
> complicated scenario:

Yes, it was a quick fix for the immediate problem.  Please try the
attached patch for a more complete solution.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU    c...@case.edu    http://cnswww.cns.cwru.edu/~chet/
*** ../bash-4.2/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;
  	}

Reply via email to