sign icon indicating copy to clipboard operation
sign copied to clipboard

Multiple ClickOnce versions fail to be signed

Open MH-ZShearer opened this issue 1 year ago • 2 comments

Describe the bug

When using a git repository to host a ClickOnce project, additional previous versions may exist. This means each version will contain a manifest file so when the sign tool iterates through the ClickOnceSigner looking for a SingleOrDefault manifest to sign, it may find more than one, resulting in the below stack trace.

Repro steps

  1. Publish ClickOnce output
  2. Bump version
  3. Publish ClickOnce output to same directory
  4. Run sign tool on manifest .application file
  5. ~~Profit~~ Encounter exception

Expected behavior

I believe two different behaviors are acceptable here per manifest file:

  1. Iterate across all files, signing as usual.
  2. Iterate across all files. If files were previously signed, for example version 1 was signed previously, don't re-sign.

I believe the preference should probably be with the first, but I'm indifferent

Actual behavior

fail: Sign.Core.ISigner[0]
      Sequence contains more than one matching element
      System.InvalidOperationException: Sequence contains more than one matching element
         at System.Linq.ThrowHelper.ThrowMoreThanOneMatchException()
         at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
         at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
         at Sign.Core.ClickOnceSigner.<>c__DisplayClass9_0.<<SignAsync>b__0>d.MoveNext() in /_/src/Sign.Core/DataFormatSigners/ClickOnceSigner.cs:line 130
      --- End of stack trace from previous location ---
         at System.Threading.Tasks.Parallel.<>c__53`1.<<ForEachAsync>b__53_0>d.MoveNext()
      --- End of stack trace from previous location ---
         at Sign.Core.ClickOnceSigner.SignAsync(IEnumerable`1 files, SignOptions options) in /_/src/Sign.Core/DataFormatSigners/ClickOnceSigner.cs:line 82
         at Sign.Core.AggregatingSigner.SignAsync(IEnumerable`1 files, SignOptions options) in /_/src/Sign.Core/DataFormatSigners/AggregatingSigner.cs:line 204
         at Sign.Core.Signer.<>c__DisplayClass3_0.<<SignAsync>b__0>d.MoveNext() in /_/src/Sign.Core/Signer.cs:line 155
      --- End of stack trace from previous location ---
         at System.Threading.Tasks.Parallel.<>c__53`1.<<ForEachAsync>b__53_0>d.MoveNext()
      --- End of stack trace from previous location ---
         at Sign.Core.Signer.SignAsync(IReadOnlyList`1 inputFiles, String outputFile, FileInfo fileList, DirectoryInfo baseDirectory, String applicationName, String publisherName, String description, Uri descriptionUrl, Uri timestampUrl, Int32 maxConcurrency, HashAlgorithmName fileHashAlgorithm, HashAlgorithmName timestampHashAlgorithm) in /_/src/Sign.Core/Signer.cs:line 84

Additional context

Potentially problematic code:

https://github.com/dotnet/sign/blob/d018f756bb9fea160069bca578f6f1bb33d00549/src/Sign.Core/DataFormatSigners/ClickOnceSigner.cs#L125-L132

This issue happened with at least the three latest versions:

  • 0.9.1-beta.24406.1+6584f5d081d8a06660d58d1a777b2352ff376a68
  • 0.9.1-beta.24170.3
  • 0.9.1-beta.24361.2
dotnet --info
.NET SDK:
 Version:           8.0.400
 Commit:            36fe6dda56
 Workload version:  8.0.400-manifests.56cd0383
 MSBuild version:   17.11.3+0c8610977

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.22631
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\8.0.400\

.NET workloads installed:
Configured to use loose manifests when installing new manifests.
 [android]
   Installation Source: VS 17.11.35219.272
   Manifest Version:    34.0.113/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.android\34.0.113\WorkloadManifest.json
   Install Type:        FileBased

 [maccatalyst]
   Installation Source: VS 17.11.35219.272
   Manifest Version:    17.5.8020/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maccatalyst\17.5.8020\WorkloadManifest.json
   Install Type:        FileBased

 [wasm-tools]
   Installation Source: VS 17.11.35219.272
   Manifest Version:    8.0.8/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.workload.mono.toolchain.current\8.0.8\WorkloadManifest.json
   Install Type:        FileBased

 [maui-windows]
   Installation Source: VS 17.11.35219.272
   Manifest Version:    8.0.72/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maui\8.0.72\WorkloadManifest.json
   Install Type:        FileBased

 [ios]
   Installation Source: VS 17.11.35219.272
   Manifest Version:    17.5.8020/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.ios\17.5.8020\WorkloadManifest.json
   Install Type:        FileBased

 [aspire]
   Installation Source: VS 17.11.35219.272
   Manifest Version:    8.1.0/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.1.0\WorkloadManifest.json
   Install Type:        FileBased


Host:
  Version:      8.0.8
  Architecture: x64
  Commit:       08338fcaa5

.NET SDKs installed:
  3.1.426 [C:\Program Files\dotnet\sdk]
  6.0.321 [C:\Program Files\dotnet\sdk]
  8.0.400 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

MH-ZShearer avatar Aug 29 '24 17:08 MH-ZShearer

This appears to be resolved by https://github.com/dotnet/sign/pull/758.

dtivel avatar Oct 01 '24 19:10 dtivel

I looked into that PR, but it did not appear to address the issue. #773 also does not resolve this issue. I provided some additional detail about the file structure in https://github.com/dotnet/sign/issues/681#issuecomment-2426793329.

MH-ZShearer avatar Oct 21 '24 14:10 MH-ZShearer