On 12/1/12 10:41 AM, Ulf Magnusson wrote:
> GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)
> 
> Take the following example, assumed to be run in an empty directory:
> 
> $ mkdir a
> $ echo **
> a
> $ echo **/**
>  a a
> $ echo **/**/**
>  a a a
> 
> I would expect the result to be just 'a' in all cases.
> 
> You also get back a null filename, as shown by
> 
> $ for f in **/**/**; do echo "'$f'"; done
> ''
> 'a'
> 'a'
> 'a'

Thanks for the report.  This is definitely a problem.  It will be fixed
in the next version of bash, and may be released as a future patch.  I've
attached a patch for you to test; it fixes the problem for me without
introducing any new errors.

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-patched/lib/glob/glob.c	2012-07-14 15:53:13.000000000 -0400
--- lib/glob/glob.c	2012-12-04 21:03:07.000000000 -0500
***************
*** 934,938 ****
--- 1075,1081 ----
  	{
  	  char **temp_results;
+ 	  int shouldbreak;
  
+ 	  shouldbreak = 0;
  	  /* XXX -- we've recursively scanned any directories resulting from
  	     a `**', so turn off the flag.  We turn it on again below if
***************
*** 966,970 ****
  		 name to the results; we've already done it in glob_vector */
  	      if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
! 		array = temp_results;
  	      else
  		array = glob_dir_to_array (directories[i], temp_results, flags);
--- 1109,1144 ----
  		 name to the results; we've already done it in glob_vector */
  	      if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
! 		{
! 		  /* When do we remove null elements from temp_results?  And
! 		     how to avoid duplicate elements in the final result? */
! 		  /* If (dflags & GX_NULLDIR) glob_filename potentially left a
! 		     NULL placeholder in the temp results just in case
! 		     glob_vector/glob_dir_to_array did something with it, but
! 		     if it didn't, and we're not supposed to be passing them
! 		     through for some reason ((flags & GX_NULLDIR) == 0) we
! 		     need to remove all the NULL elements from the beginning
! 		     of TEMP_RESULTS. */
! 		  /* If we have a null directory name and ** as the filename,
! 		     we have just searched for everything from the current
! 		     directory on down. Break now (shouldbreak = 1) to avoid
! 		     duplicate entries in the final result. */
! #define NULL_PLACEHOLDER(x)	((x) && *(x) && **(x) == 0)
! 		  if ((dflags & GX_NULLDIR) && (flags & GX_NULLDIR) == 0 &&
! 			NULL_PLACEHOLDER (temp_results))
! #undef NULL_PLACEHOLDER
! 		    {
! 		      register int i, n;
! 		      for (n = 0; temp_results[n] && *temp_results[n] == 0; n++)
! 			;
! 		      i = n;
! 		      do
! 			temp_results[i - n] = temp_results[i];
! 		      while (temp_results[i++] != 0);
! 		      array = temp_results;
! 		      shouldbreak = 1;
! 		    }
! 	          else
! 		    array = temp_results;
! 		}
  	      else
  		array = glob_dir_to_array (directories[i], temp_results, flags);
***************
*** 987,990 ****
--- 1161,1169 ----
  	      if (array != temp_results)
  		free ((char *) array);
+ 	      else if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
+ 		free (temp_results);	/* expanding ** case above */
+ 
+ 	      if (shouldbreak)
+ 		break;
  	    }
  	}

Reply via email to