]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Fix a mtree detection bug brought by a commit 78307be86b71.
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Mon, 24 Sep 2012 11:32:42 +0000 (20:32 +0900)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Mon, 24 Sep 2012 11:32:42 +0000 (20:32 +0900)
libarchive/archive_read_support_format_mtree.c
libarchive/test/test_read_format_mtree.c

index 4f0ffbd9a8e81c3b4f425176f9fca3e04324eaa1..e1413a373f2ecc4a766a1992faf088e28e2898d4 100644 (file)
@@ -510,7 +510,8 @@ bid_entry(const char *p, ssize_t len, ssize_t nl, int *last_is_path)
        /*
         * Skip the path-name which is quoted.
         */
-       while (ll > 0 && *pp != ' ' && *pp != '\t') {
+       while (ll > 0 && *pp != ' ' &&*pp != '\t' && *pp != '\r' &&
+           *pp != '\n') {
                if (!safe_char[*(const unsigned char *)pp]) {
                        f = 0;
                        break;
@@ -525,6 +526,7 @@ bid_entry(const char *p, ssize_t len, ssize_t nl, int *last_is_path)
        if (f == 0) {
                const char *pb = p + len - nl;
                int name_len = 0;
+               int slash;
 
                /* Do not accept multi lines for form D. */
                if (pb-2 >= p &&
@@ -533,12 +535,17 @@ bid_entry(const char *p, ssize_t len, ssize_t nl, int *last_is_path)
                if (pb-1 >= p && pb[-1] == '\\')
                        return (-1);
 
+               slash = 0;
                while (p <= --pb && *pb != ' ' && *pb != '\t') {
                        if (!safe_char[*(const unsigned char *)pb])
                                return (-1);
                        name_len++;
+                       /* The pathname should have a slash in this
+                        * format. */
+                       if (*pb == '/')
+                               slash = 1;
                }
-               if (name_len == 0)
+               if (name_len == 0 || slash == 0)
                        return (-1);
                ll = len - nl - name_len;
                pp = p;
index 419e7c27046da96ef535e240b1f90563bc741887..bab4ee03652f730c238d34576a6ef073660fe275 100644 (file)
@@ -231,6 +231,53 @@ DEFINE_TEST(test_read_format_mtree)
        test_read_format_mtree3();
 }
 
+DEFINE_TEST(test_read_format_mtree_filenames_only)
+{
+       static char archive[] =
+           "/set type=file mode=0644\n"
+           "./a\n"
+           "./b\n"
+           "./c\n"
+           "./d\n"
+           "./e\n"
+           "./f mode=0444\n";
+       struct archive_entry *ae;
+       struct archive *a;
+
+       assertMakeFile("file", 0644, "file contents");
+
+       assert((a = archive_read_new()) != NULL);
+       assertEqualIntA(a, ARCHIVE_OK,
+           archive_read_support_filter_all(a));
+       assertEqualIntA(a, ARCHIVE_OK,
+           archive_read_support_format_all(a));
+       assertEqualIntA(a, ARCHIVE_OK,
+           archive_read_open_memory(a, archive, sizeof(archive)));
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       assertEqualString(archive_entry_pathname(ae), "./a");
+       assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       assertEqualString(archive_entry_pathname(ae), "./b");
+       assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       assertEqualString(archive_entry_pathname(ae), "./c");
+       assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       assertEqualString(archive_entry_pathname(ae), "./d");
+       assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       assertEqualString(archive_entry_pathname(ae), "./e");
+       assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+       assertEqualString(archive_entry_pathname(ae), "./f");
+       assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0444);
+
+       assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+       assertEqualInt(6, archive_file_count(a));
+       assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
 DEFINE_TEST(test_read_format_mtree_nomagic_v1_form)
 {
        const char reffile[] = "test_read_format_mtree_nomagic.mtree";