BASH PATCH REPORT ================= Bash-Release: 4.3 Patch-ID: bash43-016 Bug-Reported-by: Pierre Gaston <pierre.gaston@gmail.com> Bug-Reference-ID: <CAPSX3sTCD61k1VQLJ5r-LWzEt+e7Xc-fxXmwn2u8EA5gJJej8Q@mail.gmail.com> Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2014-04/msg00100.html Bug-Description: An extended glob pattern containing a slash (`/') causes the globbing code to misinterpret it as a directory separator. Patch (apply with `patch -p0'): *** ../bash-4.3-patched/lib/glob/glob.c 2014-03-28 10:54:23.000000000 -0400 --- lib/glob/glob.c 2014-05-02 10:24:28.000000000 -0400 *************** *** 124,127 **** --- 124,129 ---- extern wchar_t *glob_patscan_wc __P((wchar_t *, wchar_t *, int)); + extern char *glob_dirscan __P((char *, int)); + /* Compile `glob_loop.c' for single-byte characters. */ #define CHAR unsigned char *************** *** 188,191 **** --- 190,196 ---- pe = glob_patscan (pp, se, 0); /* end of extglob pattern (( */ /* we should check for invalid extglob pattern here */ + if (pe == 0) + return 0; + /* if pe != se we have more of the pattern at the end of the extglob pattern. Check the easy case first ( */ *************** *** 1016,1020 **** char **result; unsigned int result_size; ! char *directory_name, *filename, *dname; unsigned int directory_len; int free_dirname; /* flag */ --- 1021,1025 ---- char **result; unsigned int result_size; ! char *directory_name, *filename, *dname, *fn; unsigned int directory_len; int free_dirname; /* flag */ *************** *** 1032,1035 **** --- 1037,1052 ---- /* Find the filename. */ filename = strrchr (pathname, '/'); + #if defined (EXTENDED_GLOB) + if (filename && extended_glob) + { + fn = glob_dirscan (pathname, '/'); + #if DEBUG_MATCHING + if (fn != filename) + fprintf (stderr, "glob_filename: glob_dirscan: fn (%s) != filename (%s)\n", fn ? fn : "(null)", filename); + #endif + filename = fn; + } + #endif + if (filename == NULL) { *** ../bash-4.3-patched/lib/glob/gmisc.c 2014-03-28 10:54:23.000000000 -0400 --- lib/glob/gmisc.c 2014-05-02 09:35:57.000000000 -0400 *************** *** 43,46 **** --- 43,48 ---- #define WRPAREN L')' + extern char *glob_patscan __P((char *, char *, int)); + /* Return 1 of the first character of WSTRING could match the first character of pattern WPAT. Wide character version. */ *************** *** 376,377 **** --- 378,410 ---- return matlen; } + + /* Skip characters in PAT and return the final occurrence of DIRSEP. This + is only called when extended_glob is set, so we have to skip over extglob + patterns x(...) */ + char * + glob_dirscan (pat, dirsep) + char *pat; + int dirsep; + { + char *p, *d, *pe, *se; + + d = pe = se = 0; + for (p = pat; p && *p; p++) + { + if (extglob_pattern_p (p)) + { + if (se == 0) + se = p + strlen (p) - 1; + pe = glob_patscan (p + 2, se, 0); + if (pe == 0) + continue; + else if (*pe == 0) + break; + p = pe - 1; /* will do increment above */ + continue; + } + if (*p == dirsep) + d = p; + } + return d; + } *** ../bash-4.3/patchlevel.h 2012-12-29 10:47:57.000000000 -0500 --- patchlevel.h 2014-03-20 20:01:28.000000000 -0400 *************** *** 26,30 **** looks for to find the patch level (for the sccs version string). */ ! #define PATCHLEVEL 15 #endif /* _PATCHLEVEL_H_ */ --- 26,30 ---- looks for to find the patch level (for the sccs version string). */ ! #define PATCHLEVEL 16 #endif /* _PATCHLEVEL_H_ */