*** ../bash-5.2-patched/lib/glob/sm_loop.c 2021-08-03 10:24:49.000000000 -0400 --- lib/glob/sm_loop.c 2022-11-16 16:22:42.000000000 -0500 *************** *** 344,347 **** --- 344,352 ---- return (FNM_NOMATCH); + /* If we are matching pathnames, we can't match a slash with a + bracket expression. */ + if (sc == L('/') && (flags & FNM_PATHNAME)) + return (FNM_NOMATCH); + /* `?' cannot match `.' or `..' if it is the first character of the string or if it is the first character following a slash and *************** *** 452,455 **** --- 457,466 ---- pc = FOLD (p[1]); p += 4; + + /* Finding a slash in a bracket expression means you have to + match the bracket as an ordinary character (see below). */ + if (c == L('/') && (flags & FNM_PATHNAME)) + return ((test == L('[')) ? savep : (CHAR *)0); /*]*/ + if (COLLEQUIV (test, pc)) { *************** *** 566,569 **** --- 579,592 ---- return ((test == L('[')) ? savep : (CHAR *)0); + /* POSIX.2 2.13.3 says: `If a character is found following an + unescaped character before a corresponding + is found, the open bracket shall be treated + as an ordinary character.' If we find a slash in a bracket + expression and the flags indicate we're supposed to be treating the + string like a pathname, we have to treat the `[' as just a character + to be matched. */ + if ((flags & FNM_PATHNAME) && c == L('/')) + return ((test == L('[')) ? savep : (CHAR *)0); + c = *p++; c = FOLD (c); *************** *** 572,579 **** return ((test == L('[')) ? savep : (CHAR *)0); - if ((flags & FNM_PATHNAME) && c == L('/')) - /* [/] can never match when matching a pathname. */ - return (CHAR *)0; - /* This introduces a range, unless the `-' is the last character of the class. Find the end of the range --- 595,598 ----