aboutsummaryrefslogtreecommitdiff
path: root/libarchive/archive_read_open_file.c
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2025-10-16 17:36:33 +0000
committerMartin Matuska <mm@FreeBSD.org>2025-10-16 17:41:19 +0000
commit8f38cbcd9c4a4f27bdccf2e75a7e20026cff5181 (patch)
treed6d99051589c097001ba225066098ae579a57bcc /libarchive/archive_read_open_file.c
parent76141d3306dea42228646b9a4a5e97ccba59fe2a (diff)
Diffstat (limited to 'libarchive/archive_read_open_file.c')
-rw-r--r--libarchive/archive_read_open_file.c16
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);
}