diff options
Diffstat (limited to 'libarchive/archive_read_support_format_ar.c')
-rw-r--r-- | libarchive/archive_read_support_format_ar.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/libarchive/archive_read_support_format_ar.c b/libarchive/archive_read_support_format_ar.c index 40be18c0cce2..4b5b66bd50a6 100644 --- a/libarchive/archive_read_support_format_ar.c +++ b/libarchive/archive_read_support_format_ar.c @@ -122,7 +122,9 @@ archive_read_support_format_ar(struct archive *_a) archive_read_format_ar_read_data, archive_read_format_ar_skip, NULL, - archive_read_format_ar_cleanup); + archive_read_format_ar_cleanup, + NULL, + NULL); if (r != ARCHIVE_OK) { free(ar); @@ -178,7 +180,7 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry, if (strncmp(h + AR_fmag_offset, "`\n", 2) != 0) { archive_set_error(&a->archive, EINVAL, "Incorrect file header signature"); - return (ARCHIVE_WARN); + return (ARCHIVE_FATAL); } /* Copy filename into work buffer. */ @@ -237,8 +239,15 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry, * and are not terminated in '/', so we don't trim anything * that starts with '/'.) */ - if (filename[0] != '/' && *p == '/') + if (filename[0] != '/' && p > filename && *p == '/') { *p = '\0'; + } + + if (p < filename) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Found entry with empty filename"); + return (ARCHIVE_FATAL); + } /* * '//' is the GNU filename table. @@ -260,12 +269,12 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry, if (entry_size == 0) { archive_set_error(&a->archive, EINVAL, "Invalid string table"); - return (ARCHIVE_WARN); + return (ARCHIVE_FATAL); } if (ar->strtab != NULL) { archive_set_error(&a->archive, EINVAL, "More than one string tables exist"); - return (ARCHIVE_WARN); + return (ARCHIVE_FATAL); } /* Read the filename table into memory. */ @@ -309,11 +318,11 @@ _ar_read_header(struct archive_read *a, struct archive_entry *entry, */ if (ar->strtab == NULL || number > ar->strtab_size) { archive_set_error(&a->archive, EINVAL, - "Can't find long filename for entry"); + "Can't find long filename for GNU/SVR4 archive entry"); archive_entry_copy_pathname(entry, filename); /* Parse the time, owner, mode, size fields. */ ar_parse_common_header(ar, entry, h); - return (ARCHIVE_WARN); + return (ARCHIVE_FATAL); } archive_entry_copy_pathname(entry, &ar->strtab[(size_t)number]); @@ -571,7 +580,7 @@ bad_string_table: "Invalid string table"); free(ar->strtab); ar->strtab = NULL; - return (ARCHIVE_WARN); + return (ARCHIVE_FATAL); } static uint64_t |