116-upstream-bash43-016.patch (3406B)
1 BASH PATCH REPORT 2 ================= 3 4 Bash-Release: 4.3 5 Patch-ID: bash43-016 6 7 Bug-Reported-by: Pierre Gaston <pierre.gaston@gmail.com> 8 Bug-Reference-ID: <CAPSX3sTCD61k1VQLJ5r-LWzEt+e7Xc-fxXmwn2u8EA5gJJej8Q@mail.gmail.com> 9 Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2014-04/msg00100.html 10 11 Bug-Description: 12 13 An extended glob pattern containing a slash (`/') causes the globbing code 14 to misinterpret it as a directory separator. 15 16 Patch (apply with `patch -p0'): 17 --- a/lib/glob/glob.c 18 +++ b/lib/glob/glob.c 19 @@ -123,6 +123,8 @@ static char **glob_dir_to_array __P((cha 20 extern char *glob_patscan __P((char *, char *, int)); 21 extern wchar_t *glob_patscan_wc __P((wchar_t *, wchar_t *, int)); 22 23 +extern char *glob_dirscan __P((char *, int)); 24 + 25 /* Compile `glob_loop.c' for single-byte characters. */ 26 #define CHAR unsigned char 27 #define INT int 28 @@ -187,6 +189,9 @@ extglob_skipname (pat, dname, flags) 29 se = pp + strlen (pp) - 1; /* end of string */ 30 pe = glob_patscan (pp, se, 0); /* end of extglob pattern (( */ 31 /* we should check for invalid extglob pattern here */ 32 + if (pe == 0) 33 + return 0; 34 + 35 /* if pe != se we have more of the pattern at the end of the extglob 36 pattern. Check the easy case first ( */ 37 if (pe == se && *pe == ')' && (t = strchr (pp, '|')) == 0) 38 @@ -1015,7 +1020,7 @@ glob_filename (pathname, flags) 39 { 40 char **result; 41 unsigned int result_size; 42 - char *directory_name, *filename, *dname; 43 + char *directory_name, *filename, *dname, *fn; 44 unsigned int directory_len; 45 int free_dirname; /* flag */ 46 int dflags; 47 @@ -1031,6 +1036,18 @@ glob_filename (pathname, flags) 48 49 /* Find the filename. */ 50 filename = strrchr (pathname, '/'); 51 +#if defined (EXTENDED_GLOB) 52 + if (filename && extended_glob) 53 + { 54 + fn = glob_dirscan (pathname, '/'); 55 +#if DEBUG_MATCHING 56 + if (fn != filename) 57 + fprintf (stderr, "glob_filename: glob_dirscan: fn (%s) != filename (%s)\n", fn ? fn : "(null)", filename); 58 +#endif 59 + filename = fn; 60 + } 61 +#endif 62 + 63 if (filename == NULL) 64 { 65 filename = pathname; 66 --- a/lib/glob/gmisc.c 67 +++ b/lib/glob/gmisc.c 68 @@ -42,6 +42,8 @@ 69 #define WLPAREN L'(' 70 #define WRPAREN L')' 71 72 +extern char *glob_patscan __P((char *, char *, int)); 73 + 74 /* Return 1 of the first character of WSTRING could match the first 75 character of pattern WPAT. Wide character version. */ 76 int 77 @@ -375,3 +377,34 @@ bad_bracket: 78 79 return matlen; 80 } 81 + 82 +/* Skip characters in PAT and return the final occurrence of DIRSEP. This 83 + is only called when extended_glob is set, so we have to skip over extglob 84 + patterns x(...) */ 85 +char * 86 +glob_dirscan (pat, dirsep) 87 + char *pat; 88 + int dirsep; 89 +{ 90 + char *p, *d, *pe, *se; 91 + 92 + d = pe = se = 0; 93 + for (p = pat; p && *p; p++) 94 + { 95 + if (extglob_pattern_p (p)) 96 + { 97 + if (se == 0) 98 + se = p + strlen (p) - 1; 99 + pe = glob_patscan (p + 2, se, 0); 100 + if (pe == 0) 101 + continue; 102 + else if (*pe == 0) 103 + break; 104 + p = pe - 1; /* will do increment above */ 105 + continue; 106 + } 107 + if (*p == dirsep) 108 + d = p; 109 + } 110 + return d; 111 +} 112 --- a/patchlevel.h 113 +++ b/patchlevel.h 114 @@ -25,6 +25,6 @@ 115 regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh 116 looks for to find the patch level (for the sccs version string). */ 117 118 -#define PATCHLEVEL 15 119 +#define PATCHLEVEL 16 120 121 #endif /* _PATCHLEVEL_H_ */