Skip to content

Incorrect stat struct used on windows leading to incorrect metadata #138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Darkrael opened this issue Mar 27, 2025 · 1 comment · May be fixed by #139
Open

Incorrect stat struct used on windows leading to incorrect metadata #138

Darkrael opened this issue Mar 27, 2025 · 1 comment · May be fixed by #139

Comments

@Darkrael
Copy link

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.

Darkrael added a commit to Darkrael/compress-tools-rs that referenced this issue Mar 27, 2025
…nsafe extern" blocks instead of "extern" blocks, the MSRV is now 1.82, where support for this was added.
@Darkrael Darkrael linked a pull request Mar 27, 2025 that will close this issue
@Darkrael
Copy link
Author

Created pull request, let me know if anything else is needed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

1 participant