-
Notifications
You must be signed in to change notification settings - Fork 8.3k
posix: c_lib_ext: fnmatch: fix escape-oriented regression #99442
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
6f09b19 to
462e5af
Compare
The pattern is not erroneous (which would cause the function to return -FNM_NOMATCH). It is a legitimate pattern equivalent to "[[?*]" and not a bracket expression at all. We might want to add a test to verify that the pattern works in this way. Note that Musl has the same bug, which is why the test was flawed. |
Ok - sorry - I was proceeding based on your comment here, where you wrote that Maybe I was reading-in to your comment too far though, and assumed that if the final In either case, when the pattern is invalid or when it is I can update the PR description and / or commentary as you like, but it would be nice to have a reference to the specification to support it. I've confirmed that Zephyr's implementation recognizes |
|
It would seem that even the glibc agrees with the former interpretation (that there is an incomplete bracket expression). A sample program I wrote to test #include <fnmatch.h>
#include <stdio.h>
int main()
{
const char *pat = "[abc\\]";
const char *in = "a";
int ret;
ret = fnmatch(pat, in, 0);
if (ret == 0) {
printf("fnmatch(\"%s\", \"%s\", 0) -> success!\n", pat, in);
} else {
printf("fnmatch(\"%s\", \"%s\", 0) -> failed! (%d)\n", pat, in, ret);
}
return ret;
}produces the output below. $ /tmp/blah
fnmatch("[abc\]", "a", 0) -> failed! (1)It fails as well with |
I think you've mis-interpreted my comment -- yes, this is an invalid bracket expression, but https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13_01 says that you only get a bracket expression when the bracket expression is valid, otherwise you interpret the bytes as not being part of a bracket expression at all. An valid expression which does not match the string returns So, the difference is which return value is expected, in this case the expression is valid (although does not contain a bracket expression), it's just that it doesn't match the string, so it should return FNM_NOMATCH. |
A regression in 936d027 introduced a subtle bug in the way that escaped expressions were handled. The regression originated with the assumption that test data (originally adapted from a 3rd-party testsuite) was correct when it was in fact flawed. Specifically, `fnmatch("[[?*\\]", "\\", 0)` should fail (`FNM_NOMATCH`), since the "\\" sequence (a single backslash after compilation) escapes the following ']' character, thus leaving the bracket expression incomplete. As @keith-packard has pointed out, https://pubs.opengroup.org/onlinepubs/9699919799/utilities/\ V3_chap02.html#tag_18_13_01 says that a bracket expression is only interpreted as a bracket expression, when a proper bracket expression is formed. Therefore, the pattern is interpreted as the sequence `'['`, `'['`, `'?'`, `*` (wildcard), `']'` and the call should return `FNM_NOMATCH` to indicate failure rather than 0 to indicate success. Added new test cases from zephyrproject-rtos#98827 and some commentary for subsequent reviewers. This change does not completely fix zephyrproject-rtos#55186 but is related to it. Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com> Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no> Signed-off-by: Keith Packard <keithp@keithp.com>
462e5af to
501511e
Compare
|
@keith-packard - thanks for clarifying. I've updated the PR description and comment. |
|
|
@keith-packard - just a gentle ping to re-review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is incorrect. The first path component, "a", matches *[![:digit:]]* as 'a' is not a digit. The second path component, "b", matches [![:d-d] because 'b' is not [, not : and not any of the range d-d.
keith-packard
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix the remaining bugs in the implementation and update the tests to conform with the spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is also incorrect, again "a" matches *[![:digit:]]* while "[" matches one of [, : or the range d-d.
I'd strongly prefer that the bugs in the Zephyr implementation be fixed before this series is merged; there's no particular reason to commit known-buggy code, especially as this function doesn't appear to be urgently in need of updates.



A regression in 936d027 introduced a subtle bug in the way that escaped expressions were handled.
The regression originated with the assumption that test data (originally adapted from a 3rd-party testsuite) was correct when it was in fact flawed.
Specifically,
fnmatch("[[?*\\]", "\\", 0)should fail (FNM_NOMATCH), since the "\" sequence (a single backslash after compilation) escapes the following ']' character, thus leaving the bracket expression incomplete.As @keith-packard has pointed out, pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13_01, a bracket expression is only interpreted as a bracket expression, when a proper bracket expression is formed.
Therefore, the pattern is interpreted as the sequence
'[','[','?','*',']'and the call should returnFNM_NOMATCHto indicate failure rather than 0 to indicate success.Added new test cases from #98827 and some commentary for subsequent reviewers.
This change does not completely fix #55186 but is related to it.
The remaining changes are fixed in #97400