From: Dustin L. Howett Date: Sat, 15 Jun 2024 00:13:42 +0000 (-0500) Subject: xar: guard against file entries containing multiple name elements (#2236) X-Git-Tag: v3.7.5~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e3c0c8d4800fda6b92bc1c50d3ece82ae688dae5;p=thirdparty%2Flibarchive.git xar: guard against file entries containing multiple name elements (#2236) It appears that there are xar archives (in the form of Apple .pkg files) that contain TOCs with duplicated name elements: ```xml ... file PackageInfo PackageInfo PackageInfo ``` When libarchive encounters one such file, it will produce an archive_entry named PackageInfoPackageInfoPackageInfo. To produce a test archive, the XAR writer was modified to emit two name elements. --- diff --git a/Makefile.am b/Makefile.am index eb88654fc..372ade1bd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -937,6 +937,7 @@ libarchive_test_EXTRA_DIST=\ libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \ libarchive/test/test_read_format_warc.warc.uu \ libarchive/test/test_read_format_xar_doublelink.xar.uu \ + libarchive/test/test_read_format_xar_duplicate_filename_node.xar.uu \ libarchive/test/test_read_format_zip.zip.uu \ libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu \ libarchive/test/test_read_format_zip_7z_deflate.zip.uu \ diff --git a/libarchive/archive_read_support_format_xar.c b/libarchive/archive_read_support_format_xar.c index dbc31df94..7c327e02f 100644 --- a/libarchive/archive_read_support_format_xar.c +++ b/libarchive/archive_read_support_format_xar.c @@ -2707,6 +2707,9 @@ xml_data(void *userData, const char *s, size_t len) switch (xar->xmlsts) { case FILE_NAME: + if (xar->file->has & HAS_PATHNAME) + break; + if (xar->file->parent != NULL) { archive_string_concat(&(xar->file->pathname), &(xar->file->parent->pathname)); diff --git a/libarchive/test/test_read_format_xar.c b/libarchive/test/test_read_format_xar.c index daff29216..41cbd7dab 100644 --- a/libarchive/test/test_read_format_xar.c +++ b/libarchive/test/test_read_format_xar.c @@ -860,3 +860,34 @@ DEFINE_TEST(test_read_format_xar) verify(archive12, sizeof(archive12), verify12, NULL, GZIP); verifyB(archive13, sizeof(archive13)); } + +DEFINE_TEST(test_read_format_xar_duplicate_filename_node) +{ + static const char *reffiles[] = + { + "test_read_format_xar_duplicate_filename_node.xar", + NULL + }; + struct archive_entry *ae; + struct archive *a; + int r; + + extract_reference_files(reffiles); + assert((a = archive_read_new()) != NULL); + assertA(0 == archive_read_support_filter_all(a)); + + r = archive_read_support_format_xar(a); + if (r == ARCHIVE_WARN) { + skipping("xar reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + return; + } + + assertA(0 == archive_read_open_filenames(a, reffiles, 10240)); + + assertA(0 == archive_read_next_header(a, &ae)); + assertEqualString("File", archive_entry_pathname(ae)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} diff --git a/libarchive/test/test_read_format_xar_duplicate_filename_node.xar.uu b/libarchive/test/test_read_format_xar_duplicate_filename_node.xar.uu new file mode 100644 index 000000000..18cbcf589 --- /dev/null +++ b/libarchive/test/test_read_format_xar_duplicate_filename_node.xar.uu @@ -0,0 +1,14 @@ +begin 644 test_read_format_xar_duplicate_filename_node.xar +M>&%R(0`<``$````````!EP````````.]`````7BVIC +MC('((;N7JG3.JNUT4V]=_P6[ +MCJI%(W5=;-VWU[T7N[OT^8E?H+6/XW#3B`%8*%H%QMIY1ENI=JZW0%\=R0MW>1YITR*.1K1S'3ZUL?A:`"C +M-S2YFP2Y+I6CI:UFX;0&&W]O&8X&^#]AKD>5Y@,QP)G0=2-M&E'"DIBC^V\F +MI3IKH>HF]0-&68!]PM$LF[6JW@8S9CM4K][$>J%9K57B@"FM5"0;FG_V7JB[,(?5MHB-8#&+(0L`DQED2!@!)1(,PS^.$,I&)+"-1 +M&`*)./KIZ:N]:-%?COHMO%\?NI\?1_T]?@(L`P/8\;44V2:R;"\D48GC?CRL +C(UAG)C5XG./E`@``)@`8>)R%4TEN@S`4W5?J'1![:F.,@<@` +` +end