1- import { Arch , CopyFileTransformer , executeAppBuilder , FileTransformer , InvalidConfigurationError , use , walk } from "builder-util"
1+ import { Arch , CopyFileTransformer , executeAppBuilder , FileTransformer , InvalidConfigurationError , log , use , walk } from "builder-util"
22import { Nullish } from "builder-util-runtime"
33import { createHash } from "crypto"
44import { readdir } from "fs/promises"
@@ -119,7 +119,12 @@ export class WinPackager extends PlatformPackager<WindowsConfiguration> {
119119 return chooseNotNull ( chooseNotNull ( this . platformSpecificBuildOptions . signtoolOptions ?. certificatePassword , process . env . WIN_CSC_KEY_PASSWORD ) , super . doGetCscPassword ( ) )
120120 }
121121
122- async sign ( file : string ) : Promise < boolean > {
122+ async signIf ( file : string ) : Promise < boolean > {
123+ if ( ! this . shouldSignFile ( file , true ) ) {
124+ log . info ( { file : log . filePath ( file ) } , "file signing skipped via signExts configuration" )
125+ return false
126+ }
127+
123128 const signOptions : WindowsSignOptions = {
124129 path : file ,
125130 options : this . platformSpecificBuildOptions ,
@@ -207,17 +212,31 @@ export class WinPackager extends PlatformPackager<WindowsConfiguration> {
207212 await execWine ( path . join ( vendorPath , "rcedit-ia32.exe" ) , path . join ( vendorPath , "rcedit-x64.exe" ) , args )
208213 }
209214
210- await this . sign ( file )
215+ await this . signIf ( file )
211216 timer . end ( )
212217
213218 if ( buildCacheManager != null ) {
214219 await buildCacheManager . save ( )
215220 }
216221 }
217222
218- private shouldSignFile ( file : string ) : boolean {
219- const shouldSignExplicit = ! ! this . platformSpecificBuildOptions . signExts ?. some ( ext => file . endsWith ( ext ) )
220- return shouldSignExplicit || file . endsWith ( ".exe" )
223+ private shouldSignFile ( file : string , fallbackValue = false ) : boolean {
224+ const backwardCompatibility = file . endsWith ( ".exe" )
225+ const signExts = this . platformSpecificBuildOptions . signExts
226+ if ( ! signExts ?. length ) {
227+ return backwardCompatibility || fallbackValue
228+ }
229+ // process patterns ( !exe => exclude .exe, .dll => include .dll )
230+ // we process first to allow literal negatives in case a filename matches "help!.txt" or similar
231+ if ( signExts . some ( ext => file . endsWith ( ext ) ) ) {
232+ return true
233+ }
234+ // process negative patterns
235+ if ( signExts . some ( ext => ext . startsWith ( "!" ) && file . endsWith ( ext . substring ( 1 ) ) ) ) {
236+ return false
237+ }
238+ // if no explicit patterns matched, fall back to backward compatibility
239+ return backwardCompatibility || fallbackValue
221240 }
222241
223242 protected createTransformerForExtraFiles ( packContext : AfterPackContext ) : FileTransformer | null {
@@ -229,7 +248,7 @@ export class WinPackager extends PlatformPackager<WindowsConfiguration> {
229248 if ( this . shouldSignFile ( file ) ) {
230249 const parentDir = path . dirname ( file )
231250 if ( parentDir !== packContext . appOutDir ) {
232- return new CopyFileTransformer ( file => this . sign ( file ) )
251+ return new CopyFileTransformer ( file => this . signIf ( file ) )
233252 }
234253 }
235254 return null
@@ -253,7 +272,7 @@ export class WinPackager extends PlatformPackager<WindowsConfiguration> {
253272 this . platformSpecificBuildOptions . requestedExecutionLevel
254273 )
255274 } else if ( this . shouldSignFile ( file ) ) {
256- await this . sign ( path . join ( packContext . appOutDir , file ) )
275+ await this . signIf ( path . join ( packContext . appOutDir , file ) )
257276 }
258277 }
259278
@@ -267,7 +286,7 @@ export class WinPackager extends PlatformPackager<WindowsConfiguration> {
267286 }
268287 const filesToSign = await Promise . all ( [ filesPromise ( [ "resources" , "app.asar.unpacked" ] ) , filesPromise ( [ "swiftshader" ] ) ] )
269288 for ( const file of filesToSign . flat ( 1 ) ) {
270- await this . sign ( file )
289+ await this . signIf ( file )
271290 }
272291
273292 return true
0 commit comments