ZIPFoundation icon indicating copy to clipboard operation
ZIPFoundation copied to clipboard

I got a crash when try setAttributes to S_IFLNK

Open rongcondihoc opened this issue 7 years ago • 1 comments

Summary

I have framework folder Foo.framework

  • foo // this is a link file to Versions/A/foo
  • Versions
    • A
      • foo // this is a binary file

I got crash when unzip this framework. The crash is: Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=4 "The file “foo” doesn’t exist." UserInfo={NSFilePath=/MyPath/foo, NSUnderlyingError=0x10300f060 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}

I have checked if library doesn't setAttributes (Archive.extract method) library works fine. Maybe link file doesn't allow for setAttributes.

Could you check it.

Steps to Reproduce

Expected Results

Actual Results

Regression & Version

Related Link

rongcondihoc avatar Apr 26 '18 02:04 rongcondihoc

Thank you for your bug report.

I was able to reproduce the behaviour by extracting a zipped macOS framework bundle.
The underlying problem is twofold:

  • .framework bundles internally use multilevel symlinks (e.g a symlink "FrameworkName" that points to "Versions/Current/FrameworkName" whereas "Current" also is a symlink)
  • FileManager.setAttributes: does not set the attributes of the symlink, but instead resolves the symlink and applies the attributes to the resolved target.

ZIP Foundation does sort entries so that files and directories are created before symlinks. The sort was implemented to guarantee that files and directories already exist when a symlink to a file/directory is restored from an archive. But the sorting does currently not take symlinks into account that point to another symlink. So when setAttributes: tries to resolve the chain of links, it might fail (like in your case) because the 2nd level symlink hasn't been restored from the archive yet.

The best fix for this would be to introduce special handling for symlink file attributes where a lutimes call is used instead of the high level FileManager.setAttributes:.
This would fix the wrong behaviour where attributes of the destination files are changed (instead of the symlink's attributes) and also avoid the error because setAttributes: isn't called at all.

I will leave this issue open until I find time to fix this bug. I'd also happily merge a Pull Request 😉.

weichsel avatar Apr 27 '18 09:04 weichsel