summaryrefslogtreecommitdiff
path: root/libarchive/archive_read_support_format_tar.c
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2012-07-27 08:24:12 +0000
committerMartin Matuska <mm@FreeBSD.org>2012-07-27 08:24:12 +0000
commit81418b36c02b6434acd4b8ae4cfb8c80a3742fd4 (patch)
tree4b551422581ae9a8093415e07c619e2a59ef6a7b /libarchive/archive_read_support_format_tar.c
parent132160f77407d2174d2bec0a8ba9c6eefc4429d7 (diff)
Diffstat (limited to 'libarchive/archive_read_support_format_tar.c')
-rw-r--r--libarchive/archive_read_support_format_tar.c146
1 files changed, 76 insertions, 70 deletions
diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c
index 52d431e7e0c3e..4538331f3d053 100644
--- a/libarchive/archive_read_support_format_tar.c
+++ b/libarchive/archive_read_support_format_tar.c
@@ -527,56 +527,57 @@ archive_read_format_tar_read_data(struct archive_read *a,
tar = (struct tar *)(a->format->data);
-skip_hole:
- /* Remove exhausted entries from sparse list. */
- while (tar->sparse_list != NULL &&
- tar->sparse_list->remaining == 0) {
- p = tar->sparse_list;
- tar->sparse_list = p->next;
- free(p);
- }
+ for (;;) {
+ /* Remove exhausted entries from sparse list. */
+ while (tar->sparse_list != NULL &&
+ tar->sparse_list->remaining == 0) {
+ p = tar->sparse_list;
+ tar->sparse_list = p->next;
+ free(p);
+ }
- if (tar->entry_bytes_unconsumed) {
- __archive_read_consume(a, tar->entry_bytes_unconsumed);
- tar->entry_bytes_unconsumed = 0;
- }
+ if (tar->entry_bytes_unconsumed) {
+ __archive_read_consume(a, tar->entry_bytes_unconsumed);
+ tar->entry_bytes_unconsumed = 0;
+ }
- /* If we're at end of file, return EOF. */
- if (tar->sparse_list == NULL || tar->entry_bytes_remaining == 0) {
- if (__archive_read_consume(a, tar->entry_padding) < 0)
- return (ARCHIVE_FATAL);
- tar->entry_padding = 0;
- *buff = NULL;
- *size = 0;
- *offset = tar->realsize;
- return (ARCHIVE_EOF);
- }
+ /* If we're at end of file, return EOF. */
+ if (tar->sparse_list == NULL ||
+ tar->entry_bytes_remaining == 0) {
+ if (__archive_read_consume(a, tar->entry_padding) < 0)
+ return (ARCHIVE_FATAL);
+ tar->entry_padding = 0;
+ *buff = NULL;
+ *size = 0;
+ *offset = tar->realsize;
+ return (ARCHIVE_EOF);
+ }
- *buff = __archive_read_ahead(a, 1, &bytes_read);
- if (bytes_read < 0)
- return (ARCHIVE_FATAL);
- if (*buff == NULL) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Truncated tar archive");
- return (ARCHIVE_FATAL);
+ *buff = __archive_read_ahead(a, 1, &bytes_read);
+ if (bytes_read < 0)
+ return (ARCHIVE_FATAL);
+ if (*buff == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Truncated tar archive");
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_read > tar->entry_bytes_remaining)
+ bytes_read = (ssize_t)tar->entry_bytes_remaining;
+ /* Don't read more than is available in the
+ * current sparse block. */
+ if (tar->sparse_list->remaining < bytes_read)
+ bytes_read = (ssize_t)tar->sparse_list->remaining;
+ *size = bytes_read;
+ *offset = tar->sparse_list->offset;
+ tar->sparse_list->remaining -= bytes_read;
+ tar->sparse_list->offset += bytes_read;
+ tar->entry_bytes_remaining -= bytes_read;
+ tar->entry_bytes_unconsumed = bytes_read;
+
+ if (!tar->sparse_list->hole)
+ return (ARCHIVE_OK);
+ /* Current is hole data and skip this. */
}
- if (bytes_read > tar->entry_bytes_remaining)
- bytes_read = tar->entry_bytes_remaining;
- /* Don't read more than is available in the
- * current sparse block. */
- if (tar->sparse_list->remaining < bytes_read)
- bytes_read = tar->sparse_list->remaining;
- *size = bytes_read;
- *offset = tar->sparse_list->offset;
- tar->sparse_list->remaining -= bytes_read;
- tar->sparse_list->offset += bytes_read;
- tar->entry_bytes_remaining -= bytes_read;
- tar->entry_bytes_unconsumed = bytes_read;
-
- if (tar->sparse_list->hole)
- goto skip_hole;
-
- return (ARCHIVE_OK);
}
static int
@@ -786,7 +787,7 @@ checksum(struct archive_read *a, const void *h)
* Test the checksum. Note that POSIX specifies _unsigned_
* bytes for this calculation.
*/
- sum = tar_atol(header->checksum, sizeof(header->checksum));
+ sum = (int)tar_atol(header->checksum, sizeof(header->checksum));
check = 0;
for (i = 0; i < 148; i++)
check += (unsigned char)bytes[i];
@@ -847,7 +848,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
* more to make sure that we don't overrun acl_text later.
*/
header = (const struct archive_entry_header_ustar *)h;
- size = tar_atol(header->size, sizeof(header->size));
+ size = (size_t)tar_atol(header->size, sizeof(header->size));
err = read_body_to_string(a, tar, &(tar->acl_text), h, unconsumed);
if (err != ARCHIVE_OK)
return (err);
@@ -1021,7 +1022,7 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
}
/* Fail if we can't make our buffer big enough. */
- if (archive_string_ensure(as, size+1) == NULL) {
+ if (archive_string_ensure(as, (size_t)size+1) == NULL) {
archive_set_error(&a->archive, ENOMEM,
"No memory");
return (ARCHIVE_FATAL);
@@ -1030,15 +1031,15 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
tar_flush_unconsumed(a, unconsumed);
/* Read the body into the string. */
- *unconsumed = (size + 511) & ~ 511;
+ *unconsumed = (size_t)((size + 511) & ~ 511);
src = __archive_read_ahead(a, *unconsumed, NULL);
if (src == NULL) {
*unconsumed = 0;
return (ARCHIVE_FATAL);
}
- memcpy(as->s, src, size);
+ memcpy(as->s, src, (size_t)size);
as->s[size] = '\0';
- as->length = size;
+ as->length = (size_t)size;
return (ARCHIVE_OK);
}
@@ -1068,7 +1069,8 @@ header_common(struct archive_read *a, struct tar *tar,
archive_string_empty(&(tar->entry_linkpath));
/* Parse out the numeric fields (all are octal) */
- archive_entry_set_mode(entry, tar_atol(header->mode, sizeof(header->mode)));
+ archive_entry_set_mode(entry,
+ (mode_t)tar_atol(header->mode, sizeof(header->mode)));
archive_entry_set_uid(entry, tar_atol(header->uid, sizeof(header->uid)));
archive_entry_set_gid(entry, tar_atol(header->gid, sizeof(header->gid)));
tar->entry_bytes_remaining = tar_atol(header->size, sizeof(header->size));
@@ -1310,13 +1312,13 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
* Q: Is the above idea really possible? Even
* when there are GNU or pax extension entries?
*/
- data = __archive_read_ahead(a, size, NULL);
+ data = __archive_read_ahead(a, (size_t)size, NULL);
if (data == NULL) {
*unconsumed = 0;
return (ARCHIVE_FATAL);
}
- archive_entry_copy_mac_metadata(entry, data, size);
- *unconsumed = (size + 511) & ~ 511;
+ archive_entry_copy_mac_metadata(entry, data, (size_t)size);
+ *unconsumed = (size_t)((size + 511) & ~ 511);
tar_flush_unconsumed(a, unconsumed);
return (tar_read_header(a, tar, entry, unconsumed));
}
@@ -1424,9 +1426,9 @@ header_ustar(struct archive_read *a, struct tar *tar,
/* Parse out device numbers only for char and block specials. */
if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
- archive_entry_set_rdevmajor(entry,
+ archive_entry_set_rdevmajor(entry, (dev_t)
tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
- archive_entry_set_rdevminor(entry,
+ archive_entry_set_rdevminor(entry, (dev_t)
tar_atol(header->rdevminor, sizeof(header->rdevminor)));
}
@@ -1663,6 +1665,9 @@ pax_attribute(struct archive_read *a, struct tar *tar,
long n;
int err = ARCHIVE_OK, r;
+ if (value == NULL)
+ value = ""; /* Disable compiler warning; do not pass
+ * NULL pointer to strlen(). */
switch (key[0]) {
case 'G':
/* GNU "0.0" sparse pax format. */
@@ -1709,11 +1714,11 @@ pax_attribute(struct archive_read *a, struct tar *tar,
/* GNU "1.0" sparse pax format */
if (strcmp(key, "GNU.sparse.major") == 0) {
- tar->sparse_gnu_major = tar_atol10(value, strlen(value));
+ tar->sparse_gnu_major = (int)tar_atol10(value, strlen(value));
tar->sparse_gnu_pending = 1;
}
if (strcmp(key, "GNU.sparse.minor") == 0) {
- tar->sparse_gnu_minor = tar_atol10(value, strlen(value));
+ tar->sparse_gnu_minor = (int)tar_atol10(value, strlen(value));
tar->sparse_gnu_pending = 1;
}
if (strcmp(key, "GNU.sparse.name") == 0) {
@@ -1796,20 +1801,20 @@ pax_attribute(struct archive_read *a, struct tar *tar,
}
} else if (strcmp(key, "SCHILY.devmajor") == 0) {
archive_entry_set_rdevmajor(entry,
- tar_atol10(value, strlen(value)));
+ (dev_t)tar_atol10(value, strlen(value)));
} else if (strcmp(key, "SCHILY.devminor") == 0) {
archive_entry_set_rdevminor(entry,
- tar_atol10(value, strlen(value)));
+ (dev_t)tar_atol10(value, strlen(value)));
} else if (strcmp(key, "SCHILY.fflags") == 0) {
archive_entry_copy_fflags_text(entry, value);
} else if (strcmp(key, "SCHILY.dev") == 0) {
archive_entry_set_dev(entry,
- tar_atol10(value, strlen(value)));
+ (dev_t)tar_atol10(value, strlen(value)));
} else if (strcmp(key, "SCHILY.ino") == 0) {
archive_entry_set_ino(entry,
tar_atol10(value, strlen(value)));
} else if (strcmp(key, "SCHILY.nlink") == 0) {
- archive_entry_set_nlink(entry,
+ archive_entry_set_nlink(entry, (unsigned)
tar_atol10(value, strlen(value)));
} else if (strcmp(key, "SCHILY.realsize") == 0) {
tar->realsize = tar_atol10(value, strlen(value));
@@ -2018,9 +2023,9 @@ header_gnutar(struct archive_read *a, struct tar *tar,
/* Parse out device numbers only for char and block specials */
if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
- archive_entry_set_rdevmajor(entry,
+ archive_entry_set_rdevmajor(entry, (dev_t)
tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
- archive_entry_set_rdevminor(entry,
+ archive_entry_set_rdevminor(entry, (dev_t)
tar_atol(header->rdevminor, sizeof(header->rdevminor)));
} else
archive_entry_set_rdev(entry, 0);
@@ -2255,7 +2260,8 @@ gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
* don't require this, but they should.
*/
do {
- bytes_read = readline(a, tar, &p, tar_min(*remaining, 100), unconsumed);
+ bytes_read = readline(a, tar, &p,
+ (ssize_t)tar_min(*remaining, 100), unconsumed);
if (bytes_read <= 0)
return (ARCHIVE_FATAL);
*remaining -= bytes_read;
@@ -2296,7 +2302,7 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar, size_t *unconsumed)
remaining = tar->entry_bytes_remaining;
/* Parse entries. */
- entries = gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
+ entries = (int)gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
if (entries < 0)
return (ARCHIVE_FATAL);
/* Parse the individual entries. */
@@ -2314,11 +2320,11 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar, size_t *unconsumed)
}
/* Skip rest of block... */
tar_flush_unconsumed(a, unconsumed);
- bytes_read = tar->entry_bytes_remaining - remaining;
+ bytes_read = (ssize_t)(tar->entry_bytes_remaining - remaining);
to_skip = 0x1ff & -bytes_read;
if (to_skip != __archive_read_consume(a, to_skip))
return (ARCHIVE_FATAL);
- return (bytes_read + to_skip);
+ return ((ssize_t)(bytes_read + to_skip));
}
/*