]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Merge pull request #2928 from stoeckmann/anchor_no_flags
authorTim Kientzle <kientzle@acm.org>
Sat, 9 May 2026 20:49:25 +0000 (13:49 -0700)
committerMartin Matuska <martin@matuska.de>
Tue, 23 Jun 2026 08:27:41 +0000 (10:27 +0200)
pathmatch: Treat anchors not special without flags
(cherry picked from commit 5ed0b5ea88bbe75e1e5e6e273724433bd59e5736)

libarchive/archive_pathmatch.c
libarchive/test/test_archive_match_path.c
libarchive/test/test_archive_pathmatch.c

index f65f43745527f70697539ae791dcd963ece5e79c..4b69ae1e4afb4e84334eb4c1ce4b40b5261cbf21 100644 (file)
@@ -399,7 +399,7 @@ __archive_pathmatch(const char *p, const char *s, int flags)
                return (0);
 
        /* Leading '^' anchors the start of the pattern. */
-       if (*p == '^') {
+       if ((flags & PATHMATCH_NO_ANCHOR_START) && *p == '^') {
                ++p;
                flags &= ~PATHMATCH_NO_ANCHOR_START;
        }
@@ -444,7 +444,7 @@ __archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags)
                return (0);
 
        /* Leading '^' anchors the start of the pattern. */
-       if (*p == L'^') {
+       if ((flags & PATHMATCH_NO_ANCHOR_START) && *p == L'^') {
                ++p;
                flags &= ~PATHMATCH_NO_ANCHOR_START;
        }
index ce48263f761404327327651a49fa179a1260a5bd..527413db799201891b458f0cb6123ad35e8903ac 100644 (file)
@@ -233,8 +233,8 @@ test_inclusion_mbs(void)
                return;
        }
 
-       /* Test for pattern "^aa*" */
-       assertEqualIntA(m, 0, archive_match_include_pattern(m, "^aa*"));
+       /* Test for pattern "aa*" */
+       assertEqualIntA(m, 0, archive_match_include_pattern(m, "aa*"));
 
        /* Test with 'aa1234', which should not be excluded. */
        archive_entry_copy_pathname(ae, "aa1234");
@@ -282,8 +282,8 @@ test_inclusion_wcs(void)
                return;
        }
 
-       /* Test for pattern "^aa*" */
-       assertEqualIntA(m, 0, archive_match_include_pattern_w(m, L"^aa*"));
+       /* Test for pattern "aa*" */
+       assertEqualIntA(m, 0, archive_match_include_pattern_w(m, L"aa*"));
 
        /* Test with 'aa1234', which should not be excluded. */
        archive_entry_copy_pathname(ae, "aa1234");
@@ -383,8 +383,8 @@ test_exclusion_and_inclusion(void)
        }
 
        assertEqualIntA(m, 0, archive_match_exclude_pattern(m, "^aaa*"));
-       assertEqualIntA(m, 0, archive_match_include_pattern_w(m, L"^aa*"));
-       assertEqualIntA(m, 0, archive_match_include_pattern(m, "^a1*"));
+       assertEqualIntA(m, 0, archive_match_include_pattern_w(m, L"aa*"));
+       assertEqualIntA(m, 0, archive_match_include_pattern(m, "a1*"));
 
        /* Test with 'aa1234', which should not be excluded. */
        archive_entry_copy_pathname(ae, "aa1234");
@@ -413,13 +413,13 @@ test_exclusion_and_inclusion(void)
        /* Verify unmatched inclusion patterns. */
        assertEqualIntA(m, ARCHIVE_OK,
            archive_match_path_unmatched_inclusions_next(m, &mp));
-       assertEqualString("^a1*", mp);
+       assertEqualString("a1*", mp);
        assertEqualIntA(m, ARCHIVE_EOF,
            archive_match_path_unmatched_inclusions_next(m, &mp));
        /* Verify unmatched inclusion patterns again in Wide-Char. */
        assertEqualIntA(m, ARCHIVE_OK,
            archive_match_path_unmatched_inclusions_next_w(m, &wp));
-       assertEqualWString(L"^a1*", wp);
+       assertEqualWString(L"a1*", wp);
        assertEqualIntA(m, ARCHIVE_EOF,
            archive_match_path_unmatched_inclusions_next_w(m, &wp));
 
index 3b212aca9d94225e909a3f767fe1d133a12758cd..ea75851dbe64dc878773a982986401fa25eb9501 100644 (file)
@@ -56,6 +56,10 @@ DEFINE_TEST(test_archive_pathmatch)
        assertEqualInt(0, archive_pathmatch_w(L"a/b/c", NULL, 0));
 
        /* Empty pattern only matches empty string. */
+       assertEqualInt(1, archive_pathmatch(NULL,NULL, 0));
+       assertEqualInt(1, archive_pathmatch(NULL,"", 0));
+       assertEqualInt(0, archive_pathmatch(NULL,"a", 0));
+       assertEqualInt(1, archive_pathmatch("",NULL, 0));
        assertEqualInt(1, archive_pathmatch("","", 0));
        assertEqualInt(0, archive_pathmatch("","a", 0));
        assertEqualInt(1, archive_pathmatch("*","", 0));
@@ -76,11 +80,15 @@ DEFINE_TEST(test_archive_pathmatch)
        assertEqualInt(0, archive_pathmatch("a", "ab", 0));
        assertEqualInt(0, archive_pathmatch("a", "ab", 0));
        assertEqualInt(1, archive_pathmatch("a?c", "abc", 0));
+       assertEqualInt(1, archive_pathmatch("*a", "/a", 0));
+       assertEqualInt(1, archive_pathmatch("*a", "a", 0));
        /* SUSv2: ? matches / */
        assertEqualInt(1, archive_pathmatch("a?c", "a/c", 0));
        assertEqualInt(1, archive_pathmatch("a?*c*", "a/c", 0));
        assertEqualInt(1, archive_pathmatch("*a*", "a/c", 0));
        assertEqualInt(1, archive_pathmatch("*a*", "/a/c", 0));
+       assertEqualInt(0, archive_pathmatch("*a", "/a/c", 0));
+       assertEqualInt(0, archive_pathmatch("*a", "a/c", 0));
        assertEqualInt(1, archive_pathmatch("*a*", "defaaaaaaa", 0));
        assertEqualInt(0, archive_pathmatch("a*", "defghi", 0));
        assertEqualInt(0, archive_pathmatch("*a*", "defghi", 0));
@@ -201,6 +209,14 @@ DEFINE_TEST(test_archive_pathmatch)
        failure("Trailing '/.' is still the same directory.");
        assertEqualInt(1, archive_pathmatch("./abc*/./def", "abc/def/.", 0));
 
+       /* Anchor characters without flags not special. */
+       assertEqualInt(0, archive_pathmatch("^abc", "abc", 0));
+       assertEqualInt(1, archive_pathmatch("^abc", "^abc", 0));
+       assertEqualInt(0, archive_pathmatch("abc$", "abc", 0));
+       assertEqualInt(1, archive_pathmatch("abc$", "abc$", 0));
+       assertEqualInt(0, archive_pathmatch("^abc$", "abc", 0));
+       assertEqualInt(1, archive_pathmatch("^abc$", "^abc$", 0));
+
        /* Matches not anchored at beginning. */
        assertEqualInt(0,
            archive_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_START));