8000 .NET cataloger should consider compile target paths from deps.json by wagoodman · Pull Request #3821 · anchore/syft · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

.NET cataloger should consider compile target paths from deps.json #3821

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion syft/pkg/cataloger/dotnet/cataloger_test.go
8000
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,7 @@ func TestCataloger(t *testing.T) {
"Serilog.Sinks.Console @ 4.0.1 (/app/helloworld.deps.json)",
"helloworld @ 1.0.0 (/app/helloworld.deps.json)",
"runtime.linux-x64.Microsoft.NETCore.App @ 2.2.8 (/usr/share/dotnet/shared/Microsoft.NETCore.App/2.2.8/Microsoft.NETCore.App.deps.json)",
"runtime.linux-x64.Microsoft.NETCore.DotNetHostPolicy @ 2.2.8 (/usr/share/dotnet/shared/Microsoft.NETCore.App/2.2.8/Microsoft.NETCore.App.deps.json)", // a compile target reference
},
expectedRels: []string{
"Serilog @ 2.10.0 (/app/helloworld.deps.json) [dependency-of] Serilog.Sinks.Console @ 4.0.1 (/app/helloworld.deps.json)",
Expand Down Expand Up @@ -1035,7 +1036,7 @@ func TestCataloger(t *testing.T) {
}
}

