From b910cb70d4c1b311c9d85cd536a6c91647c43df7 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sun, 28 Apr 2024 23:48:05 +0200 Subject: [PATCH] xar: Fix another infinite loop and expat error handling (#2150) Fixes two issues: - expat code keeps track of error conditions - adding link=original multiple times is prohibited --- libarchive/archive_read_support_format_xar.c | 8 ++++++-- libarchive/test/test_read_format_xar_doublelink.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libarchive/archive_read_support_format_xar.c b/libarchive/archive_read_support_format_xar.c index 2c343264..cefb3641 100644 --- a/libarchive/archive_read_support_format_xar.c +++ b/libarchive/archive_read_support_format_xar.c @@ -2055,9 +2055,10 @@ xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list) attr = attr->next) { if (strcmp(attr->name, "link") != 0) continue; - if (xar->file->hdnext != NULL || xar->file->link != 0) { + if (xar->file->hdnext != NULL || xar->file->link != 0 || + xar->file == xar->hdlink_orgs) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "File with multiple link targets"); + "File with multiple link attributes"); return (ARCHIVE_FATAL); } if (strcmp(attr->value, "original") == 0) { @@ -3256,6 +3257,9 @@ expat_start_cb(void *userData, const XML_Char *name, const XML_Char **atts) struct xmlattr_list list; int r; + if (ud->state != ARCHIVE_OK) + return; + r = expat_xmlattr_setup(a, &list, atts); if (r == ARCHIVE_OK) r = xml_start(a, (const char *)name, &list); diff --git a/libarchive/test/test_read_format_xar_doublelink.c b/libarchive/test/test_read_format_xar_doublelink.c index 73ddebd2..78d6626a 100644 --- a/libarchive/test/test_read_format_xar_doublelink.c +++ b/libarchive/test/test_read_format_xar_doublelink.c @@ -47,7 +47,7 @@ DEFINE_TEST(test_read_format_xar_doublelink) assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae)); assertEqualString(archive_error_string(a), - "File with multiple link targets"); + "File with multiple link attributes"); assert(archive_errno(a) != 0); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); -- 2.39.2