diff options
-rw-r--r-- | include/tar.h | 3 | ||||
-rw-r--r-- | lib/tar/read_header.c | 23 | ||||
-rw-r--r-- | tar/tar2sqfs.c | 4 | ||||
-rw-r--r-- | tests/tar_sparse_gnu.c | 6 |
4 files changed, 19 insertions, 17 deletions
diff --git a/include/tar.h b/include/tar.h index 1f8ca7e..513e5bc 100644 --- a/include/tar.h +++ b/include/tar.h @@ -68,7 +68,8 @@ typedef struct { char *name; char *link_target; sparse_map_t *sparse; - uint64_t sparse_size; + uint64_t actual_size; + uint64_t record_size; bool unknown_record; } tar_header_decoded_t; diff --git a/lib/tar/read_header.c b/lib/tar/read_header.c index 74666b3..21642d9 100644 --- a/lib/tar/read_header.c +++ b/lib/tar/read_header.c @@ -206,8 +206,7 @@ static int read_pax_header(int fd, uint64_t entsize, unsigned int *set_by_pax, goto fail_errno; *set_by_pax |= PAX_NAME; } else if (!strncmp(line, "size=", 5)) { - pax_read_decimal(line + 5, &field); - out->sb.st_size = field; + pax_read_decimal(line + 5, &out->record_size); *set_by_pax |= PAX_SIZE; } else if (!strncmp(line, "linkpath=", 9)) { free(out->link_target); @@ -287,9 +286,8 @@ static int decode_header(const tar_header_t *hdr, unsigned int set_by_pax, } if (!(set_by_pax & PAX_SIZE)) { - if (read_number(hdr->size, sizeof(hdr->size), &field)) + if (read_number(hdr->size, sizeof(hdr->size), &out->record_size)) return -1; - out->sb.st_size = field; } if (!(set_by_pax & PAX_UID)) { @@ -617,6 +615,10 @@ int read_header(int fd, tar_header_decoded_t *out) out->sparse = read_gnu_old_sparse(fd, &hdr); if (out->sparse == NULL) goto fail; + if (read_number(hdr.tail.gnu.realsize, + sizeof(hdr.tail.gnu.realsize), + &out->actual_size)) + goto fail; break; } break; @@ -625,15 +627,12 @@ int read_header(int fd, tar_header_decoded_t *out) if (decode_header(&hdr, set_by_pax, out, version)) goto fail; - if (hdr.typeflag == TAR_TYPE_GNU_SPARSE) { - if (read_number(hdr.tail.gnu.realsize, - sizeof(hdr.tail.gnu.realsize), &pax_size)) - goto fail; - - out->sparse_size = out->sb.st_size; - out->sb.st_size = pax_size; + if (out->sparse != NULL) { + out->sb.st_size = out->actual_size; + } else { + out->sb.st_size = out->record_size; + out->actual_size = out->record_size; } - return 0; out_eof: clear_header(out); diff --git a/tar/tar2sqfs.c b/tar/tar2sqfs.c index bce6a4d..dec717b 100644 --- a/tar/tar2sqfs.c +++ b/tar/tar2sqfs.c @@ -176,7 +176,7 @@ static int write_file(tar_header_decoded_t *hdr, file_info_t *fi, if (ret) return -1; - return skip_padding(STDIN_FILENO, hdr->sparse_size); + return skip_padding(STDIN_FILENO, hdr->record_size); } if (write_data_from_fd(data, fi, STDIN_FILENO)) @@ -242,7 +242,7 @@ static int process_tar_ball(fstree_t *fs, data_writer_t *data) count += m->count; } - if (count != hdr.sparse_size) + if (count != hdr.record_size) skip = true; if (skip) { diff --git a/tests/tar_sparse_gnu.c b/tests/tar_sparse_gnu.c index d4d65d3..4c3ee31 100644 --- a/tests/tar_sparse_gnu.c +++ b/tests/tar_sparse_gnu.c @@ -40,7 +40,8 @@ int main(void) assert(hdr.sb.st_uid == 01750); assert(hdr.sb.st_gid == 01750); assert(hdr.sb.st_size == 524288); - assert(hdr.sparse_size == 8192); + assert(hdr.actual_size == 524288); + assert(hdr.record_size == 8192); assert(strcmp(hdr.name, "input.bin") == 0); assert(!hdr.unknown_record); @@ -70,7 +71,8 @@ int main(void) assert(hdr.sb.st_uid == 01750); assert(hdr.sb.st_gid == 01750); assert(hdr.sb.st_size == 2097152); - assert(hdr.sparse_size == 32768); + assert(hdr.actual_size == 2097152); + assert(hdr.record_size == 32768); assert(strcmp(hdr.name, "input.bin") == 0); assert(!hdr.unknown_record); |