diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-07-24 13:36:50 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-07-24 18:10:34 +0200 |
commit | 4fdfd1f62a9d50298b0bb71e8bea04174af4a3ab (patch) | |
tree | d511b488ce77ef2b0b84b26ead69a1d01375491c /lib/tar | |
parent | 30fbd496a1793b4374873144432f9b7a996a689d (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.c | 19 |
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; } |