]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Improve the testing of tar -X and try to correctly handle some odd cases.
authorTim Kientzle <kientzle@gmail.com>
Sun, 11 Apr 2010 18:08:36 +0000 (14:08 -0400)
committerTim Kientzle <kientzle@gmail.com>
Sun, 11 Apr 2010 18:08:36 +0000 (14:08 -0400)
Here are some of the cases currently handled
(assuming test.tar contains a single entry "file1"):

 $ tar xf test.tar file1

Extracts file1 with no error.

 $ tar xf test.tar file1 file2

Extracts file1, error because file2 was requested but not found.

 $ tar xf test.tar file1 'file2*'

Extracts file1, error because 'file2*' pattern matched no entries.

 $ tar xf test.tar file1 file1

Extracts file1 with no error

 $ tar xf test.tar file1 'file*'

Extracts file1 with no error

 $ tar xf test.tar --exclude=file1

Does not extract file1, no error.

 $ tar xf test.tar --exclude=file1 file1

Does not extract file1, no error.

 $ tar xf test.tar --exclude=file2 file1

Extracts file1, no error.

SVN-Revision: 2229

libarchive_fe/matching.c
tar/test/test_option_X_upper.c

index f774ac773ca9f614591b6484779a061e61118b82..b2aba0227eaf9015b6683aebb3f474bc3409a20b 100644 (file)
@@ -156,40 +156,41 @@ lafe_excluded(struct lafe_matching *matching, const char *pathname)
        if (matching == NULL)
                return (0);
 
+       /* Mark off any unmatched inclusions. */
+       /* In particular, if a filename does appear in the archive and
+        * is explicitly included and excluded, then we don't report
+        * it as missing even though we don't extract it.
+        */
+       matched = NULL;
+       for (match = matching->inclusions; match != NULL; match = match->next){
+               if (match->matches == 0
+                   && match_inclusion(match, pathname)) {
+                       matching->inclusions_unmatched_count--;
+                       match->matches++;
+                       matched = match;
+               }
+       }
+
        /* Exclusions take priority */
        for (match = matching->exclusions; match != NULL; match = match->next){
                if (match_exclusion(match, pathname))
                        return (1);
        }
 
