BASH PATCH REPORT ================= Bash-Release: 4.3 Patch-ID: bash43-008 Bug-Reported-by: Stephane Chazelas Bug-Reference-ID: <20140318135901.GB22158@chaz.gmail.com> Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2014-03/msg00098.html Bug-Description: Some extended glob patterns incorrectly matched filenames with a leading dot, regardless of the setting of the `dotglob' option. Patch (apply with `patch -p0'): *** ../bash-4.3/lib/glob/gmisc.c 2013-10-28 14:45:25.000000000 -0400 --- lib/glob/gmisc.c 2014-03-19 09:16:08.000000000 -0400 *************** *** 211,214 **** --- 211,215 ---- case '!': case '@': + case '?': return (pat[1] == LPAREN); default: *** ../bash-4.3/lib/glob/glob.c 2014-01-31 21:43:51.000000000 -0500 --- lib/glob/glob.c 2014-03-20 09:01:26.000000000 -0400 *************** *** 180,202 **** int flags; { ! char *pp, *pe, *t; ! int n, r; pp = pat + 2; ! pe = pp + strlen (pp) - 1; /*(*/ ! if (*pe != ')') ! return 0; ! if ((t = strchr (pp, '|')) == 0) /* easy case first */ { *pe = '\0'; r = skipname (pp, dname, flags); /*(*/ *pe = ')'; return r; } while (t = glob_patscan (pp, pe, '|')) { n = t[-1]; t[-1] = '\0'; r = skipname (pp, dname, flags); t[-1] = n; if (r == 0) /* if any pattern says not skip, we don't skip */ --- 180,215 ---- int flags; { ! char *pp, *pe, *t, *se; ! int n, r, negate; + negate = *pat == '!'; pp = pat + 2; ! se = pp + strlen (pp) - 1; /* end of string */ ! pe = glob_patscan (pp, se, 0); /* end of extglob pattern (( */ ! /* we should check for invalid extglob pattern here */ ! /* if pe != se we have more of the pattern at the end of the extglob ! pattern. Check the easy case first ( */ ! if (pe == se && *pe == ')' && (t = strchr (pp, '|')) == 0) { *pe = '\0'; + #if defined (HANDLE_MULTIBYTE) + r = mbskipname (pp, dname, flags); + #else r = skipname (pp, dname, flags); /*(*/ + #endif *pe = ')'; return r; } + + /* check every subpattern */ while (t = glob_patscan (pp, pe, '|')) { n = t[-1]; t[-1] = '\0'; + #if defined (HANDLE_MULTIBYTE) + r = mbskipname (pp, dname, flags); + #else r = skipname (pp, dname, flags); + #endif t[-1] = n; if (r == 0) /* if any pattern says not skip, we don't skip */ *************** *** 205,219 **** } /*(*/ ! if (pp == pe) /* glob_patscan might find end of pattern */ return r; ! *pe = '\0'; ! # if defined (HANDLE_MULTIBYTE) ! r = mbskipname (pp, dname, flags); /*(*/ ! # else ! r = skipname (pp, dname, flags); /*(*/ ! # endif ! *pe = ')'; ! return r; } #endif --- 218,227 ---- } /*(*/ ! /* glob_patscan might find end of pattern */ ! if (pp == se) return r; ! /* but if it doesn't then we didn't match a leading dot */ ! return 0; } #endif *************** *** 278,289 **** { #if EXTENDED_GLOB ! wchar_t *pp, *pe, *t, n; ! int r; pp = pat + 2; ! pe = pp + wcslen (pp) - 1; /*(*/ ! if (*pe != L')') ! return 0; ! if ((t = wcschr (pp, L'|')) == 0) { *pe = L'\0'; --- 286,298 ---- { #if EXTENDED_GLOB ! wchar_t *pp, *pe, *t, n, *se; ! int r, negate; + negate = *pat == L'!'; pp = pat + 2; ! se = pp + wcslen (pp) - 1; /*(*/ ! pe = glob_patscan_wc (pp, se, 0); ! ! if (pe == se && *pe == ')' && (t = wcschr (pp, L'|')) == 0) { *pe = L'\0'; *************** *** 292,295 **** --- 301,306 ---- return r; } + + /* check every subpattern */ while (t = glob_patscan_wc (pp, pe, '|')) { *************** *** 306,313 **** return r; ! *pe = L'\0'; ! r = wchkname (pp, dname); /*(*/ ! *pe = L')'; ! return r; #else return (wchkname (pat, dname)); --- 317,322 ---- return r; ! /* but if it doesn't then we didn't match a leading dot */ ! return 0; #else return (wchkname (pat, dname)); *** ../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 7 #endif /* _PATCHLEVEL_H_ */ --- 26,30 ---- looks for to find the patch level (for the sccs version string). */ ! #define PATCHLEVEL 8 #endif /* _PATCHLEVEL_H_ */