summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/tar.h3
-rw-r--r--lib/tar/read_header.c23
-rw-r--r--tar/tar2sqfs.c4
-rw-r--r--tests/tar_sparse_gnu.c6
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);