-       /* Then check for inclusions */
-       matched = NULL;
+       /* It's not excluded and we found an inclusion above, so it's included. */
+       if (matched != NULL)
+               return (0);
+
+
+       /* We didn't find an unmatched inclusion, check the remaining ones. */
        for (match = matching->inclusions; match != NULL; match = match->next){
-               if (match_inclusion(match, pathname)) {
-                       /*
-                        * If this pattern has never been matched,
-                        * then we're done.
-                        */
-                       if (match->matches == 0) {
-                               match->matches++;
-                               matching->inclusions_unmatched_count--;
-                               return (0);
-                       }
-                       /*
-                        * Otherwise, remember the match but keep checking
-                        * in case we can tick off an unmatched pattern.
-                        */
-                       matched = match;
+               /* We looked at previously-unmatched inclusions already. */
+               if (match->matches > 0
+                   && match_inclusion(match, pathname)) {
+                       match->matches++;
+                       return (0);
                }
        }
-       /*
-        * We didn't find a pattern that had never been matched, but
-        * we did find a match, so count it and exit.
-        */
-       if (matched != NULL) {
-               matched->matches++;
-               return (0);
-       }
 
        /* If there were inclusions, default is to exclude. */
        if (matching->inclusions != NULL)
@@ -219,11 +220,7 @@ match_exclusion(struct match *match, const char *pathname)
 static int
 match_inclusion(struct match *match, const char *pathname)
 {
-#if 0
-       return (lafe_pathmatch(match->pattern, pathname, 0));
-#else
        return (lafe_pathmatch(match->pattern, pathname, PATHMATCH_NO_ANCHOR_END));
-#endif 
 }
 
 void
index 5aedc5eca437cd12f260c2f898f1c3a19ccf66bb..1aa21fc90a670f319151849a90eb32675d6322f0 100644 (file)
@@ -34,7 +34,10 @@ DEFINE_TEST(test_option_X_upper)
         */
        assertMakeFile("file1", 0644, "file1");
        assertMakeFile("file2", 0644, "file2");
-       assertEqualInt(0, systemf("%s -cf archive.tar file1 file2", testprog));
+       assertMakeFile("file3a", 0644, "file3a");
+       assertMakeFile("file4a", 0644, "file4a");
+       assertEqualInt(0,
+           systemf("%s -cf archive.tar file1 file2 file3a file4a", testprog));
 
        /*
         * Now, try extracting from the test archive with various -X usage.
@@ -50,6 +53,8 @@ DEFINE_TEST(test_option_X_upper)
 
        assertFileContents("file1", 5, "file1");
        assertFileContents("file2", 5, "file2");
+       assertFileContents("file3a", 6, "file3a");
+       assertFileContents("file4a", 6, "file4a");
        assertEmptyFile("test.out");
        assertEmptyFile("test.err");
        assertChdir("..");
@@ -62,6 +67,78 @@ DEFINE_TEST(test_option_X_upper)
            systemf("%s -xf ../archive.tar -X exclusions >test.out 2>test.err", testprog));
        assertFileNotExists("file1");
        assertFileContents("file2", 5, "file2");
+       assertFileContents("file3a", 6, "file3a");
+       assertFileContents("file4a", 6, "file4a");
+       assertEmptyFile("test.out");
+       assertEmptyFile("test.err");
+       assertChdir("..");
+
+       /* Test 3: Use -X to skip multiple files */
+       assertMakeDir("test3", 0755);
+       assertChdir("test3");
+       assertMakeFile("exclusions", 0644, "file1\nfile2\n");
+       assertEqualInt(0,
+           systemf("%s -xf ../archive.tar -X exclusions >test.out 2>test.err", testprog));
+       assertFileNotExists("file1");
+       assertFileNotExists("file2");
+       assertFileContents("file3a", 6, "file3a");
+       assertFileContents("file4a", 6, "file4a");
+       assertEmptyFile("test.out");
+       assertEmptyFile("test.err");
+       assertChdir("..");
+
+       /* Test 4: Omit trailing \n */
+       assertMakeDir("test4", 0755);
+       assertChdir("test4");
+       assertMakeFile("exclusions", 0644, "file1\nfile2");
+       assertEqualInt(0,
+           systemf("%s -xf ../archive.tar -X exclusions >test.out 2>test.err", testprog));
+       assertFileNotExists("file1");
+       assertFileNotExists("file2");
+       assertFileContents("file3a", 6, "file3a");
+       assertFileContents("file4a", 6, "file4a");
+       assertEmptyFile("test.out");
+       assertEmptyFile("test.err");
+       assertChdir("..");
+
+       /* Test 5: include/exclude without overlap */
+       assertMakeDir("test5", 0755);
+       assertChdir("test5");
+       assertMakeFile("exclusions", 0644, "file1\nfile2");
+       assertEqualInt(0,
+           systemf("%s -xf ../archive.tar -X exclusions file3a >test.out 2>test.err", testprog));
+       assertFileNotExists("file1");
+       assertFileNotExists("file2");
+       assertFileContents("file3a", 6, "file3a");
+       assertFileNotExists("file4a");
+       assertEmptyFile("test.out");
+       assertEmptyFile("test.err");
+       assertChdir("..");
+
+       /* Test 6: Overlapping include/exclude */
+       assertMakeDir("test6", 0755);
+       assertChdir("test6");
+       assertMakeFile("exclusions", 0644, "file1\nfile2");
+       assertEqualInt(0,
+           systemf("%s -xf ../archive.tar -X exclusions file1 file3a >test.out 2>test.err", testprog));
+       assertFileNotExists("file1");
+       assertFileNotExists("file2");
+       assertFileContents("file3a", 6, "file3a");
+       assertFileNotExists("file4a");
+       assertEmptyFile("test.out");
+       assertEmptyFile("test.err");
+       assertChdir("..");
+
+       /* Test 7: with pattern */
+       assertMakeDir("test7", 0755);
+       assertChdir("test7");
+       assertMakeFile("exclusions", 0644, "file*a\nfile1");
+       assertEqualInt(0,
+           systemf("%s -xf ../archive.tar -X exclusions >test.out 2>test.err", testprog));
+       assertFileNotExists("file1");
+       assertFileContents("file2", 5, "file2");
+       assertFileNotExists("file3a");
+       assertFileNotExists("file4a");
        assertEmptyFile("test.out");
        assertEmptyFile("test.err");
        assertChdir("..");