aboutsummaryrefslogtreecommitdiff
path: root/libarchive/archive_read_support_format_ar.c
diff options
context:
space:
mode:
Diffstat (limited to 'libarchive/archive_read_support_format_ar.c')
-rw-r--r--libarchive/archive_read_support_format_ar.c25
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