fix: .net deps.json cataloger no longer shows phantom pkgs (#4971)

Signed-off-by: Rez Moss <hi@rezmoss.com>
This commit is contained in:
Rez Moss 2026-06-16 12:02:42 -04:00 committed by GitHub
parent 8d48a8b8c2
commit 92ae4d44c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 167 additions and 0 deletions

View File

@ -292,6 +292,14 @@ func packagesFromLogicalDepsJSON(doc logicalDepsJSON, config CatalogerConfig) (*
} }
lp := doc.PackagesByNameVersion[nameVersion] lp := doc.PackagesByNameVersion[nameVersion]
if lp.Library != nil &&
lp.Library.Type == "referenceassembly" &&
lp.Library.Sha512 == "" &&
lp.Library.Path == "" {
skippedDepPkgs[nameVersion] = lp
continue
}
if config.ExcludeProjectReferences && lp.Library != nil && lp.Library.Type == "project" { if config.ExcludeProjectReferences && lp.Library != nil && lp.Library.Type == "project" {
skippedDepPkgs[nameVersion] = lp skippedDepPkgs[nameVersion] = lp
continue continue

View File

@ -0,0 +1,97 @@
package dotnet
import (
"encoding/json"
"os"
"testing"
"github.com/scylladb/go-set/strset"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
)
func Test_packagesFromLogicalDepsJSON_skipsReferenceAssemblies(t *testing.T) {
mkPkg := func(name, version, libType, sha, path string) logicalDepsJSONPackage {
nv := name + "/" + version
return logicalDepsJSONPackage{
NameVersion: nv,
Library: &depsLibrary{Type: libType, Sha512: sha, Path: path},
Targets: []depsTarget{
{Runtime: map[string]map[string]string{"lib/" + name + ".dll": {}}},
},
RuntimePathsByRelativeDLLPath: map[string]string{name + ".dll": "lib/" + name + ".dll"},
ResourcePathsByRelativeDLLPath: map[string]string{},
CompilePathsByRelativeDLLPath: map[string]string{},
NativePaths: strset.New(),
}
}
realPkg := mkPkg("Real", "1.0.0", "package", "abc", "real/1.0.0")
phantom := mkPkg("Phantom", "2.0.0", "referenceassembly", "", "")
keptRef := mkPkg("KeptRef", "3.0.0", "referenceassembly", "xyz", "p")
doc := logicalDepsJSON{
Location: file.NewLocation("/app/Test.deps.json"),
PackagesByNameVersion: map[string]logicalDepsJSONPackage{
realPkg.NameVersion: realPkg,
phantom.NameVersion: phantom,
keptRef.NameVersion: keptRef,
},
PackageNameVersions: strset.New(realPkg.NameVersion, phantom.NameVersion, keptRef.NameVersion),
}
cfg := DefaultCatalogerConfig().
WithDepPackagesMustClaimDLL(false).
WithDepPackagesMustHaveDLL(false)
_, pkgs, _ := packagesFromLogicalDepsJSON(doc, cfg)
names := make(map[string]string)
for _, p := range pkgs {
names[p.Name] = p.Version
}
assert.Equal(t, "1.0.0", names["Real"])
assert.Equal(t, "3.0.0", names["KeptRef"], "ref-asm w/ sha kept")
assert.NotContains(t, names, "Phantom", "ref-asm w/o evidence skipped")
for _, p := range pkgs {
assert.Equal(t, pkg.DotnetPkg, p.Type)
}
}
func Test_packagesFromLogicalDepsJSON_fixture_referenceassembly(t *testing.T) {
const fixturePath = "testdata/deps-with-referenceassembly/MyApp.deps.json"
raw, err := os.ReadFile(fixturePath)
require.NoError(t, err)
var deps depsJSON
require.NoError(t, json.Unmarshal(raw, &deps))
deps.Location = file.NewLocation("/app/MyApp.deps.json")
doc := getLogicalDepsJSON(deps, nil)
doc.Location = deps.Location
cfg := DefaultCatalogerConfig().
WithDepPackagesMustClaimDLL(false).
WithDepPackagesMustHaveDLL(false)
_, pkgs, _ := packagesFromLogicalDepsJSON(doc, cfg)
names := make(map[string]string)
for _, p := range pkgs {
names[p.Name] = p.Version
}
assert.Equal(t, "13.0.3", names["Newtonsoft.Json"])
assert.NotContains(t, names, "Microsoft.AspNetCore.DataProtection")
assert.NotContains(t, names, "Microsoft.AspNetCore.DataProtection.Abstractions")
for _, p := range pkgs {
assert.NotEqual(t, "10.0.0.0", p.Version, "no 10.0.0.0 phantom")
}
}

View File

@ -0,0 +1,62 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v10.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v10.0": {
"MyApp/1.0.0": {
"dependencies": {
"Newtonsoft.Json": "13.0.3",
"Microsoft.AspNetCore.DataProtection": "10.0.0.0"
},
"runtime": {
"MyApp.dll": {}
}
},
"Newtonsoft.Json/13.0.3": {
"runtime": {
"lib/net6.0/Newtonsoft.Json.dll": {
"assemblyVersion": "13.0.0.0",
"fileVersion": "13.0.3.27908"
}
}
},
"Microsoft.AspNetCore.DataProtection/10.0.0.0": {
"compile": {
"Microsoft.AspNetCore.DataProtection.dll": {}
}
},
"Microsoft.AspNetCore.DataProtection.Abstractions/10.0.0.0": {
"compile": {
"Microsoft.AspNetCore.DataProtection.Abstractions.dll": {}
}
}
}
},
"libraries": {
"MyApp/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Newtonsoft.Json/13.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==",
"path": "newtonsoft.json/13.0.3",
"hashPath": "newtonsoft.json.13.0.3.nupkg.sha512"
},
"Microsoft.AspNetCore.DataProtection/10.0.0.0": {
"type": "referenceassembly",
"serviceable": false,
"sha512": ""
},
"Microsoft.AspNetCore.DataProtection.Abstractions/10.0.0.0": {
"type": "referenceassembly",
"serviceable": false,
"sha512": ""
}
}
}