22
33import { spawnSync } from "node:child_process" ;
44import {
5+ closeSync ,
56 existsSync ,
67 lstatSync ,
78 mkdtempSync ,
9+ openSync ,
810 readdirSync ,
911 readFileSync ,
12+ readSync ,
1013 rmSync ,
1114 statSync ,
1215 writeFileSync ,
@@ -19,14 +22,14 @@ import {
1922 collectArchitectureErrors ,
2023 collectCodeSigningMetadataErrors ,
2124 collectEntitlementErrors ,
25+ hasMachOMagic ,
2226} from "./macos-distribution-policy.mjs" ;
2327
2428const projectRoot = process . cwd ( ) ;
2529const packageJson = JSON . parse ( readFileSync ( path . join ( projectRoot , "package.json" ) , "utf8" ) ) ;
2630const productName = packageJson . productName ?? packageJson . name ?? "Recordly" ;
2731const expectedBundleId = "dev.recordly.app" ;
2832const commandTimeoutMs = 5 * 60 * 1000 ;
29- const fileClassificationBatchSize = 100 ;
3033const maxReportDetailLength = 4_000 ;
3134
3235function parseArguments ( argv ) {
@@ -174,6 +177,17 @@ function walkRegularFiles(rootPath) {
174177 return files ;
175178}
176179
180+ function isMachOBinary ( filePath ) {
181+ const header = new Uint8Array ( 4 ) ;
182+ const descriptor = openSync ( filePath , "r" ) ;
183+ try {
184+ const bytesRead = readSync ( descriptor , header , 0 , header . byteLength , 0 ) ;
185+ return bytesRead === header . byteLength && hasMachOMagic ( header ) ;
186+ } finally {
187+ closeSync ( descriptor ) ;
188+ }
189+ }
190+
177191function extractPlist ( commandResult ) {
178192 const output = [ commandResult . stdout , commandResult . stderr ] . filter ( Boolean ) . join ( "\n" ) ;
179193 const xmlStart = output . indexOf ( "<?xml" ) ;
@@ -281,23 +295,7 @@ function verifyEntitlements(appPath, label, tempRoot, check) {
281295
282296function verifyMachOBinaries ( appPath , arch , check ) {
283297 check ( "packaged app: nested Mach-O signatures and architectures" , ( ) => {
284- const machOBinaries = [ ] ;
285- const regularFiles = walkRegularFiles ( appPath ) ;
286- for ( let index = 0 ; index < regularFiles . length ; index += fileClassificationBatchSize ) {
287- const batch = regularFiles . slice ( index , index + fileClassificationBatchSize ) ;
288- const fileTypes = runProcess ( "file" , [ "-b" , ...batch ] ) . stdout . split ( / \r ? \n / ) ;
289- if ( fileTypes . length !== batch . length ) {
290- throw new Error (
291- `file classification returned ${ fileTypes . length } rows for ${ batch . length } paths` ,
292- ) ;
293- }
294-
295- for ( let batchIndex = 0 ; batchIndex < batch . length ; batchIndex += 1 ) {
296- if ( fileTypes [ batchIndex ] . includes ( "Mach-O" ) ) {
297- machOBinaries . push ( batch [ batchIndex ] ) ;
298- }
299- }
300- }
298+ const machOBinaries = walkRegularFiles ( appPath ) . filter ( isMachOBinary ) ;
301299
302300 if ( machOBinaries . length === 0 ) {
303301 throw new Error ( "no Mach-O binaries were found in the app bundle" ) ;
0 commit comments