cyclonedx-dotnet icon indicating copy to clipboard operation
cyclonedx-dotnet copied to clipboard

Can't handle referenced build properties for AssemblyName

Open TobiDimmel opened this issue 1 year ago • 1 comments

Current Behavior

We use the following definition in all our project files:

<RootNamespace>CycloneDxDotnet.Repro.WebApi</RootNamespace>
<AssemblyName>$(RootNamespace)</AssemblyName>

If you now reference multiple such projects in a main project, cyclonedx-dotnet throws an error:

Unhandled exception: System.ArgumentException: An item with the same key has already been added. Key: $(RootNamespace)
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector)
   at CycloneDX.Services.ProjectFileService.RecursivelyGetProjectReferencesAsync(String projectFilePath) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/ProjectFileService.cs:line 368
   at CycloneDX.Services.ProjectFileService.RecursivelyGetProjectDotnetDependencysAsync(String projectFilePath, String baseIntermediateOutputPath, Boolean excludeTestProjects, String framework, String runtime) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Services/ProjectFileService.cs:line 248
   at CycloneDX.Runner.HandleCommandAsync(RunOptions options) in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Runner.cs:line 182
   at CycloneDX.Program.<>c__DisplayClass0_0.<<Main>b__2>d.MoveNext() in /home/runner/work/cyclonedx-dotnet/cyclonedx-dotnet/CycloneDX/Program.cs:line 137
--- End of stack trace from previous location ---
   at System.CommandLine.Invocation.AnonymousCommandHandler.InvokeAsync(InvocationContext context)
   at System.CommandLine.Invocation.AnonymousCommandHandler.SyncUsingAsync(InvocationContext context)
   at System.CommandLine.Invocation.AnonymousCommandHandler.Invoke(InvocationContext context)
   at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass17_0.<<UseParseErrorReporting>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass12_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseVersionOption>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass19_0.<<UseTypoCorrections>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__18_0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<UseParseDirective>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__5_0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass8_0.<<UseExceptionHandler>b__0>d.MoveNext()

Workaround

To work around this issue, you could set AssemblyName explicitly. Reversing the reference of the build property is not a good solution because it can make problems in other tools (e.g. ReSharper):

<RootNamespace>$(AssemblyName)</RootNamespace>
<AssemblyName>CycloneDxDotnet.Repro.WebApi</AssemblyName>

Reproduction

For reproduction use the added solution folder and execute:

dotnet CycloneDX .\WebApi\WebApi.csproj -o . -f WebApi.sbom.json --json --recursive

Expected Behavior

Resolve referenced build properties for AssemblyName or detect such use cases and return a descriptive error message that cyclonedx-dotnet can't handle it.

Environment

dotnet cyclonedx --version

4.1.0+3ad0483c8724b6ddd0c20506b034dde5f8555b44

dotnet --info

.NET SDK:
 Version:           8.0.404
 Commit:            7b190310f2
 Workload version:  8.0.400-manifests.c6df56b6
 MSBuild version:   17.11.9+a69bbaaf5

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

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


Host:
  Version:      8.0.11
  Architecture: x64
  Commit:       9cb3b725e3

.NET SDKs installed:
  8.0.404 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 8.0.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.22 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.23 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.22 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.23 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.13 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.11 [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

TobiDimmel avatar Dec 03 '24 10:12 TobiDimmel

A workaround could also be to disable recursive. If not needed, I recommend to not use it as it can also cause inaccurate scan results.

The problem is likely here: https://github.com/CycloneDX/cyclonedx-dotnet/blob/790c3a79777f412e930a2ed68c2bde4f9ba98f79/CycloneDX/Services/ProjectFileService.cs#L99C1-L100C132.

It could become difficult to resolve those variables at design time, however for simpler cases, like $(RootNamespace), we could add handling.

mtsfoni avatar Feb 01 '25 23:02 mtsfoni