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));
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);
/*
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;
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. */
/*