Created attachment 35745 [details] Extra tests for apr_fnmatch_test function. # Problem description `apr_fnmatch_test` is wrong on wild-card strings with escape character (backslash) and no other special characters. # Impact It is not possible to specify some directories in `Directory` of Apache configuration file. # STR 1 ## Steps 1. Install and configure Apache Web server. 2. Create the directories like the following: 1. `/var/www/vhosts/myhost.example/foo*bar` 2. `/var/www/vhosts/myhost.example/foo\*bar` 3. `/var/www/vhosts/myhost.example/fooBAZbar` 3. Try to deny access to `foo*bar` using: <Directory "var/www/vhosts/myhost.example/foo*bar"> Require all denied </Directory> 4. Remove the previous configuration block and try to deny access to `foo*bar` using: <Directory "var/www/vhosts/myhost.example/foo\*bar"> Require all denied </Directory> 5. Remove the previous configuration block and try to deny access to `foo*bar` using: <Directory "var/www/vhosts/myhost.example/foo\\*bar"> Require all denied </Directory> ## Actual result On step 3: access to all three directories is denied. On step 4: access to `foo\*bar` only is denied. On step 5: access to `foo\*bar` only is denied. ## Expected result On step 3: access to all three directories is denied. On step 4: access to `foo*bar` only is denied. On step 5: access to `foo*bar` only is denied. # STR 2 ## Steps ~~~ gcc test-apr_fnmatch_test.cpp -o test-apr_fnmatch_test -ldl ./test-apr_fnmatch_test ~~~ ## Actual result ~~~ [user@host ~]# gcc test-apr_fnmatch_test.cpp -o test-apr_fnmatch_test -ldl [user@host ~]# ./test-apr_fnmatch_test apr_fnmatch_test("foo\*bar") returns 0, expected 1 apr_fnmatch_test("foo\bar") returns 0, expected 1 done test_fnmatch_test ~~~ ## Expected result ~~~ [root@host ~]# gcc test-apr_fnmatch_test.cpp -o test-apr_fnmatch_test -ldl [root@host ~]# ./test-apr_fnmatch_test done test_fnmatch_test ~~~ # Root cause [apr/strings/apr_fnmatch.c:416-420](https://github.com/apache/apr/blob/71cf5aa36f5c5138d3bad87c6c1e8124b8df457f/strings/apr_fnmatch.c#L416) # Possible solution ~~~ --- apr/strings/apr_fnmatch.c +++ apr/strings/apr_fnmatch.c (Unsaved) @@ -414,10 +414,11 @@ return 1; case '\\': - if (*++pattern == '\0') { + if (*(pattern + 1) == '\0') { return 0; - } - break; + } else { + return 1; + } case '[': /* '[' is only a glob if it has a matching ']' */ ++nesting; ~~~ # Workaround Use the following configuration to deny access to `foo*bar`: <Directory "var/www/vhosts/myhost.example/foo[*]bar"> Require all denied </Directory>
Commenting so that this lands on my radar. Thank you for the report.