]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Merge pull request #2688 from stoeckmann/entry_off32
authorTim Kientzle <kientzle@acm.org>
Sat, 28 Jun 2025 21:11:17 +0000 (14:11 -0700)
committerMartin Matuska <martin@matuska.de>
Wed, 10 Sep 2025 08:16:55 +0000 (10:16 +0200)
Ignore sizes which do not fit into off_t

(cherry picked from commit a474bab7e381e4d54dc336b8206060e64b81cffd)

libarchive/archive_entry_stat.c
libarchive/archive_windows.c
libarchive/test/test_entry.c

index c4906838ed0febe3cc87a497ffadafc717765446..345d3d29b2f2ae4665ae574e13671a49ec3bc859 100644 (file)
@@ -38,6 +38,7 @@
 const struct stat *
 archive_entry_stat(struct archive_entry *entry)
 {
+       int64_t size;
        struct stat *st;
        if (entry->stat == NULL) {
                entry->stat = calloc(1, sizeof(*st));
@@ -74,7 +75,10 @@ archive_entry_stat(struct archive_entry *entry)
        st->st_ino = (ino_t)archive_entry_ino64(entry);
        st->st_nlink = archive_entry_nlink(entry);
        st->st_rdev = archive_entry_rdev(entry);
-       st->st_size = (off_t)archive_entry_size(entry);
+       size = archive_entry_size(entry);
+       st->st_size = (off_t)size;
+       if (st->st_size < 0 || (int64_t)st->st_size != size)
+               st->st_size = 0;
        st->st_mode = archive_entry_mode(entry);
 
        /*
index 0ccea0f818b90cd4edd185901131fc74223cad23..19180bba6102ec7249f9e7f35b969fe05b8ad941 100644 (file)
@@ -561,6 +561,8 @@ copy_stat(struct stat *st, struct ustat *us)
        st->st_mode = us->st_mode;
        st->st_nlink = us->st_nlink;
        st->st_size = (off_t)us->st_size;
+       if (st->st_size < 0 || (uint64_t)st->st_size != us->st_size)
+               st->st_size = 0;
        st->st_uid = us->st_uid;
        st->st_dev = us->st_dev;
        st->st_rdev = us->st_rdev;
index 9b21b83ecdfb84a3203304ff65d766b3898ccba8..cff9c5c86efcb67a001724b2372c0c6c05447474 100644 (file)
@@ -880,6 +880,17 @@ DEFINE_TEST(test_entry)
        if (pst == NULL)
                return;
        assertEqualInt(pst->st_uid, 22);
+
+       /* Check behavior with large sizes. */
+       archive_entry_set_size(e, INT64_MAX - 1);
+       assert((pst = archive_entry_stat(e)) != NULL);
+       if (pst == NULL)
+               return;
+       if (sizeof(pst->st_size) < sizeof(int64_t))
+               assertEqualInt(pst->st_size, 0);
+       else
+               assertEqualInt(pst->st_size, INT64_MAX - 1);
+
        /* We don't need to check high-res fields here. */
 
        /*