Re: lib/60517: fnmatch(2) does not implement FNM_PATHNAME correctly

Luke Mewburn <[email protected]>
Newsgroups gmane.os.netbsd.bugs
Message-ID <[email protected]>
On 26-07-29 17:35, [email protected] via gnats wrote:
  | >Description:
  | fnmatch(3) does not implement FNM_PATHNAME correctly in rangematch,
  | causing some patterns to not match correctly.
  | 
  | >How-To-Repeat:
  | The following program reproduces the issue:
  | 
  | #include <fnmatch.h>
  | #include <stdio.h>
  | 
  | int main(int argc, char *argv[]) {
  | 	int match = fnmatch(argv[1], argv[2], 0);
  | 	printf("%d\n", match);
  | 	return 0;
  | }
  | 
  | Run:
  | 
  | ./fnmatch '[\\/$]*' '/usr/lib'
  | 
  | And it should print 0.

(+ Christos)

Hi Drew,

tl;dr: I think you have identified a bug with fnmatch without FNM_PATHNAME,
even if I think your test case pattern was a bit tricky at first :)

Unless Christos (or someone else) disagrees with your report
and my analysis, I think this should be committed.


Details:

When I first analyzed your report it wasn't clear what the fault was:
1. Your pattern was a bit tricky. Now I see that the intention is to
   match any string starting with `\', `/', or `$', relying upon
   `\\' to become `\` because you're not using FNM_NOESCAPE.
2. You're not using FNM_PATHNAME.

I've dug into the commit that caused the issue, and read multiple
versions of the relevant POSIX pages, and I now understand your bug
report and think your proposed fix is correct.

The commit to lib/libc/gen/fnmatch.c 1.26 on 2014-10-12 was by Christos,
with commit message:
	Fix fnmatch issues according to POSIX.
	http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_13_01
	1. A [...] pattern containing a slash is not a pattern; the [ ]'s become regular
	   characters
	2. A [] or a [!] is not an empty pattern, why would it? The first would never
	   match and the second would always match which makes it equivalent to ?
	   In those cases the ] is taken as a literal character and does not have
	   special meaning.

Reading that POSIX (issue 6) "Shell Command Language" page linked in item 1,
I don't actually see the text relating to item 1 in section 2.13.1.
There's related text in section 2.13.3 "Patterns Used for Filename Expansion".

However, the POSIX (issue 6) fnmatch page at
  https://pubs.opengroup.org/onlinepubs/009695399/functions/fnmatch.html 
doesn't cross-reference back to this shell section 2.13.3 about filename
expansion.  It seems to me that fnmatch FNM_PATHNAME has a limited and
different implementation than the shell.

The relevant text in fnmatch for slash without FNM_PATHNAME is:
	If the FNM_PATHNAME flag is not set, the slash character shall be
	treated as an ordinary character.

The latest POSIX (issue 8) page for fnmatch at
  https://pubs.opengroup.org/onlinepubs/9799919799/functions/fnmatch.html
has similar text:
	If the FNM_PATHNAME flag is not set, the <slash> character shall
	be treated as an ordinary character.

Regards,
Luke.



  | >Fix:
  | --- src.orig/lib/libc/gen/fnmatch.c	2014-10-13 00:32:33.000000000 +0200
  | +++ src/lib/libc/gen/fnmatch.c	2026-07-29 15:25:45.271817024 +0200
  | @@ -91,7 +91,7 @@
  |  	need = 1;
  |  	for (ok = 0; (c = FOLDCASE(*pattern++, flags)) != ']' || need;) {
  |  		need = 0;
  | -		if (c == '/')
  | +		if (c == '/' && (flags & FNM_PATHNAME))
  |  			return (void *)-1;
  |  		if (c == '\\' && !(flags & FNM_NOESCAPE))
  |  			c = FOLDCASE(*pattern++, flags);
  | --- src.orig/tests/lib/libc/gen/t_fnmatch.c	2016-10-31 06:08:53.000000000 +0100
  | +++ src/tests/lib/libc/gen/t_fnmatch.c	2026-07-29 19:25:10.723264988 +0200
  | @@ -125,6 +125,8 @@
  |  	ATF_CHECK(fnmatch("???x", "xxxx", FNM_PATHNAME) == 0);
  |  	ATF_CHECK(fnmatch("*/xxx", "/xxx", FNM_PATHNAME) == 0);
  |  	ATF_CHECK(fnmatch("x/*.y", "x/z.y", FNM_PATHNAME) == 0);
  | +
  | +	ATF_CHECK(fnmatch("[\\\\/$]*", "/usr/lib", 0) == 0);
  |  }
  |
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.