diff --git a/apple-codesign/CHANGELOG.md b/apple-codesign/CHANGELOG.md index 153953d2f..236a073f4 100644 --- a/apple-codesign/CHANGELOG.md +++ b/apple-codesign/CHANGELOG.md @@ -62,6 +62,8 @@ Released on ReleaseDate. * Bundle signing logic has been significantly overhauled to hopefully make it conform with Apple tooling's behavior. This likely fixed several bugs with bundle signing. +* Fixed a bundle signing bug where overwriting symlinks would incorrectly + result in an `Error: I/O error: File exists (os error 17)` or similar. * aws crates 0.53 -> 0.57. * bitflags 1.3 -> 2.0. * cryptographic-message-syntax 0.19 -> 0.25. diff --git a/apple-codesign/src/bundle_signing.rs b/apple-codesign/src/bundle_signing.rs index e1020f43b..48170b1cb 100644 --- a/apple-codesign/src/bundle_signing.rs +++ b/apple-codesign/src/bundle_signing.rs @@ -303,6 +303,13 @@ impl<'a, 'key> BundleFileHandler for SingleBundleHandler<'a, 'key> { let dest_path = self.dest_dir.join(dest_rel_path); if source_path != dest_path { + // Remove an existing file before installing the replacement. In + // the case of symlinks this is required due to how symlink creation + // works. + if dest_path.symlink_metadata().is_ok() { + std::fs::remove_file(&dest_path)?; + } + if let Some(parent) = dest_path.parent() { std::fs::create_dir_all(parent)?; } diff --git a/apple-codesign/tests/cmd/sign-bundle-symlink-overwrite.trycmd b/apple-codesign/tests/cmd/sign-bundle-symlink-overwrite.trycmd index 672c567e1..60b7f1137 100644 --- a/apple-codesign/tests/cmd/sign-bundle-symlink-overwrite.trycmd +++ b/apple-codesign/tests/cmd/sign-bundle-symlink-overwrite.trycmd @@ -40,7 +40,6 @@ writing signed main executable to MyApp.app.signed/Contents/MacOS/MyApp $ ln -sf file-01.txt MyApp.app/Contents/Resources/file.txt $ rcodesign sign MyApp.app MyApp.app.signed -? 1 signing MyApp.app to MyApp.app.signed signing bundle at MyApp.app signing 0 nested bundles in the following order: @@ -53,6 +52,15 @@ sealing regular file Resources/file-01.txt copying file MyApp.app/Contents/Resources/file-01.txt -> MyApp.app.signed/Contents/Resources/file-01.txt sealing symlink Resources/file.txt -> file-01.txt replicating symlink MyApp.app.signed/Contents/Resources/file.txt -> file-01.txt -Error: I/O error: File exists (os error 17) +writing sealed resources to MyApp.app.signed/Contents/_CodeSignature/CodeResources +signing main executable Contents/MacOS/MyApp +setting main executable binary identifier to com.example.mybundle (derived from CFBundleIdentifier in Info.plist) +inferring default signing settings from Mach-O binary +signing Mach-O binary at index 0 +binary targets macOS >= 11.0.0 with SDK 11.0.0 +creating ad-hoc signature +code directory version: 132096 +total signature size: 421 bytes +writing signed main executable to MyApp.app.signed/Contents/MacOS/MyApp ```