mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +01:00
feat: add cataloger for NuGet packages (#3484)
* add cataloger for dotnet packages.lock.json files Signed-off-by: Kemosabert <bert.coppens14@gmail.com> * add entry for dotnet packages.lock files Signed-off-by: Kemosabert <bert.coppens14@gmail.com> * add unit test for dotnet packages.lock cataloger Signed-off-by: Kemosabert <bert.coppens14@gmail.com> * add test for faulty packages.lock.json file Signed-off-by: Kemosabert <bert.coppens14@gmail.com> * add missing name metadata Signed-off-by: Kemosabert <bert.coppens14@gmail.com> * ensure package appears with version Signed-off-by: Kemosabert <bert.coppens14@gmail.com> * add example of conflicting dependencies Signed-off-by: Kemosabert <bert.coppens14@gmail.com> * fix linting Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * bump json schema and fix tests Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * move section Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: Kemosabert <bert.coppens14@gmail.com> Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
parent
6b2d73d4b7
commit
512319337f
@ -1,5 +1,6 @@
|
|||||||
issues:
|
issues:
|
||||||
max-same-issues: 25
|
max-same-issues: 25
|
||||||
|
uniq-by-line: false
|
||||||
|
|
||||||
# TODO: enable this when we have coverage on docstring comments
|
# TODO: enable this when we have coverage on docstring comments
|
||||||
# # The list of ids of default excludes to include or disable.
|
# # The list of ids of default excludes to include or disable.
|
||||||
@ -60,8 +61,6 @@ linters-settings:
|
|||||||
gosec:
|
gosec:
|
||||||
excludes:
|
excludes:
|
||||||
- G115
|
- G115
|
||||||
output:
|
|
||||||
uniq-by-line: false
|
|
||||||
run:
|
run:
|
||||||
timeout: 10m
|
timeout: 10m
|
||||||
tests: false
|
tests: false
|
||||||
|
|||||||
@ -3,5 +3,5 @@ package internal
|
|||||||
const (
|
const (
|
||||||
// JSONSchemaVersion is the current schema version output by the JSON encoder
|
// JSONSchemaVersion is the current schema version output by the JSON encoder
|
||||||
// This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment.
|
// This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment.
|
||||||
JSONSchemaVersion = "16.0.18"
|
JSONSchemaVersion = "16.0.19"
|
||||||
)
|
)
|
||||||
|
|||||||
@ -114,6 +114,7 @@ func DefaultPackageTaskFactories() PackageTaskFactories {
|
|||||||
newSimplePackageTaskFactory(ocaml.NewOpamPackageManagerCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "ocaml", "opam"),
|
newSimplePackageTaskFactory(ocaml.NewOpamPackageManagerCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "ocaml", "opam"),
|
||||||
|
|
||||||
// language-specific package for both image and directory scans (but not necessarily declared) ////////////////////////////////////////
|
// language-specific package for both image and directory scans (but not necessarily declared) ////////////////////////////////////////
|
||||||
|
newSimplePackageTaskFactory(dotnet.NewDotnetPackagesLockCataloger, pkgcataloging.DeclaredTag, pkgcataloging.ImageTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "dotnet", "c#"),
|
||||||
newSimplePackageTaskFactory(dotnet.NewDotnetPortableExecutableCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "dotnet", "c#", "binary"),
|
newSimplePackageTaskFactory(dotnet.NewDotnetPortableExecutableCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "dotnet", "c#", "binary"),
|
||||||
newSimplePackageTaskFactory(python.NewInstalledPackageCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "python"),
|
newSimplePackageTaskFactory(python.NewInstalledPackageCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "python"),
|
||||||
newPackageTaskFactory(
|
newPackageTaskFactory(
|
||||||
|
|||||||
2753
schema/json/schema-16.0.19.json
Normal file
2753
schema/json/schema-16.0.19.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
"$id": "anchore.io/schema/syft/json/16.0.18/document",
|
"$id": "anchore.io/schema/syft/json/16.0.19/document",
|
||||||
"$ref": "#/$defs/Document",
|
"$ref": "#/$defs/Document",
|
||||||
"$defs": {
|
"$defs": {
|
||||||
"AlpmDbEntry": {
|
"AlpmDbEntry": {
|
||||||
@ -492,6 +492,29 @@
|
|||||||
"hashPath"
|
"hashPath"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"DotnetPackagesLockEntry": {
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"contentHash": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"version",
|
||||||
|
"contentHash",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
"DotnetPortableExecutableEntry": {
|
"DotnetPortableExecutableEntry": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"assemblyVersion": {
|
"assemblyVersion": {
|
||||||
@ -1648,6 +1671,9 @@
|
|||||||
{
|
{
|
||||||
"$ref": "#/$defs/DotnetDepsEntry"
|
"$ref": "#/$defs/DotnetDepsEntry"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/DotnetPackagesLockEntry"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"$ref": "#/$defs/DotnetPortableExecutableEntry"
|
"$ref": "#/$defs/DotnetPortableExecutableEntry"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -19,6 +19,7 @@ func Test_OriginatorSupplier(t *testing.T) {
|
|||||||
pkg.ConaninfoEntry{},
|
pkg.ConaninfoEntry{},
|
||||||
pkg.DartPubspecLockEntry{},
|
pkg.DartPubspecLockEntry{},
|
||||||
pkg.DotnetDepsEntry{},
|
pkg.DotnetDepsEntry{},
|
||||||
|
pkg.DotnetPackagesLockEntry{},
|
||||||
pkg.ELFBinaryPackageNoteJSONPayload{},
|
pkg.ELFBinaryPackageNoteJSONPayload{},
|
||||||
pkg.ElixirMixLockEntry{},
|
pkg.ElixirMixLockEntry{},
|
||||||
pkg.ErlangRebarLockEntry{},
|
pkg.ErlangRebarLockEntry{},
|
||||||
|
|||||||
@ -17,6 +17,7 @@ func AllTypes() []any {
|
|||||||
pkg.ConaninfoEntry{},
|
pkg.ConaninfoEntry{},
|
||||||
pkg.DartPubspecLockEntry{},
|
pkg.DartPubspecLockEntry{},
|
||||||
pkg.DotnetDepsEntry{},
|
pkg.DotnetDepsEntry{},
|
||||||
|
pkg.DotnetPackagesLockEntry{},
|
||||||
pkg.DotnetPortableExecutableEntry{},
|
pkg.DotnetPortableExecutableEntry{},
|
||||||
pkg.DpkgDBEntry{},
|
pkg.DpkgDBEntry{},
|
||||||
pkg.ELFBinaryPackageNoteJSONPayload{},
|
pkg.ELFBinaryPackageNoteJSONPayload{},
|
||||||
|
|||||||
@ -109,6 +109,7 @@ var jsonTypes = makeJSONTypes(
|
|||||||
jsonNamesWithoutLookup(pkg.RustBinaryAuditEntry{}, "rust-cargo-audit-entry", "RustCargoPackageMetadata"), // the legacy value is split into two types, where the other is preferred
|
jsonNamesWithoutLookup(pkg.RustBinaryAuditEntry{}, "rust-cargo-audit-entry", "RustCargoPackageMetadata"), // the legacy value is split into two types, where the other is preferred
|
||||||
jsonNames(pkg.WordpressPluginEntry{}, "wordpress-plugin-entry", "WordpressMetadata"),
|
jsonNames(pkg.WordpressPluginEntry{}, "wordpress-plugin-entry", "WordpressMetadata"),
|
||||||
jsonNames(pkg.LuaRocksPackage{}, "luarocks-package"),
|
jsonNames(pkg.LuaRocksPackage{}, "luarocks-package"),
|
||||||
|
jsonNames(pkg.DotnetPackagesLockEntry{}, "dotnet-packages-lock-entry"),
|
||||||
)
|
)
|
||||||
|
|
||||||
func expandLegacyNameVariants(names ...string) []string {
|
func expandLegacyNameVariants(names ...string) []string {
|
||||||
|
|||||||
@ -19,3 +19,7 @@ func NewDotnetPortableExecutableCataloger() pkg.Cataloger {
|
|||||||
return generic.NewCataloger("dotnet-portable-executable-cataloger").
|
return generic.NewCataloger("dotnet-portable-executable-cataloger").
|
||||||
WithParserByGlobs(parseDotnetPortableExecutable, "**/*.dll", "**/*.exe")
|
WithParserByGlobs(parseDotnetPortableExecutable, "**/*.dll", "**/*.exe")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewDotnetPackagesLockCataloger() pkg.Cataloger {
|
||||||
|
return generic.NewCataloger("dotnet-packages-lock-cataloger").WithParserByGlobs(parseDotnetPackagesLock, "**/packages.lock.json")
|
||||||
|
}
|
||||||
|
|||||||
159
syft/pkg/cataloger/dotnet/parse_dotnet_packages_lock.go
Normal file
159
syft/pkg/cataloger/dotnet/parse_dotnet_packages_lock.go
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
package dotnet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"slices"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/anchore/packageurl-go"
|
||||||
|
"github.com/anchore/syft/internal/log"
|
||||||
|
"github.com/anchore/syft/internal/relationship"
|
||||||
|
"github.com/anchore/syft/syft/artifact"
|
||||||
|
"github.com/anchore/syft/syft/file"
|
||||||
|
"github.com/anchore/syft/syft/pkg"
|
||||||
|
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ generic.Parser = parseDotnetPackagesLock
|
||||||
|
|
||||||
|
type dotnetPackagesLock struct {
|
||||||
|
Version int `json:"version"`
|
||||||
|
Dependencies map[string]map[string]dotnetPackagesLockDep `json:"dependencies"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type dotnetPackagesLockDep struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Requested string `json:"requested"`
|
||||||
|
Resolved string `json:"resolved"`
|
||||||
|
ContentHash string `json:"contentHash"`
|
||||||
|
Dependencies map[string]string `json:"dependencies,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseDotnetPackagesLock(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { //nolint:funlen
|
||||||
|
var pkgs []pkg.Package
|
||||||
|
var pkgMap = make(map[string]pkg.Package)
|
||||||
|
var relationships []artifact.Relationship
|
||||||
|
|
||||||
|
dec := json.NewDecoder(reader)
|
||||||
|
|
||||||
|
// unmarshal file
|
||||||
|
var lockFile dotnetPackagesLock
|
||||||
|
if err := dec.Decode(&lockFile); err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to parse packages.lock.json file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// collect all deps here
|
||||||
|
allDependencies := make(map[string]dotnetPackagesLockDep)
|
||||||
|
|
||||||
|
var names []string
|
||||||
|
for _, dependencies := range lockFile.Dependencies {
|
||||||
|
for name, dep := range dependencies {
|
||||||
|
depNameVersion := createNameAndVersion(name, dep.Resolved)
|
||||||
|
|
||||||
|
if slices.Contains(names, depNameVersion) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
names = append(names, depNameVersion)
|
||||||
|
allDependencies[depNameVersion] = dep
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort the names so that the order of the packages is deterministic
|
||||||
|
sort.Strings(names)
|
||||||
|
|
||||||
|
// create artifact for each pkg
|
||||||
|
for _, nameVersion := range names {
|
||||||
|
name, _ := extractNameAndVersion(nameVersion)
|
||||||
|
|
||||||
|
dep := allDependencies[nameVersion]
|
||||||
|
dotnetPkg := newDotnetPackagesLockPackage(name, dep, reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation))
|
||||||
|
if dotnetPkg != nil {
|
||||||
|
pkgs = append(pkgs, *dotnetPkg)
|
||||||
|
pkgMap[nameVersion] = *dotnetPkg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill up relationships
|
||||||
|
for depNameVersion, dep := range allDependencies {
|
||||||
|
parentPkg, ok := pkgMap[depNameVersion]
|
||||||
|
if !ok {
|
||||||
|
log.Debug("package \"%s\" not found in map of all pacakges", depNameVersion)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for childDepName, childDepVersion := range dep.Dependencies {
|
||||||
|
childDepNameVersion := createNameAndVersion(childDepName, childDepVersion)
|
||||||
|
|
||||||
|
// try and find pkg for dependency with exact name and version
|
||||||
|
childPkg, ok := pkgMap[childDepNameVersion]
|
||||||
|
if !ok {
|
||||||
|
// no exact match found, lets match on name only, lockfile will contain other version of pkg
|
||||||
|
cpkg, ok := findPkgByName(childDepName, pkgMap)
|
||||||
|
if !ok {
|
||||||
|
log.Debug("dependency \"%s\" of package \"%s\" not found in map of all packages", childDepNameVersion, depNameVersion)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
childPkg = *cpkg
|
||||||
|
}
|
||||||
|
|
||||||
|
rel := artifact.Relationship{
|
||||||
|
From: parentPkg,
|
||||||
|
To: childPkg,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
}
|
||||||
|
relationships = append(relationships, rel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort the relationships for deterministic output
|
||||||
|
relationship.Sort(relationships)
|
||||||
|
|
||||||
|
return pkgs, relationships, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDotnetPackagesLockPackage(name string, dep dotnetPackagesLockDep, locations ...file.Location) *pkg.Package {
|
||||||
|
metadata := pkg.DotnetPackagesLockEntry{
|
||||||
|
Name: name,
|
||||||
|
Version: dep.Resolved,
|
||||||
|
ContentHash: dep.ContentHash,
|
||||||
|
Type: dep.Type,
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pkg.Package{
|
||||||
|
Name: name,
|
||||||
|
Version: dep.Resolved,
|
||||||
|
Type: pkg.DotnetPkg,
|
||||||
|
Metadata: metadata,
|
||||||
|
Locations: file.NewLocationSet(locations...),
|
||||||
|
Language: pkg.Dotnet,
|
||||||
|
PURL: packagesLockPackageURL(name, dep.Resolved),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func packagesLockPackageURL(name, version string) string {
|
||||||
|
var qualifiers packageurl.Qualifiers
|
||||||
|
|
||||||
|
return packageurl.NewPackageURL(
|
||||||
|
packageurl.TypeNuget, // See explanation in syft/pkg/cataloger/dotnet/package.go as to why this was chosen.
|
||||||
|
"",
|
||||||
|
name,
|
||||||
|
version,
|
||||||
|
qualifiers,
|
||||||
|
"",
|
||||||
|
).ToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
func findPkgByName(pkgName string, pkgMap map[string]pkg.Package) (*pkg.Package, bool) {
|
||||||
|
for pkgNameVersion, pkg := range pkgMap {
|
||||||
|
name, _ := extractNameAndVersion(pkgNameVersion)
|
||||||
|
if name == pkgName {
|
||||||
|
return &pkg, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
199
syft/pkg/cataloger/dotnet/parse_dotnet_packages_lock_test.go
Normal file
199
syft/pkg/cataloger/dotnet/parse_dotnet_packages_lock_test.go
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
package dotnet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/anchore/syft/syft/artifact"
|
||||||
|
"github.com/anchore/syft/syft/file"
|
||||||
|
"github.com/anchore/syft/syft/pkg"
|
||||||
|
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_corruptDotnetPackagesLock(t *testing.T) {
|
||||||
|
pkgtest.NewCatalogTester().
|
||||||
|
FromFile(t, "test-fixtures/glob-paths/src/packages.lock.json").
|
||||||
|
WithError().
|
||||||
|
TestParser(t, parseDotnetDeps)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseDotnetPackagesLock(t *testing.T) {
|
||||||
|
fixture := "test-fixtures/packages.lock.json"
|
||||||
|
fixtureLocationSet := file.NewLocationSet(file.NewLocation(fixture))
|
||||||
|
|
||||||
|
autoMapperPkg := pkg.Package{
|
||||||
|
Name: "AutoMapper",
|
||||||
|
Version: "13.0.1",
|
||||||
|
PURL: "pkg:nuget/AutoMapper@13.0.1",
|
||||||
|
Locations: fixtureLocationSet,
|
||||||
|
Language: pkg.Dotnet,
|
||||||
|
Type: pkg.DotnetPkg,
|
||||||
|
Metadata: pkg.DotnetPackagesLockEntry{
|
||||||
|
Name: "AutoMapper",
|
||||||
|
Version: "13.0.1",
|
||||||
|
ContentHash: "/Fx1SbJ16qS7dU4i604Sle+U9VLX+WSNVJggk6MupKVkYvvBm4XqYaeFuf67diHefHKHs50uQIS2YEDFhPCakQ==",
|
||||||
|
Type: "Direct",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
bootstrapPkg := pkg.Package{
|
||||||
|
Name: "bootstrap",
|
||||||
|
Version: "5.0.0",
|
||||||
|
PURL: "pkg:nuget/bootstrap@5.0.0",
|
||||||
|
Locations: fixtureLocationSet,
|
||||||
|
Language: pkg.Dotnet,
|
||||||
|
Type: pkg.DotnetPkg,
|
||||||
|
Metadata: pkg.DotnetPackagesLockEntry{
|
||||||
|
Name: "bootstrap",
|
||||||
|
Version: "5.0.0",
|
||||||
|
ContentHash: "NKQFzFwrfWOMjTwr+X/2iJyCveuAGF+fNzkxyB0YW45+InVhcE9PUxoL1a8Vmc/Lq9E/CQd4DjO8kU32P4w/Gg==",
|
||||||
|
Type: "Direct",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
log4netPkg := pkg.Package{
|
||||||
|
Name: "log4net",
|
||||||
|
Version: "2.0.5",
|
||||||
|
PURL: "pkg:nuget/log4net@2.0.5",
|
||||||
|
Locations: fixtureLocationSet,
|
||||||
|
Language: pkg.Dotnet,
|
||||||
|
Type: pkg.DotnetPkg,
|
||||||
|
Metadata: pkg.DotnetPackagesLockEntry{
|
||||||
|
Name: "log4net",
|
||||||
|
Version: "2.0.5",
|
||||||
|
ContentHash: "AEqPZz+v+OikfnR2SqRVdQPnSaLq5y9Iz1CfRQZ9kTKPYCXHG6zYmDHb7wJotICpDLMr/JqokyjiqKAjUKp0ng==",
|
||||||
|
Type: "Direct",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
log4net1Pkg := pkg.Package{
|
||||||
|
Name: "log4net",
|
||||||
|
Version: "1.2.15",
|
||||||
|
PURL: "pkg:nuget/log4net@1.2.15",
|
||||||
|
Locations: fixtureLocationSet,
|
||||||
|
Language: pkg.Dotnet,
|
||||||
|
Type: pkg.DotnetPkg,
|
||||||
|
Metadata: pkg.DotnetPackagesLockEntry{
|
||||||
|
Name: "log4net",
|
||||||
|
Version: "1.2.15",
|
||||||
|
ContentHash: "KPajjkU1rbF6uY2rnakbh36LB9z9FVcYlciyOi6C5SJ3AMNywxjCGxBTN/Hl5nQEinRLuWvHWPF8W7YHh9sONw==",
|
||||||
|
Type: "Direct",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencyInjectionAbstractionsPkg := pkg.Package{
|
||||||
|
Name: "Microsoft.Extensions.DependencyInjection.Abstractions",
|
||||||
|
Version: "9.0.0",
|
||||||
|
PURL: "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@9.0.0",
|
||||||
|
Locations: fixtureLocationSet,
|
||||||
|
Language: pkg.Dotnet,
|
||||||
|
Type: pkg.DotnetPkg,
|
||||||
|
Metadata: pkg.DotnetPackagesLockEntry{
|
||||||
|
Name: "Microsoft.Extensions.DependencyInjection.Abstractions",
|
||||||
|
Version: "9.0.0",
|
||||||
|
ContentHash: "xlzi2IYREJH3/m6+lUrQlujzX8wDitm4QGnUu6kUXTQAWPuZY8i+ticFJbzfqaetLA6KR/rO6Ew/HuYD+bxifg==",
|
||||||
|
Type: "Transitive",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
extensionOptionsPkg := pkg.Package{
|
||||||
|
Name: "Microsoft.Extensions.Options",
|
||||||
|
Version: "9.0.0",
|
||||||
|
PURL: "pkg:nuget/Microsoft.Extensions.Options@9.0.0",
|
||||||
|
Locations: fixtureLocationSet,
|
||||||
|
Language: pkg.Dotnet,
|
||||||
|
Type: pkg.DotnetPkg,
|
||||||
|
Metadata: pkg.DotnetPackagesLockEntry{
|
||||||
|
Name: "Microsoft.Extensions.Options",
|
||||||
|
Version: "9.0.0",
|
||||||
|
ContentHash: "dzXN0+V1AyjOe2xcJ86Qbo233KHuLEY0njf/P2Kw8SfJU+d45HNS2ctJdnEnrWbM9Ye2eFgaC5Mj9otRMU6IsQ==",
|
||||||
|
Type: "Transitive",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
extensionPrimitivesPkg := pkg.Package{
|
||||||
|
Name: "Microsoft.Extensions.Primitives",
|
||||||
|
Version: "9.0.0",
|
||||||
|
PURL: "pkg:nuget/Microsoft.Extensions.Primitives@9.0.0",
|
||||||
|
Locations: fixtureLocationSet,
|
||||||
|
Language: pkg.Dotnet,
|
||||||
|
Type: pkg.DotnetPkg,
|
||||||
|
Metadata: pkg.DotnetPackagesLockEntry{
|
||||||
|
Name: "Microsoft.Extensions.Primitives",
|
||||||
|
Version: "9.0.0",
|
||||||
|
ContentHash: "9+PnzmQFfEFNR9J2aDTfJGGupShHjOuGw4VUv+JB044biSHrnmCIMD+mJHmb2H7YryrfBEXDurxQ47gJZdCKNQ==",
|
||||||
|
Type: "Transitive",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
compilerServicesUnsafePkg := pkg.Package{
|
||||||
|
Name: "System.Runtime.CompilerServices.Unsafe",
|
||||||
|
Version: "9.0.0",
|
||||||
|
PURL: "pkg:nuget/System.Runtime.CompilerServices.Unsafe@9.0.0",
|
||||||
|
Locations: fixtureLocationSet,
|
||||||
|
Language: pkg.Dotnet,
|
||||||
|
Type: pkg.DotnetPkg,
|
||||||
|
Metadata: pkg.DotnetPackagesLockEntry{
|
||||||
|
Name: "System.Runtime.CompilerServices.Unsafe",
|
||||||
|
Version: "9.0.0",
|
||||||
|
ContentHash: "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==",
|
||||||
|
Type: "Transitive",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
microsoftLoggingPkg := pkg.Package{
|
||||||
|
Name: "Microsoft.Extensions.Logging",
|
||||||
|
Version: "9.0.0",
|
||||||
|
PURL: "pkg:nuget/Microsoft.Extensions.Logging@9.0.0",
|
||||||
|
Locations: fixtureLocationSet,
|
||||||
|
Language: pkg.Dotnet,
|
||||||
|
Type: pkg.DotnetPkg,
|
||||||
|
Metadata: pkg.DotnetPackagesLockEntry{
|
||||||
|
Name: "Microsoft.Extensions.Logging",
|
||||||
|
Version: "9.0.0",
|
||||||
|
ContentHash: "crjWyORoug0kK7RSNJBTeSE6VX8IQgLf3nUpTB9m62bPXp/tzbnOsnbe8TXEG0AASNaKZddnpHKw7fET8E++Pg==",
|
||||||
|
Type: "Direct",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedPkgs := []pkg.Package{
|
||||||
|
autoMapperPkg,
|
||||||
|
compilerServicesUnsafePkg,
|
||||||
|
dependencyInjectionAbstractionsPkg,
|
||||||
|
microsoftLoggingPkg,
|
||||||
|
extensionOptionsPkg,
|
||||||
|
extensionPrimitivesPkg,
|
||||||
|
bootstrapPkg,
|
||||||
|
log4net1Pkg,
|
||||||
|
log4netPkg,
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedRelationships := []artifact.Relationship{
|
||||||
|
{
|
||||||
|
From: autoMapperPkg,
|
||||||
|
To: extensionOptionsPkg,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: extensionOptionsPkg,
|
||||||
|
To: dependencyInjectionAbstractionsPkg,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: extensionOptionsPkg,
|
||||||
|
To: extensionPrimitivesPkg,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: extensionPrimitivesPkg,
|
||||||
|
To: compilerServicesUnsafePkg,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: microsoftLoggingPkg,
|
||||||
|
To: extensionOptionsPkg,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
pkgtest.TestFileParser(t, fixture, parseDotnetPackagesLock, expectedPkgs, expectedRelationships)
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
"i am bogus"
|
||||||
78
syft/pkg/cataloger/dotnet/test-fixtures/packages.lock.json
Normal file
78
syft/pkg/cataloger/dotnet/test-fixtures/packages.lock.json
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"dependencies": {
|
||||||
|
"net8.0": {
|
||||||
|
"AutoMapper": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[13.0.1, )",
|
||||||
|
"resolved": "13.0.1",
|
||||||
|
"contentHash": "/Fx1SbJ16qS7dU4i604Sle+U9VLX+WSNVJggk6MupKVkYvvBm4XqYaeFuf67diHefHKHs50uQIS2YEDFhPCakQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.Options": "6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bootstrap": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[5.0.0, )",
|
||||||
|
"resolved": "5.0.0",
|
||||||
|
"contentHash": "NKQFzFwrfWOMjTwr+X/2iJyCveuAGF+fNzkxyB0YW45+InVhcE9PUxoL1a8Vmc/Lq9E/CQd4DjO8kU32P4w/Gg=="
|
||||||
|
},
|
||||||
|
"log4net": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[2.0.5, )",
|
||||||
|
"resolved": "2.0.5",
|
||||||
|
"contentHash": "AEqPZz+v+OikfnR2SqRVdQPnSaLq5y9Iz1CfRQZ9kTKPYCXHG6zYmDHb7wJotICpDLMr/JqokyjiqKAjUKp0ng=="
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "9.0.0",
|
||||||
|
"contentHash": "xlzi2IYREJH3/m6+lUrQlujzX8wDitm4QGnUu6kUXTQAWPuZY8i+ticFJbzfqaetLA6KR/rO6Ew/HuYD+bxifg=="
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Logging": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[9.0.0, )",
|
||||||
|
"resolved": "9.0.0",
|
||||||
|
"contentHash": "crjWyORoug0kK7RSNJBTeSE6VX8IQgLf3nUpTB9m62bPXp/tzbnOsnbe8TXEG0AASNaKZddnpHKw7fET8E++Pg==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.Options": "9.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Options": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "9.0.0",
|
||||||
|
"contentHash": "dzXN0+V1AyjOe2xcJ86Qbo233KHuLEY0njf/P2Kw8SfJU+d45HNS2ctJdnEnrWbM9Ye2eFgaC5Mj9otRMU6IsQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0",
|
||||||
|
"Microsoft.Extensions.Primitives": "9.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.Primitives": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "9.0.0",
|
||||||
|
"contentHash": "9+PnzmQFfEFNR9J2aDTfJGGupShHjOuGw4VUv+JB044biSHrnmCIMD+mJHmb2H7YryrfBEXDurxQ47gJZdCKNQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"System.Runtime.CompilerServices.Unsafe": "9.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"System.Runtime.CompilerServices.Unsafe": {
|
||||||
|
"type": "Transitive",
|
||||||
|
"resolved": "9.0.0",
|
||||||
|
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
|
||||||
|
}
|
||||||
|
},
|
||||||
|
".netcore2.0": {
|
||||||
|
"bootstrap": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[5.0.0, )",
|
||||||
|
"resolved": "5.0.0",
|
||||||
|
"contentHash": "NKQFzFwrfWOMjTwr+X/2iJyCveuAGF+fNzkxyB0YW45+InVhcE9PUxoL1a8Vmc/Lq9E/CQd4DjO8kU32P4w/Gg=="
|
||||||
|
},
|
||||||
|
"log4net": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[1.2.15, )",
|
||||||
|
"resolved": "1.2.15",
|
||||||
|
"contentHash": "KPajjkU1rbF6uY2rnakbh36LB9z9FVcYlciyOi6C5SJ3AMNywxjCGxBTN/Hl5nQEinRLuWvHWPF8W7YHh9sONw=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,6 +9,14 @@ type DotnetDepsEntry struct {
|
|||||||
HashPath string `mapstructure:"hashPath" json:"hashPath"`
|
HashPath string `mapstructure:"hashPath" json:"hashPath"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DotnetPackagesLockEntry is a struct that represents a single entry found in the "dependencies" section in a .NET packages.lock.json file.
|
||||||
|
type DotnetPackagesLockEntry struct {
|
||||||
|
Name string `mapstructure:"name" json:"name"`
|
||||||
|
Version string `mapstructure:"version" json:"version"`
|
||||||
|
ContentHash string `mapstructure:"contentHash" json:"contentHash"`
|
||||||
|
Type string `mapstructure:"type" json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
// DotnetPortableExecutableEntry is a struct that represents a single entry found within "VersionResources" section of a .NET Portable Executable binary file.
|
// DotnetPortableExecutableEntry is a struct that represents a single entry found within "VersionResources" section of a .NET Portable Executable binary file.
|
||||||
type DotnetPortableExecutableEntry struct {
|
type DotnetPortableExecutableEntry struct {
|
||||||
AssemblyVersion string `json:"assemblyVersion"`
|
AssemblyVersion string `json:"assemblyVersion"`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user