diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libarchive/archive_read_support_format_ar.c | 75 | ||||
-rw-r--r-- | lib/libarchive/test/test_read_format_ar.c | 4 | ||||
-rw-r--r-- | lib/libarchive/test/test_write_format_ar.c | 4 |
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)); |