Skip to content

Commit ccce1c3

Browse files
committed
posix: fnmatch: 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 ccce1c3

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

lib/posix/options/fnmatch.c

Lines changed: 20 additions & 2 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 == '/') {
87+
88+
if (c == '/' && (flags & FNM_PATHNAME)) {
8889
return (void *)-1;
8990
}
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,22 @@ static int fnmatchx(const char *pattern, const char *string, int flags, size_t r
221224
return FNM_NOMATCH;
222225
}
223226

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

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)