Description
Hey everyone, i've noticed that using the ArchiveIterator
API on windows uses the incorrect stat
struct and contains corrupted data.
In particular, the crate uses libc::stat
to map the return value of the libarchive function archive_entry_stat
.
However looking into the definition for that struct on windows reveals that is in fact not the same as the struct used in libarchive which causes the data returned from archive_entry_stat
to be mapped incorrectly:
libarchive uses sys/stat.h
on windows which is defined as following:
struct stat
{
_dev_t st_dev;
_ino_t st_ino;
unsigned short st_mode;
short st_nlink;
short st_uid;
short st_gid;
_dev_t st_rdev;
_off_t st_size;
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
};
The rust crate libc::stat struct on windows however looks like this:
// note this is the struct called stat64 in Windows. Not stat, nor stati64.
pub struct stat {
pub st_dev: dev_t,
pub st_ino: ino_t,
pub st_mode: u16,
pub st_nlink: c_short,
pub st_uid: c_short,
pub st_gid: c_short,
pub st_rdev: dev_t,
pub st_size: i64,
pub st_atime: time64_t,
pub st_mtime: time64_t,
pub st_ctime: time64_t,
}
The comment explains why these structs are not the same. I'm not sure why this is the case, but it leads to incorrect data being filled into st_size
, st_atime
, st_mtime
and st_ctime
due to the difference in type size.
I was unable to find the correct struct in the rust libc
library.
I've therefore implemented the correct struct definition in this crate and changed the source files to use this struct when the target os is windows.
I also had to modify the generate-ffi
script to include the correct type when generating the binding and to work with the newest bindgen version.
Pull request will follow soon. Feel free to modify it to fit the code structure or improve it with an existing correct struct definition.