From 91d7e73d26d27d306bd05746c56375fcfa3fd8ab Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Mon, 27 Jul 2026 14:43:58 -0400 Subject: [PATCH] Strip com.apple.FinderInfo xattrs from files in Mac disk images hdiutil makehybrid gives every file on the image non-empty Finder info (it sets an icon location), which appears as a com.apple.FinderInfo extended attribute. codesign --verify --strict rejects FinderInfo as detritus, and it can cause Safari to fail to load the web extension. (Reported by a user with Safari 17.6 on macOS 12. No other reports from the beta, so maybe not universal.) The Safari App Extension apparently wasn't affected, since it shipped with the same attributes for years. Convert the hybrid image to a read-write image, mount it, strip the attributes from its files, and compress from that. The volume header is untouched, so the open-folder flag that makes Finder open the volume window on mount is preserved. Only fresh installs from the DMG were affected. The updater writes fresh files without the attributes, so copies updated in place were clean. (Notably, this is the reverse of the post-update extension breakage for which the standard advice has always been to delete Zotero.app and redownload. Following that advice is exactly what resulted in a broken copy here.) https://forums.zotero.org/discussion/132925/ --- app/mac/pkg-dmg | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/app/mac/pkg-dmg b/app/mac/pkg-dmg index f84ba962ca..6d5581861c 100755 --- a/app/mac/pkg-dmg +++ b/app/mac/pkg-dmg @@ -303,6 +303,7 @@ my(@gCleanup, %gConfig, $gDarwinMajor, $gDryRun, $gVerbosity); 'cmd_chmod' => 'chmod', 'cmd_diskutil' => 'diskutil', 'cmd_du' => 'du', + 'cmd_find' => 'find', 'cmd_hdid' => 'hdid', 'cmd_hdiutil' => 'hdiutil', 'cmd_mkdir' => 'mkdir', @@ -311,6 +312,7 @@ my(@gCleanup, %gConfig, $gDarwinMajor, $gDryRun, $gVerbosity); 'cmd_rm' => 'rm', 'cmd_rsync' => 'rsync', 'cmd_SetFile' => '/Developer/Tools/SetFile', + 'cmd_xattr' => 'xattr', # create_directly indicates whether hdiutil create supports # -srcfolder and -srcdevice. It does on >= 10.3 (Panther). @@ -996,6 +998,65 @@ sub diskImageMaker($$$$$$$$) { cleanupDie('unlink hybridImage failed: '.$!); } } + + # hdiutil makehybrid gives every file on the image non-empty + # Finder info (it sets an icon location), which appears as a + # com.apple.FinderInfo extended attribute that "codesign + # --verify --strict" rejects as detritus and that can cause + # Safari to silently ignore a bundled web extension (observed + # with Safari 17.6 on macOS 12; the exact trigger conditions + # are unknown). Mount a read-write copy of the image and strip + # the attributes before compressing. Note that Finder flags set + # with --attribute are stored in the same Finder info, so if + # --attribute is ever used, the affected files would need to be + # excluded from the strip. + if($uncompressedImage eq $hybridImage) { + my($udrwImage); + $udrwImage = giveExtension($tempDir.'/udrw', '.dmg'); + + if(command($gConfig{'cmd_hdiutil'}, 'convert', '-format', 'UDRW', + '-ov', $hybridImage, '-o', $udrwImage) != 0) { + cleanupDie('hdiutil convert to UDRW failed'); + } + + push(@gCleanup, + sub {commandInternalVerbosity(0, 'unlink', $udrwImage);}); + + $uncompressedImage = $udrwImage; + + # $hybridImage is no longer needed. Remove it and its cleanup + # entry, which is below the entry for $udrwImage. + my(@tempCleanup) = splice(@gCleanup, -2); + push(@gCleanup, $tempCleanup[1]); + + if(commandInternal('unlink', $hybridImage) != 1) { + cleanupDie('unlink hybridImage failed: '.$!); + } + } + + my($rootDevice, $partitionDevice, $partitionMountPoint); + if(!(($rootDevice, $partitionDevice, $partitionMountPoint) = + hdidMountImage($tempMount, $uncompressedImage))) { + cleanupDie('hdid mount failed'); + } + + push(@gCleanup, sub {commandVerbosity(0, + $gConfig{'cmd_diskutil'}, 'eject', $rootDevice);}); + + if(command($gConfig{'cmd_find'}, $partitionMountPoint, + '-mindepth', '1', '-not', '-type', 'l', + '-xattrname', 'com.apple.FinderInfo', + '-exec', $gConfig{'cmd_xattr'}, '-d', 'com.apple.FinderInfo', + '{}', '+') != 0) { + cleanupDie('stripping com.apple.FinderInfo failed'); + } + + # Pop diskutil eject + pop(@gCleanup); + + if(command($gConfig{'cmd_diskutil'}, 'eject', $rootDevice) != 0) { + cleanupDie('diskutil eject failed'); + } } else { # makehybrid is not available, fall back to making a UDRW and