[gnu.bash.bug] globbing bug in 1.04

Ray.Nickson@comp.vuw.ac.nz (Ray Nickson) (11/16/89)

[ The patches in the message about HPUX job control also apply to
  1.04; sorry, forgot to say so. ]

Globbing doesn't work right:

bash$ ls
abc     abd     bbc     cbc
bash$ echo *[^c]
abc abd bbc cbc
bash$ 

I understand that *[^c] should match any sequence of characters
followed by a single character which is not a c; only abd should have
matched.  The problem is that [^c] is matching the null at the end of
each filename.  The patch below seems to fix this.

-rgn
--
Ray Nickson, Dept. Comp. Sci., Victoria University of Wellington, New Zealand.
Ray.Nickson@comp.vuw.ac.nz                                  + 64 4 721000x8593


*** glob.c.orig	Sat Sep 23 16:35:45 1989
--- glob.c	Wed Nov 15 16:16:54 1989
***************
*** 144,152 ****
  
        case '[':
  	{
! 	  register char c1 = *t++;
  	  int invert;
  
  	  invert = ((*p == '!') || (*p == '^'));
  	  if (invert)
  	    p++;
--- 145,157 ----
  
        case '[':
  	{
! 	  register char c1 = *t;
  	  int invert;
  
+ 	  if (*t++ == '\0')
+ 	    return 0;
+ 	  
+ 	  
  	  invert = ((*p == '!') || (*p == '^'));
  	  if (invert)
  	    p++;

Ray.Nickson@comp.vuw.ac.nz (Ray Nickson) (11/30/89)

This is bash-1.04, gcc-compiled on a sun3 running sunos4, but the bug
should apply on any machine.

bash$ mkdir foo
bash$ cd foo
bash$ touch f1 f2
bash$ echo f* x*
f1 f2 x*
bash$ echo f* x/*
f* x/*

The bug is in the last line; the failure of x/* to glob shouldn't
prevent the successful globbing of f* (it does in csh, which reports
an error, but (our) sh works properly).

The problem is in subst.c, in expand_words_1 (this is abbreviated):

	while (tlist)
	  {
		temp_list = shell_glob_filename (tlist->word->word);

		/* Handle error cases.
		   I don't think we should report errors like "No such file
		   or directory".  However, I would like to report errors
		   like "Read failed". */
		 
		if (temp_list == (char **)-1)
		  {
		    /* file_error (tlist->word->word); */
		    return (new_list);
		  }

		    orig_list =
		      make_word_list (copy_word (tlist->word), orig_list);

	    tlist = tlist->next;
	  }
       [ ... return orig_list ]

This code is entered with both tlist and new_list being the original
command.  For some (possibly good) reason, shell_glob_filename returns
(char **)-1 on a `file system error', including ENOENT, but returns a
pointer to (char *)0 (ie. an empty word array) when globbing fails
otherwise.

My (unintelligent and unrecommened) fix was simply to replace 
 return (new_list); 
by 
 temp_list = malloc(sizeof(char *));
 *temp_list = (char *)0;
which memory, in typical cavalier fashion, I never free.
This fixes this problem, it may or may not cause others.

-rgn
--
Ray Nickson, Dept. Comp. Sci., Victoria University of Wellington, New Zealand.
Ray.Nickson@comp.vuw.ac.nz                                  + 64 4 721000x8593