diff options
author | Martin Matuska <mm@FreeBSD.org> | 2025-10-16 17:36:33 +0000 |
---|---|---|
committer | Martin Matuska <mm@FreeBSD.org> | 2025-10-16 17:41:19 +0000 |
commit | 8f38cbcd9c4a4f27bdccf2e75a7e20026cff5181 (patch) | |
tree | d6d99051589c097001ba225066098ae579a57bcc /libarchive/archive_read_open_file.c | |
parent | 76141d3306dea42228646b9a4a5e97ccba59fe2a (diff) |
Diffstat (limited to 'libarchive/archive_read_open_file.c')
-rw-r--r-- | libarchive/archive_read_open_file.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/libarchive/archive_read_open_file.c b/libarchive/archive_read_open_file.c index 742923abbee9..6ca2ff191aa8 100644 --- a/libarchive/archive_read_open_file.c +++ b/libarchive/archive_read_open_file.c @@ -48,6 +48,7 @@ #endif #include "archive.h" +#include "archive_platform_stat.h" struct read_FILE_data { FILE *f; @@ -65,7 +66,7 @@ static int64_t FILE_skip(struct archive *, void *, int64_t); int archive_read_open_FILE(struct archive *a, FILE *f) { - struct stat st; + la_seek_stat_t st; struct read_FILE_data *mine; size_t block_size = 128 * 1024; void *b; @@ -88,7 +89,7 @@ archive_read_open_FILE(struct archive *a, FILE *f) * streams that don't support fileno()). As a result, fileno() * should be used cautiously.) */ - if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) { + if (la_seek_fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) { archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino); /* Enable the seek optimization only for regular files. */ mine->can_skip = 1; @@ -205,15 +206,15 @@ FILE_seek(struct archive *a, void *client_data, int64_t request, int whence) int seek_bits = sizeof(seek) * 8 - 1; (void)a; /* UNUSED */ - /* Reduce a request that would overflow the 'seek' variable. */ + /* Do not perform a seek which cannot be fulfilled. */ if (sizeof(request) > sizeof(seek)) { const int64_t max_seek = (((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1; const int64_t min_seek = ~max_seek; - if (request > max_seek) - seek = max_seek; - else if (request < min_seek) - seek = min_seek; + if (request < min_seek || request > max_seek) { + errno = EOVERFLOW; + goto err; + } } #ifdef __ANDROID__ @@ -236,6 +237,7 @@ FILE_seek(struct archive *a, void *client_data, int64_t request, int whence) } #endif /* If we arrive here, the input is corrupted or truncated so fail. */ +err: archive_set_error(a, errno, "Error seeking in FILE* pointer"); return (ARCHIVE_FATAL); } |