func TestDotnetDepsCataloger_problemCases(t *testing.T) {
func TestDotnetDepsCataloger_regressions(t *testing.T) {
cases := []struct {
name string
fixture string
Expand Down Expand Up @@ -1072,6 +1073,20 @@ func TestDotnetDepsCataloger_problemCases(t *testing.T) {
pkgtest.AssertPackagesEqualIgnoreLayers(t, expected, actual)
},
},
{
name: "compile target reference",
fixture: "image-net8-compile-target",
cataloger: NewDotnetDepsBinaryCataloger(DefaultCatalogerConfig()),
assertion: func(t *testing.T, pkgs []pkg.Package, relationships []artifact.Relationship) {
// ensure we find the DotNetNuke.Core package (which is using the compile target reference)
for _, p := range pkgs {
if p.Name == "DotNetNuke.Core" {
return
}
}
t.Error("expected to find DotNetNuke.Core package")
},
},
}
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
Expand Down
10 changes: 9 additions & 1 deletion syft/pkg/cataloger/dotnet/deps_binary_cataloger.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@ func attachAssociatedExecutables(dep *logicalDepsJSON, pe logicalPE) bool {
continue
}

if targetPath, ok := p.CompilePathsByRelativeDLLPath[relativeDllPath]; ok {
pe.TargetPath = targetPath
p.Executables = append(p.Executables, pe)
dep.PackagesByNameVersion[key] = p // update the map with the modified package
found = true
continue
}

if p.NativePaths.Has(relativeDllPath) {
pe.TargetPath = relativeDllPath
p.Executables = append(p.Executables, pe)
Expand Down Expand Up @@ -265,7 +273,7 @@ func packagesFromLogicalDepsJSON(doc logicalDepsJSON, config CatalogerConfig) (*
continue
}

claimsDLLs := len(lp.RuntimePathsByRelativeDLLPath) > 0 || len(lp.ResourcePathsByRelativeDLLPath) > 0
claimsDLLs := len(lp.RuntimePathsByRelativeDLLPath) > 0 || len(lp.ResourcePathsByRelativeDLLPath) > 0 || len(lp.CompilePathsByRelativeDLLPath) > 0 || len(lp.NativePaths.List()) > 0

if conf 10000 ig.DepPackagesMustClaimDLL && !claimsDLLs {
if config.RelaxDLLClaimsWhenBundlingDetected && !doc.BundlingDetected || !config.RelaxDLLClaimsWhenBundlingDetected {
Expand Down
69 changes: 49 additions & 20 deletions syft/pkg/cataloger/dotnet/deps_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,50 @@ type depsTarget struct {
Dependencies map[string]string `json:"dependencies"`
Runtime map[string]map[string]string `json:"runtime"`
Resources map[string]map[string]string `json:"resources"`
Compile map[string]map[string]string `json:"compile"`
Native map[string]map[string]string `json:"native"`
}

func (t depsTarget) nativePaths() *strset.Set {
results := strset.New()
for path := range t.Native {
results.Add(path)
}
return results
}

func (t depsTarget) compilePaths() map[string]string {
result := make(map[string]string)
for path := range t.Compile {
trimmedPath := trimLibPrefix(path)
if _, exists := result[trimmedPath]; exists {
continue
}
result[trimmedPath] = path
}
return result
}

func (t depsTarget) resourcePaths() map[string]string {
result := make(map[string]string)
for path := range t.Resources {
trimmedPath := trimLibPrefix(path)
if _, exists := result[trimmedPath]; exists {
continue
}
result[trimmedPath] = path
}
return result
}

func (t depsTarget) runtimePaths() map[string]string {
result := make(map[string]string)
for path := range t.Runtime {
result[trimLibPrefix(path)] = path
}
return result
}

type depsLibrary struct {
Type string `json:"type"`
Path string `json:"path"`
Expand All @@ -51,6 +92,10 @@ type logicalDepsJSONPackage struct {
// to the target path as described in the deps.json target entry under "resource".
ResourcePathsByRelativeDLLPath map[string]string

// CompilePathsByRelativeDLLPath is a map of the relative path to the DLL relative to the deps.json file
// to the target path as described in the deps.json target entry under "compile".
CompilePathsByRelativeDLLPath map[string]string

// NativePathsByRelativeDLLPath is a map of the relative path to the DLL relative to the deps.json file
// to the target path as described in the deps.json target entry under "native". These should not have
// any runtime references to trim from the front of the path.
Expand Down Expand Up @@ -133,31 +178,15 @@ func getLogicalDepsJSON(deps depsJSON) logicalDepsJSON {
if ok {
lib = &l
}
runtimePaths := make(map[string]string)
for path := range target.Runtime {
runtimePaths[trimLibPrefix(path)] = path
}
resourcePaths := make(map[string]string)
for path := range target.Resources {
trimmedPath := trimLibPrefix(path)
if _, exists := resourcePaths[trimmedPath]; exists {
continue
}
resourcePaths[trimmedPath] = path
}

nativePaths := strset.New()
for path := range target.Native {
nativePaths.Add(path)
}

p := &logicalDepsJSONPackage{
NameVersion: libName,
Library: lib,
Targets: &target,
RuntimePathsByRelativeDLLPath: runtimePaths,
ResourcePathsByRelativeDLLPath: resourcePaths,
NativePaths: nativePaths,
RuntimePathsByRelativeDLLPath: target.runtimePaths(),
ResourcePathsByRelativeDLLPath: target.resourcePaths(),
CompilePathsByRelativeDLLPath: target.compilePaths(),
NativePaths: target.nativePaths(),
}
packageMap[libName] = p
nameVersions.Add(libName)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/app
/extract.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine@sha256:3f93439f47fea888d94e6e228d0d0de841f4122ef46f8bfd04f8bd78cbce7ddb AS build
ARG RUNTIME=win-x64
WORKDIR /src

COPY src/helloworld.csproj .
RUN dotnet restore -r $RUNTIME

COPY src/*.cs .

RUN dotnet publish -c Release --no-restore -o /app

# note: we're not using a runtime here to make testing easier... so you cannot run this container and expect it to work
# we do this to keep the test assertions small since the don't want to include the several other runtime packages
FROM busybox:latest

WORKDIR /app

COPY --from=build /app .
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;

namespace HelloWorld
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DotNetNuke.Core" Version="9.9.1"/>
<PackageReference Include="jQuery" Version="3.4.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.2.0" />
<PackageReference Include="Microsoft.ChakraCore" Version="1.11.24">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Nuget.CommandLine" Version="6.3.1">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Umbraco.Cms" Version="11.3.0" />
</ItemGroup>

</Project>
Loading
0