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:
|
||||
max-same-issues: 25
|
||||
uniq-by-line: false
|
||||
|
||||
# TODO: enable this when we have coverage on docstring comments
|
||||
# # The list of ids of default excludes to include or disable.
|
||||
@ -60,8 +61,6 @@ linters-settings:
|
||||
gosec:
|
||||
excludes:
|
||||
- G115
|
||||
output:
|
||||
uniq-by-line: false
|
||||
run:
|
||||
timeout: 10m
|
||||
tests: false
|
||||
|
||||
@ -3,5 +3,5 @@ package internal
|
||||
const (
|
||||
// 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.
|
||||
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"),
|
||||
|
||||
// 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(python.NewInstalledPackageCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "python"),
|
||||
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",
|
||||
"$id": "anchore.io/schema/syft/json/16.0.18/document",
|
||||
"$id": "anchore.io/schema/syft/json/16.0.19/document",
|
||||
"$ref": "#/$defs/Document",
|
||||
"$defs": {
|
||||
"AlpmDbEntry": {
|
||||
@ -492,6 +492,29 @@
|
||||
"hashPath"
|
||||
]
|
||||
},
|
||||
"DotnetPackagesLockEntry": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
"contentHash": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"version",
|
||||
"contentHash",
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"DotnetPortableExecutableEntry": {
|
||||
"properties": {
|
||||
"assemblyVersion": {
|
||||
@ -1648,6 +1671,9 @@
|
||||
{
|
||||
"$ref": "#/$defs/DotnetDepsEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/DotnetPackagesLockEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/DotnetPortableExecutableEntry"
|
||||
},
|
||||
|
||||
@ -19,6 +19,7 @@ func Test_OriginatorSupplier(t *testing.T) {
|
||||
pkg.ConaninfoEntry{},
|
||||
pkg.DartPubspecLockEntry{},
|
||||
pkg.DotnetDepsEntry{},
|
||||
pkg.DotnetPackagesLockEntry{},
|
||||
pkg.ELFBinaryPackageNoteJSONPayload{},
|
||||
pkg.ElixirMixLockEntry{},
|
||||
pkg.ErlangRebarLockEntry{},
|
||||
|
||||
@ -17,6 +17,7 @@ func AllTypes() []any {
|
||||
pkg.ConaninfoEntry{},
|
||||
pkg.DartPubspecLockEntry{},
|
||||
pkg.DotnetDepsEntry{},
|
||||
pkg.DotnetPackagesLockEntry{},
|
||||
pkg.DotnetPortableExecutableEntry{},
|
||||
pkg.DpkgDBEntry{},
|
||||
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
|
||||
jsonNames(pkg.WordpressPluginEntry{}, "wordpress-plugin-entry", "WordpressMetadata"),
|
||||
jsonNames(pkg.LuaRocksPackage{}, "luarocks-package"),
|
||||
jsonNames(pkg.DotnetPackagesLockEntry{}, "dotnet-packages-lock-entry"),
|
||||
)
|
||||
|
||||
func expandLegacyNameVariants(names ...string) []string {
|
||||
|
||||
@ -19,3 +19,7 @@ func NewDotnetPortableExecutableCataloger() pkg.Cataloger {
|
||||
return generic.NewCataloger("dotnet-portable-executable-cataloger").
|
||||
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"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
type DotnetPortableExecutableEntry struct {
|
||||
AssemblyVersion string `json:"assemblyVersion"`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user