Skip to content

Commit 635a61d

Browse files
committed
fix bugs in fnmatch(), see issue #55186
all tests in tests/posix/c_lib_ext/src/fnmatch.c seem to pass except one (which is still commented) Signed-off-by: Nimish Tambe <nimisht@gmail.com>
1 parent 64ac57a commit 635a61d

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

lib/posix/options/fnmatch.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,15 @@ static const char *rangematch(const char *pattern, int test, int flags)
8484
for (need = true, ok = false, c = FOLDCASE(*pattern++, flags); c != ']' || need;
8585
c = FOLDCASE(*pattern++, flags)) {
8686
need = false;
87-
if (c == '/') {
88-
return (void *)-1;
89-
}
87+
88+
if (c == '/' && (flags & FNM_PATHNAME)) {
89+
return (void *)-1;
90+
}
9091

9192
if (c == '\\' && !(flags & FNM_NOESCAPE)) {
92-
c = FOLDCASE(*pattern++, flags);
93+
if (*pattern != ']' && *pattern != EOS) {
94+
c = FOLDCASE(*pattern++, flags);
95+
}
9396
}
9497

9598
if (c == EOS) {
@@ -221,7 +224,23 @@ static int fnmatchx(const char *pattern, const char *string, int flags, size_t r
221224
return FNM_NOMATCH;
222225
}
223226

227+
if (*string == '.' &&
228+
(flags & FNM_PERIOD) &&
229+
(string == stringstart ||
230+
((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
231+
return FNM_NOMATCH;
232+
}
233+
224234
r = rangematch(pattern, FOLDCASE(*string, flags), flags);
235+
236+
if (r == NULL) {
237+
if (FOLDCASE('[', flags) != FOLDCASE(*string, flags)) {
238+
return FNM_NOMATCH;
239+
}
240+
++string;
241+
break;
242+
}
243+
225244
if (r == NULL) {
226245
return FNM_NOMATCH;
227246
}

tests/posix/c_lib_ext/src/fnmatch.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ ZTEST(posix_c_lib_ext, test_fnmatch)
3030
zassert_equal(fnmatch("a*.c", "a/x.c", FNM_PATHNAME), FNM_NOMATCH);
3131
zassert_ok(fnmatch("*/foo", "/foo", FNM_PATHNAME));
3232
zassert_ok(fnmatch("-O[01]", "-O1", 0));
33-
/* zassert_ok(fnmatch("[[?*\\]", "\\", 0)); */
34-
/* zassert_ok(fnmatch("[]?*\\]", "]", 0)); */
33+
zassert_ok(fnmatch("[[?*\\]", "\\", 0));
34+
zassert_ok(fnmatch("[]?*\\]", "]", 0));
3535
zassert_ok(fnmatch("[!]a-]", "b", 0));
3636
zassert_ok(fnmatch("[]-_]", "^", 0));
3737
zassert_ok(fnmatch("[!]-_]", "X", 0));
3838
zassert_equal(fnmatch("??", "-", 0), FNM_NOMATCH);
3939
zassert_equal(fnmatch("*LIB*", "lib", FNM_PERIOD), FNM_NOMATCH);
40-
/* zassert_ok(fnmatch("a[/]b", "a/b", 0)); */
40+
zassert_ok(fnmatch("a[/]b", "a/b", 0));
4141
zassert_equal(fnmatch("a[/]b", "a/b", FNM_PATHNAME), FNM_NOMATCH);
4242
zassert_ok(fnmatch("[a-z]/[a-z]", "a/b", 0));
4343
zassert_equal(fnmatch("*", "a/b", FNM_PATHNAME), FNM_NOMATCH);
@@ -64,8 +64,8 @@ ZTEST(posix_c_lib_ext, test_fnmatch)
6464
zassert_equal(fnmatch("a/?b", "a/.b", FNM_PATHNAME | FNM_PERIOD), FNM_NOMATCH);
6565
zassert_equal(fnmatch("*a/b", ".a/b", FNM_PATHNAME | FNM_PERIOD), FNM_NOMATCH);
6666
zassert_equal(fnmatch("a/*b", "a/.b", FNM_PATHNAME | FNM_PERIOD), FNM_NOMATCH);
67-
/* zassert_equal(fnmatch("[.]a/b", ".a/b", FNM_PATHNAME | FNM_PERIOD), FNM_NOMATCH); */
68-
/* zassert_equal(fnmatch("a/[.]b", "a/.b", FNM_PATHNAME | FNM_PERIOD), FNM_NOMATCH); */
67+
zassert_equal(fnmatch("[.]a/b", ".a/b", FNM_PATHNAME | FNM_PERIOD), FNM_NOMATCH);
68+
zassert_equal(fnmatch("a/[.]b", "a/.b", FNM_PATHNAME | FNM_PERIOD), FNM_NOMATCH);
6969
zassert_ok(fnmatch("*/?", "a/b", FNM_PATHNAME | FNM_PERIOD));
7070
zassert_ok(fnmatch("?/*", "a/b", FNM_PATHNAME | FNM_PERIOD));
7171
zassert_ok(fnmatch(".*/?", ".a/b", FNM_PATHNAME | FNM_PERIOD));

0 commit comments

Comments
 (0)