Skip to content
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

Can't extract files to tempdir on macOs #34

Closed
biuiko opened this issue Aug 17, 2023 · 3 comments · Fixed by #55
Closed

Can't extract files to tempdir on macOs #34

biuiko opened this issue Aug 17, 2023 · 3 comments · Fixed by #55

Comments

@biuiko
Copy link

biuiko commented Aug 17, 2023

Issue Description

I'm unable to extract files to the temporary directory on macOS.
When I run the code provided below on macOS, I get the result entries [].
However, when I run the same code on Linux, I get the expected result entries [Ok(DirEntry("/tmp/.tmpbaaPum/b")), Ok(DirEntry("/tmp/.tmpbaaPum/a"))].

Environment Information:

unrar = "0.5.1"
tempfile = "3.7.1"
rustc 1.71.0 (8ede3aae2 2023-07-12)

Code

use unrar::Archive;

pub fn main() {
   let args = std::env::args();
   let file = args.skip(1).next().unwrap_or("archive.rar".to_owned());
   let mut archive = Archive::new(&file).open_for_processing().unwrap();
   let temp_path = tempfile::tempdir().unwrap();
   let temp_path = temp_path.path();
   while let Some(header) = archive.read_header().expect("can't read file header") {
       let temp_file_path = temp_path.join(header.entry().filename.as_path());
       archive = header.extract_to(temp_file_path.as_path()).unwrap();
   }
   let entries = std::fs::read_dir(&temp_path).unwrap().collect::<Vec<_>>();
   eprintln!("entries {:?}", entries);
}
@biuiko
Copy link
Author

biuiko commented Aug 17, 2023

I have successfully extracted files to a non-temporary directory.
By running the following code, I achieved the expected output: entries [Ok(DirEntry("./tmp/a")), Ok(DirEntry("./tmp/b"))].

use unrar::Archive;

pub fn main() {
    let args = std::env::args();
    let file = args.skip(1).next().unwrap_or("archive.rar".to_owned());
    let mut archive = Archive::new(&file).open_for_processing().unwrap();
    // let temp_path = tempfile::tempdir().unwrap();
    // let temp_path = temp_path.path();
    let temp_path = std::path::Path::new("./tmp");
    while let Some(header) = archive.read_header().expect("can't read file header") {
        let temp_file_path = temp_path.join(header.entry().filename.as_path());
        archive = header.extract_to(temp_file_path.as_path()).unwrap();
    }
    let entries = std::fs::read_dir(&temp_path).unwrap().collect::<Vec<_>>();
    eprintln!("entries {:?}", entries);
}

I attempted to debug the issue and found that when using tempdir(), the unrar_sys::vendor::unrar::extract.info LinksToDirs function returns false. I suspect that this could be due to the check for deleting symbolic links, which prevents the extraction of files to the specified directory.

@muja
Copy link
Owner

muja commented Sep 15, 2023

This is interesting. I have actually been using (the now unmaintained) tempdir crate to test previous versions of the library and have never run into issues. I thought initially that maybe tempfile was doing something differently. However it turns out the error is reproducible with both tempdir and tempfile which means there has been a regression in one of the RARDLL upgrades.

There are 2 workarounds you can apply:

  1. you can use the extract_with_base method instead of the extract_to. This seems to work fine.
  2. You can std::fs::File::create(temp_file_path) before using extract_to.

I don't know how else to proceed other than to file an issue with the RAR maintainers.

@muja
Copy link
Owner

muja commented Nov 11, 2023

This seems to be fixed in the v7 beta release. I checked it against both the newest v6 version (which is on crates.io right now) and the v7 beta release. The error still persists in v6 but is fixed in v7.

So once the v7 is released for good we can upgrade and it will fix itself. In the meantime you can use the workarounds that I've provided.

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

Successfully merging a pull request may close this issue.

2 participants