fix fnmatch corner cases related to escaping
authorRich Felker <dalias@aerifal.cx>
Sun, 1 Dec 2013 19:36:22 +0000 (14:36 -0500)
committerRich Felker <dalias@aerifal.cx>
Sun, 1 Dec 2013 19:36:22 +0000 (14:36 -0500)
the FNM_PATHNAME logic for advancing by /-delimited components was
incorrect when the / character was escaped (i.e. \/), and a final \ at
the end of pattern was not handled correctly.

src/regex/fnmatch.c

index c3fcaa5bb95d2e7d2ce9ea15141916be644771b3..093eb1ccfe6d550e29dd79877b6112b3f5f01d64 100644 (file)
@@ -19,7 +19,7 @@
 #include <wchar.h>
 #include <wctype.h>
 
-#define END -1
+#define END 0
 #define UNMATCHABLE -2
 #define BRACKET -3
 #define QUESTION -4
@@ -53,7 +53,7 @@ static int pat_next(const char *pat, size_t m, size_t *step, int flags)
                return END;
        }
        *step = 1;
-       if (pat[0]=='\\' && !(flags & FNM_NOESCAPE)) {
+       if (pat[0]=='\\' && pat[1] && !(flags & FNM_NOESCAPE)) {
                *step = 2;
                pat++;
                esc = 1;
@@ -288,12 +288,12 @@ int fnmatch(const char *pat, const char *str, int flags)
        if (flags & FNM_PATHNAME) for (;;) {
                for (s=str; *s && *s!='/'; s++);
                for (p=pat; (c=pat_next(p, -1, &inc, flags))!=END && c!='/'; p+=inc);
-               if (*p!=*s) return FNM_NOMATCH;
+               if (c!=*s) return FNM_NOMATCH;
                if (fnmatch_internal(pat, p-pat, str, s-str, flags))
                        return FNM_NOMATCH;
                if (!*s) return 0;
                str = s+1;
-               pat = p+1;
+               pat = p+inc;
        }
        return fnmatch_internal(pat, -1, str, -1, flags);
 }