From cbee6f5a782e9ce1b431704f33a3e03de85c4460 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Thu, 17 Nov 2022 18:44:19 +0900 Subject: [PATCH 1/3] fix(BRACKMATCH): terminate bracket expression by any slash --- lib/glob/sm_loop.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/lib/glob/sm_loop.c b/lib/glob/sm_loop.c index a448c155..f4d8d1f2 100644 --- a/lib/glob/sm_loop.c +++ b/lib/glob/sm_loop.c @@ -439,6 +439,16 @@ BRACKMATCH (p, test, flags) if (not = (*p == L('!') || *p == L('^'))) ++p; + /* 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. In this + implementation, we treat `/' the same as the end of the pattern for the + bracket expression. */ +#define ISBRACKETEOF(c) ((c) == L('\0') || (flags & FNM_PATHNAME) && (c) == L('/')) + c = *p++; for (;;) { @@ -472,7 +482,7 @@ BRACKMATCH (p, test, flags) else { c = *p++; - if (c == L('\0')) + if (ISBRACKETEOF (c)) return ((test == L('[')) ? savep : (CHAR *)0); /*]*/ c = FOLD (c); continue; @@ -486,11 +496,11 @@ BRACKMATCH (p, test, flags) pc = 0; /* make sure invalid char classes don't match. */ /* Find end of character class name */ - for (close = p + 1; *close != '\0'; close++) + for (close = p + 1; !ISBRACKETEOF (*close); close++) if (*close == L(':') && *(close+1) == L(']')) break; - if (*close != L('\0')) + if (!ISBRACKETEOF (*close)) { ccname = (CHAR *)malloc ((close - p) * sizeof (CHAR)); if (ccname == 0) @@ -535,7 +545,7 @@ BRACKMATCH (p, test, flags) /* continue the loop here, since this expression can't be the first part of a range expression. */ c = *p++; - if (c == L('\0')) + if (ISBRACKETEOF (c)) return ((test == L('[')) ? savep : (CHAR *)0); else if (c == L(']')) break; @@ -560,7 +570,7 @@ BRACKMATCH (p, test, flags) if (!(flags & FNM_NOESCAPE) && c == L('\\')) { - if (*p == '\0') + if (ISBRACKETEOF (*p)) return (CHAR *)0; cstart = cend = *p++; } @@ -573,23 +583,13 @@ BRACKMATCH (p, test, flags) expression produces undefined results.' This implementation treats the `[' as just a character to be matched if there is not a closing `]'. */ - if (c == L('\0')) - 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('/')) + if (ISBRACKETEOF (c)) return ((test == L('[')) ? savep : (CHAR *)0); c = *p++; c = FOLD (c); - if (c == L('\0')) + if (ISBRACKETEOF (c)) return ((test == L('[')) ? savep : (CHAR *)0); /* This introduces a range, unless the `-' is the last @@ -600,7 +600,7 @@ BRACKMATCH (p, test, flags) cend = *p++; if (!(flags & FNM_NOESCAPE) && cend == L('\\')) cend = *p++; - if (cend == L('\0')) + if (ISBRACKETEOF (cend)) return (CHAR *)0; if (cend == L('[') && *p == L('.')) { @@ -651,7 +651,7 @@ matched: int oc; /* A `[' without a matching `]' is just another character to match. */ - if (c == L('\0')) + if (ISBRACKETEOF (c)) return ((test == L('[')) ? savep : (CHAR *)0); oc = c; @@ -660,7 +660,8 @@ matched: { brcnt++; brchrp = p++; /* skip over the char after the left bracket */ - if ((c = *p) == L('\0')) + c = *p; + if (ISBRACKETEOF (c)) return ((test == L('[')) ? savep : (CHAR *)0); /* If *brchrp == ':' we should check that the rest of the characters form a valid character class name. We don't do that yet, but we @@ -681,13 +682,15 @@ matched: brcnt = 0; else if (!(flags & FNM_NOESCAPE) && c == L('\\')) { - if (*p == '\0') + if (ISBRACKETEOF (*p)) return (CHAR *)0; /* XXX 1003.2d11 is unclear if this is right. */ ++p; } } return (not ? (CHAR *)0 : p); + +#undef ISBRACKETEOF } #if defined (EXTENDED_GLOB) -- 2.37.2