summaryrefslogtreecommitdiffstats
path: root/lib/libarchive
diff options
context:
space:
mode:
authorkaiw <kaiw@FreeBSD.org>2008-03-12 21:10:26 +0000
committerkaiw <kaiw@FreeBSD.org>2008-03-12 21:10:26 +0000
commit5b0dd8ae2422cb4f801bf371c13092b8fda8b82f (patch)
treef38f3fe9be9ccfeef95ba78981b448f121341b7f /lib/libarchive
parent3bce78576c979c347173af624aba96b8cd85b98f (diff)
downloadFreeBSD-src-5b0dd8ae2422cb4f801bf371c13092b8fda8b82f.zip
FreeBSD-src-5b0dd8ae2422cb4f801bf371c13092b8fda8b82f.tar.gz
Current 'ar' read support in libarchive can only handle a GNU/SVR4
filename table whose size is less than 65536 bytes. The original intention was to not consume the filename table, so the client will have a chance to look at it. To achieve that, the library call decompressor->read_ahead to read(look ahead) but do not call decompressor->consume to consume the data, thus a limit was raised since read_ahead call can only look ahead at most BUFFER_SIZE(65536) bytes at the moment, and you can not "look any further" before you consume what you already "saw". This commit will turn GNU/SVR4 filename table into "archive format data", i.e., filename table will be consumed by libarchive, so the 65536-bytes limit will be gone, but client can no longer have access to the content of filename table. 'ar' support test suite is changed accordingly. BSD ar(1) is not affected by this change since it doesn't look at the filename table. Reported by: erwin Discussed with: jkoshy, kientzle Reviewed by: jkoshy, kientzle Approved by: jkoshy(mentor), kientzle
Diffstat (limited to 'lib/libarchive')
-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