summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libarchive/archive_read_support_format_ar.c75
-rw-r--r--lib/libarchive/test/test_read_format_ar.c4
-rw-r--r--lib/libarchive/test/test_write_format_ar.c4
3 files changed, 41 insertions, 42 deletions
diff --git a/lib/libarchive/archive_read_support_format_ar.c b/lib/libarchive/archive_read_support_format_ar.c
index 5ce14b9..9ce5160 100644
--- a/lib/libarchive/archive_read_support_format_ar.c
+++ b/lib/libarchive/archive_read_support_format_ar.c
@@ -83,8 +83,7 @@ static int archive_read_format_ar_read_header(struct archive_read *a,
struct archive_entry *e);
static uint64_t ar_atol8(const char *p, unsigned char_cnt);
static uint64_t ar_atol10(const char *p, unsigned char_cnt);
-static int ar_parse_gnu_filename_table(struct archive_read *, struct ar *,
- const void *, size_t);
+static int ar_parse_gnu_filename_table(struct archive_read *a);
static int ar_parse_common_header(struct ar *ar, struct archive_entry *,
const char *h);
@@ -167,8 +166,8 @@ archive_read_format_ar_read_header(struct archive_read *a,
struct ar *ar;
uint64_t number; /* Used to hold parsed numbers before validation. */
ssize_t bytes_read;
- size_t bsd_name_length, entry_size;
- char *p;
+ size_t bsd_name_length, entry_size, s;
+ char *p, *st;
const void *b;
const char *h;
int r;
@@ -277,22 +276,42 @@ archive_read_format_ar_read_header(struct archive_read *a,
return (ARCHIVE_FATAL);
}
entry_size = (size_t)number;
+ if (entry_size == 0) {
+ archive_set_error(&a->archive, EINVAL,
+ "Invalid string table");
+ return (ARCHIVE_WARN);
+ }
+ if (ar->strtab != NULL) {
+ archive_set_error(&a->archive, EINVAL,
+ "More than one string tables exist");
+ return (ARCHIVE_WARN);
+ }
+
/* Read the filename table into memory. */
- bytes_read = (a->decompressor->read_ahead)(a, &b, entry_size);
- if (bytes_read <= 0)
- return (ARCHIVE_FATAL);
- if ((size_t)bytes_read < entry_size) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Truncated input file");
+ st = malloc(entry_size);
+ if (st == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate filename table buffer");
return (ARCHIVE_FATAL);
}
- /*
- * Don't consume the contents, so the client will
- * also get a shot at reading it.
- */
+ ar->strtab = st;
+ ar->strtab_size = entry_size;
+ for (s = entry_size; s > 0; s -= bytes_read) {
+ bytes_read = (a->decompressor->read_ahead)(a, &b, s);
+ if (bytes_read <= 0)
+ return (ARCHIVE_FATAL);
+ if (bytes_read > (ssize_t)s)
+ bytes_read = s;
+ memcpy(st, b, bytes_read);
+ st += bytes_read;
+ (a->decompressor->consume)(a, bytes_read);
+ }
+ /* All contents are consumed. */
+ ar->entry_bytes_remaining = 0;
+ archive_entry_set_size(entry, ar->entry_bytes_remaining);
/* Parse the filename table. */
- return (ar_parse_gnu_filename_table(a, ar, b, entry_size));
+ return (ar_parse_gnu_filename_table(a));
}
/*
@@ -492,31 +511,15 @@ archive_read_format_ar_skip(struct archive_read *a)
}
static int
-ar_parse_gnu_filename_table(struct archive_read *a, struct ar *ar,
- const void *h, size_t size)
+ar_parse_gnu_filename_table(struct archive_read *a)
{
+ struct ar *ar;
char *p;
+ size_t size;
- if (ar->strtab != NULL) {
- archive_set_error(&a->archive, EINVAL,
- "More than one string tables exist");
- return (ARCHIVE_WARN);
- }
-
- if (size == 0) {
- archive_set_error(&a->archive, EINVAL, "Invalid string table");
- return (ARCHIVE_WARN);
- }
-
- ar->strtab_size = size;
- ar->strtab = malloc(size);
- if (ar->strtab == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate string table buffer");
- return (ARCHIVE_FATAL);
- }
+ ar = (struct ar*)(a->format->data);
+ size = ar->strtab_size;
- (void)memcpy(ar->strtab, h, size);
for (p = ar->strtab; p < ar->strtab + size - 1; ++p) {
if (*p == '/') {
*p++ = '\0';
diff --git a/lib/libarchive/test/test_read_format_ar.c b/lib/libarchive/test/test_read_format_ar.c
index 36c9c2a..95e8b3f 100644
--- a/lib/libarchive/test/test_read_format_ar.c
+++ b/lib/libarchive/test/test_read_format_ar.c
@@ -75,9 +75,7 @@ DEFINE_TEST(test_read_format_ar)
assertEqualInt(0, archive_entry_mtime(ae));
assertEqualInt(0, archive_entry_uid(ae));
assertEqualInt(0, archive_entry_gid(ae));
- assertEqualInt(40, archive_entry_size(ae));
- assertEqualIntA(a, 40, archive_read_data(a, buff, 50));
- assert(0 == memcmp(buff, "yyytttsssaaafff.o/\nhhhhjjjjkkkkllll.o/\n\n", 40));
+ assertEqualInt(0, archive_entry_size(ae));
/* First Entry */
assertA(0 == archive_read_next_header(a, &ae));
diff --git a/lib/libarchive/test/test_write_format_ar.c b/lib/libarchive/test/test_write_format_ar.c
index aff781b..cc49b28 100644
--- a/lib/libarchive/test/test_write_format_ar.c
+++ b/lib/libarchive/test/test_write_format_ar.c
@@ -119,9 +119,7 @@ DEFINE_TEST(test_write_format_ar)
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(0, archive_entry_mtime(ae));
assertEqualString("//", archive_entry_pathname(ae));
- assertEqualInt(strlen(strtab), archive_entry_size(ae));
- assertEqualIntA(a, strlen(strtab), archive_read_data(a, buff2, 100));
- assert(0 == memcmp(buff2, strtab, strlen(strtab)));
+ assertEqualInt(0, archive_entry_size(ae));
assertA(0 == archive_read_next_header(a, &ae));
assert(1 == archive_entry_mtime(ae));
OpenPOWER on IntegriCloud