From: Michihiro NAKAJIMA Date: Mon, 24 Sep 2012 11:32:42 +0000 (+0900) Subject: Fix a mtree detection bug brought by a commit 78307be86b71. X-Git-Tag: v3.1.0~49 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c892183b1012eb82958d1b59c53b9273b98e5d19;p=thirdparty%2Flibarchive.git Fix a mtree detection bug brought by a commit 78307be86b71. --- diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c index 4f0ffbd9a..e1413a373 100644 --- a/libarchive/archive_read_support_format_mtree.c +++ b/libarchive/archive_read_support_format_mtree.c @@ -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; diff --git a/libarchive/test/test_read_format_mtree.c b/libarchive/test/test_read_format_mtree.c index 419e7c270..bab4ee036 100644 --- a/libarchive/test/test_read_format_mtree.c +++ b/libarchive/test/test_read_format_mtree.c @@ -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";