From bff6a3e4d440eaf3e48530b29548c8975b319c21 Mon Sep 17 00:00:00 2001 From: Chuy Zarate Date: Wed, 25 Mar 2026 17:42:04 -0600 Subject: [PATCH 1/4] Add catalog signing for .js files for VS signing compliance The .js files in the Emscripten SDK are customer-modifiable toolchain files that cannot be directly Authenticode-signed (modifying a signed file breaks the signature). Instead, generate a .cat catalog file covering all .js files, which is signed with MicrosoftDotNet500 via the existing FileExtensionSignInfo entry for .cat files. The GenerateCatalogFiles target runs after ReallyBuild on Windows only (makecat.exe is a Windows SDK tool). It invokes eng/generate-catalog.ps1 which enumerates all .js files, generates a CDF, runs makecat.exe, and produces emscripten-js.cat in the SDK package directory so it ships alongside the files it covers. This fixes ~14,468 unsigned .js files flagged by VS signing compliance scans. --- eng/Signing.props | 5 ++- eng/emsdk.proj | 17 ++++++++ eng/generate-catalog.ps1 | 91 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 eng/generate-catalog.ps1 diff --git a/eng/Signing.props b/eng/Signing.props index afc88110f7..3d376905eb 100644 --- a/eng/Signing.props +++ b/eng/Signing.props @@ -8,7 +8,10 @@ - + + + + <_CatOutputPath>$(ArtifactsObjDir)upstream\emscripten\emscripten-js.cat + + + + + + + diff --git a/eng/generate-catalog.ps1 b/eng/generate-catalog.ps1 new file mode 100644 index 0000000000..3e94f1e006 --- /dev/null +++ b/eng/generate-catalog.ps1 @@ -0,0 +1,91 @@ +<# +.SYNOPSIS + Generates a catalog definition file (.cdf) and catalog file (.cat) for all .js files + in the specified root directory. Used for VS signing compliance - the .js files are + customer-modifiable and cannot be directly Authenticode-signed. + +.PARAMETER RootPath + Root directory to search for .js files recursively. + +.PARAMETER CatOutputPath + Full path for the output .cat file. +#> +param( + [Parameter(Mandatory)][string]$RootPath, + [Parameter(Mandatory)][string]$CatOutputPath, + [string]$WindowsSdkDir = '' +) + +$ErrorActionPreference = 'Stop' + +$cdfPath = [System.IO.Path]::ChangeExtension($CatOutputPath, '.cdf') + +$files = Get-ChildItem -Path $RootPath -Recurse -Filter '*.js' -File +if ($files.Count -eq 0) { + Write-Warning "No .js files found under $RootPath - skipping catalog generation." + exit 0 +} + +$cdf = @() +$cdf += '[CatalogHeader]' +$cdf += "Name=$CatOutputPath" +$cdf += 'CatalogVersion=2' +$cdf += 'HashAlgorithms=SHA256' +$cdf += '' +$cdf += '[CatalogFiles]' + +$i = 0 +foreach ($f in $files) { + $label = "js_${i}_" + ($f.Name -replace '[^\w\.-]', '_') + $cdf += "$label=$($f.FullName)" + $i++ +} + +$cdf | Set-Content -Path $cdfPath -Encoding ASCII +Write-Host "Generated CDF with $($files.Count) .js files at $cdfPath" + +$catDir = [System.IO.Path]::GetDirectoryName($CatOutputPath) +if (-not (Test-Path $catDir)) { + New-Item -ItemType Directory -Path $catDir -Force | Out-Null +} + +# Find makecat.exe - it ships with the Windows SDK and may not be on PATH. +# Prefer WindowsSdkDir if passed from MSBuild (not available in this repo's build +# context since it uses Microsoft.Build.Traversal, but may be set in other builds). +$makecat = $null +if ($WindowsSdkDir -and (Test-Path $WindowsSdkDir)) { + $makecat = Get-ChildItem -Path (Join-Path $WindowsSdkDir 'bin') -Recurse -Filter 'makecat.exe' -File | + Where-Object { $_.DirectoryName -match 'x64' } | + Sort-Object DirectoryName -Descending | + Select-Object -First 1 +} + +if (-not $makecat) { + $makecat = Get-Command makecat.exe -ErrorAction SilentlyContinue +} + +if (-not $makecat) { + # Fallback: search common Windows SDK locations + $sdkRoot = "${env:ProgramFiles(x86)}\Windows Kits\10\bin" + if (Test-Path $sdkRoot) { + $makecat = Get-ChildItem -Path $sdkRoot -Recurse -Filter 'makecat.exe' -File | + Where-Object { $_.DirectoryName -match 'x64' } | + Sort-Object DirectoryName -Descending | + Select-Object -First 1 + } +} + +if (-not $makecat) { + Write-Warning "makecat.exe not found - skipping catalog generation. Catalog signing requires the Windows SDK." + exit 0 +} + +$makecatPath = if ($makecat -is [System.Management.Automation.CommandInfo]) { $makecat.Source } else { $makecat.FullName } +Write-Host "Using makecat.exe at: $makecatPath" + +& $makecatPath $cdfPath +if ($LASTEXITCODE -ne 0) { + throw "makecat.exe failed with exit code $LASTEXITCODE" +} + +Write-Host "Generated catalog file: $CatOutputPath" From 106fed2714474d6ef97cb6d30565a164ceb9f018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 31 Mar 2026 10:01:02 +0200 Subject: [PATCH 2/4] Error when makecat.exe is not found in CI/official builds Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- eng/emsdk.proj | 3 ++- eng/generate-catalog.ps1 | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/eng/emsdk.proj b/eng/emsdk.proj index 7013d8351c..3c28c67abb 100644 --- a/eng/emsdk.proj +++ b/eng/emsdk.proj @@ -375,9 +375,10 @@ <_CatOutputPath>$(ArtifactsObjDir)upstream\emscripten\emscripten-js.cat + <_ErrorIfMakecatNotFound Condition="'$(ContinuousIntegrationBuild)' == 'true' or '$(OfficialBuild)' == 'true'">true - + diff --git a/eng/generate-catalog.ps1 b/eng/generate-catalog.ps1 index 3e94f1e006..91657838a3 100644 --- a/eng/generate-catalog.ps1 +++ b/eng/generate-catalog.ps1 @@ -13,7 +13,8 @@ param( [Parameter(Mandatory)][string]$RootPath, [Parameter(Mandatory)][string]$CatOutputPath, - [string]$WindowsSdkDir = '' + [string]$WindowsSdkDir = '', + [bool]$ErrorIfMakecatNotFound = $false ) $ErrorActionPreference = 'Stop' @@ -76,6 +77,9 @@ if (-not $makecat) { } if (-not $makecat) { + if ($ErrorIfMakecatNotFound) { + throw "makecat.exe not found. Catalog signing requires the Windows SDK which must be available in CI builds." + } Write-Warning "makecat.exe not found - skipping catalog generation. Catalog signing requires the Windows SDK." exit 0 } From 44b61d3ab2450c81eab0c6a1df1a93c0af01301d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 31 Mar 2026 10:03:53 +0200 Subject: [PATCH 3/4] Only log catalog message when file was actually produced Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- eng/emsdk.proj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/emsdk.proj b/eng/emsdk.proj index 3c28c67abb..c0c158f963 100644 --- a/eng/emsdk.proj +++ b/eng/emsdk.proj @@ -380,7 +380,7 @@ - + From 32b8b3b0ae4cd86e83b6acd291b0afa3afded8b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 31 Mar 2026 12:08:56 +0200 Subject: [PATCH 4/4] Use switch parameter for ErrorIfMakecatNotFound, pass conditionally Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- eng/emsdk.proj | 4 ++-- eng/generate-catalog.ps1 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/emsdk.proj b/eng/emsdk.proj index c0c158f963..eabfe550ed 100644 --- a/eng/emsdk.proj +++ b/eng/emsdk.proj @@ -375,10 +375,10 @@ <_CatOutputPath>$(ArtifactsObjDir)upstream\emscripten\emscripten-js.cat - <_ErrorIfMakecatNotFound Condition="'$(ContinuousIntegrationBuild)' == 'true' or '$(OfficialBuild)' == 'true'">true + <_ErrorIfMakecatNotFound Condition="'$(ContinuousIntegrationBuild)' == 'true' or '$(OfficialBuild)' == 'true'">-ErrorIfMakecatNotFound - + diff --git a/eng/generate-catalog.ps1 b/eng/generate-catalog.ps1 index 91657838a3..6afcda3c0e 100644 --- a/eng/generate-catalog.ps1 +++ b/eng/generate-catalog.ps1 @@ -14,7 +14,7 @@ param( [Parameter(Mandatory)][string]$RootPath, [Parameter(Mandatory)][string]$CatOutputPath, [string]$WindowsSdkDir = '', - [bool]$ErrorIfMakecatNotFound = $false + [switch]$ErrorIfMakecatNotFound ) $ErrorActionPreference = 'Stop'