summaryrefslogtreecommitdiff
path: root/lib/tar
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-07-24 13:36:50 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-07-24 18:10:34 +0200
commit4fdfd1f62a9d50298b0bb71e8bea04174af4a3ab (patch)
treed511b488ce77ef2b0b84b26ead69a1d01375491c /lib/tar
parent30fbd496a1793b4374873144432f9b7a996a689d (diff)
Fix processing of tar mtime on 32 bit systems
struct stat uses time_t to store time values. On some 32 bit systems, this may be a 32 bit integer. This patch adds a broken-out 64 bit time value to tar_header_decoded_t and makes sure to clamp the value to +/- (2^32 - 1) if required when writing it back to a struct stat. Reported-by: Matt Turner <mattst88@gmail.com> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/tar')
-rw-r--r--lib/tar/read_header.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/lib/tar/read_header.c b/lib/tar/read_header.c
index 043b5ff..a083c2f 100644
--- a/lib/tar/read_header.c
+++ b/lib/tar/read_header.c
@@ -129,11 +129,11 @@ static int read_pax_header(int fd, uint64_t entsize, unsigned int *set_by_pax,
if (line[6] == '-') {
if (pax_read_decimal(line + 7, &field))
goto fail;
- out->sb.st_mtime = -((int64_t)field);
+ out->mtime = -((int64_t)field);
} else {
if (pax_read_decimal(line + 6, &field))
goto fail;
- out->sb.st_mtime = field;
+ out->mtime = field;
}
*set_by_pax |= PAX_MTIME;
} else if (!strncmp(line, "GNU.sparse.name=", 16)) {
@@ -284,9 +284,9 @@ static int decode_header(const tar_header_t *hdr, unsigned int set_by_pax,
return -1;
if (field & 0x8000000000000000UL) {
field = ~field + 1;
- out->sb.st_mtime = -((int64_t)field);
+ out->mtime = -((int64_t)field);
} else {
- out->sb.st_mtime = field;
+ out->mtime = field;
}
}
@@ -338,6 +338,17 @@ static int decode_header(const tar_header_t *hdr, unsigned int set_by_pax,
break;
}
+#if SIZEOF_TIME_T < 8
+ if (out->mtime > (int64_t)INT32_MAX) {
+ out->sb.st_mtime = INT32_MAX;
+ } else if (out->mtime < (int64_t)INT32_MIN) {
+ out->sb.st_mtime = INT32_MIN;
+ } else {
+ out->sb.st_mtime = out->mtime;
+ }
+#else
+ out->sb.st_mtime = out->mtime;
+#endif
return 0;
}