From: Martin Matuska Date: Mon, 6 May 2019 23:16:12 +0000 (+0200) Subject: mtree reader: allow only printable ascii characters X-Git-Tag: v3.4.0~45 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=45c5008c4811a3757bc24d83f9f4b3355987ede9;p=thirdparty%2Flibarchive.git mtree reader: allow only printable ascii characters --- diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c index 5b0eadc08..a7331a267 100644 --- a/libarchive/archive_read_support_format_mtree.c +++ b/libarchive/archive_read_support_format_mtree.c @@ -45,6 +45,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011 #ifdef HAVE_STRING_H #include #endif +#ifdef HAVE_CTYPE_H +#include +#endif #include "archive.h" #include "archive_entry.h" @@ -1011,7 +1014,7 @@ read_mtree(struct archive_read *a, struct mtree *mtree) { ssize_t len; uintmax_t counter; - char *p; + char *p, *s; struct mtree_option *global; struct mtree_entry *last_entry; int r, is_form_d; @@ -1025,6 +1028,7 @@ read_mtree(struct archive_read *a, struct mtree *mtree) (void)detect_form(a, &is_form_d); for (counter = 1; ; ++counter) { + r = ARCHIVE_OK; len = readline(a, mtree, &p, 65536); if (len == 0) { mtree->this_entry = mtree->entries; @@ -1045,6 +1049,15 @@ read_mtree(struct archive_read *a, struct mtree *mtree) continue; if (*p == '\r' || *p == '\n' || *p == '\0') continue; + /* Non-printable characters are not allowed */ + for (s = p;s < p + len - 1; s++) { + if (!isprint(*s)) { + r = ARCHIVE_FATAL; + break; + } + } + if (r != ARCHIVE_OK) + break; if (*p != '/') { r = process_add_entry(a, mtree, &global, p, len, &last_entry, is_form_d); diff --git a/libarchive/test/test_read_format_mtree.c b/libarchive/test/test_read_format_mtree.c index 8576d579f..df6f6cde0 100644 --- a/libarchive/test/test_read_format_mtree.c +++ b/libarchive/test/test_read_format_mtree.c @@ -717,4 +717,28 @@ DEFINE_TEST(test_read_format_mtree_nonexistent_contents_file) assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); } +/* + * Check mtree file with non-printable ascii characters + */ +DEFINE_TEST(test_read_format_mtree_noprint) +{ + const char reffile[] = "test_read_format_mtree_noprint.mtree"; + struct archive_entry *ae; + struct archive *a; + extract_reference_file(reffile); + + 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_filename(a, reffile, 11)); + + assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); + assertEqualString("Can't parse line 3", archive_error_string(a)); + + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} diff --git a/libarchive/test/test_read_format_mtree_noprint.mtree.uu b/libarchive/test/test_read_format_mtree_noprint.mtree.uu new file mode 100644 index 000000000..7965cdf29 --- /dev/null +++ b/libarchive/test/test_read_format_mtree_noprint.mtree.uu @@ -0,0 +1,4 @@ +begin 644 test_read_format_mtree_noprint.mtree +K(VUT7!E/61I<@ID:7)?P[;%H<2'('1Y<&4]9&ER"@`` +` +end