mirror of
https://github.com/anchore/syft.git
synced 2026-07-04 18:18:26 +02:00
Signed-off-by: Rez Moss <hi@rezmoss.com> Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com> Co-authored-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
This commit is contained in:
parent
5eefd73ac7
commit
fea4a50124
@ -3,7 +3,7 @@ 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.1.4"
|
||||
JSONSchemaVersion = "16.1.5"
|
||||
|
||||
// Changelog
|
||||
// 16.1.0 - reformulated the python pdm fields (added "URL" and removed the unused "path" field).
|
||||
@ -11,5 +11,6 @@ const (
|
||||
// 16.1.2 - placeholder for 16.1.2 changelog
|
||||
// 16.1.3 - add GGUFFileParts to GGUFFileHeader metadata
|
||||
// 16.1.4 - add BunLockEntry metadata type for bun.lock support
|
||||
// 16.1.5 - add DenoLockEntry and DenoRemoteLockEntry metadata types for deno.lock support
|
||||
|
||||
)
|
||||
|
||||
@ -20,6 +20,8 @@ func AllTypes() []any {
|
||||
pkg.CondaMetaPackage{},
|
||||
pkg.DartPubspec{},
|
||||
pkg.DartPubspecLockEntry{},
|
||||
pkg.DenoLockEntry{},
|
||||
pkg.DenoRemoteLockEntry{},
|
||||
pkg.DotnetDepsEntry{},
|
||||
pkg.DotnetPackagesLockEntry{},
|
||||
pkg.DotnetPortableExecutableEntry{},
|
||||
|
||||
@ -73,6 +73,8 @@ var jsonTypes = makeJSONTypes(
|
||||
jsonNames(pkg.ConaninfoEntry{}, "c-conan-info-entry"),
|
||||
jsonNames(pkg.DartPubspecLockEntry{}, "dart-pubspec-lock-entry", "DartPubMetadata"),
|
||||
jsonNames(pkg.DartPubspec{}, "dart-pubspec"),
|
||||
jsonNames(pkg.DenoLockEntry{}, "deno-lock-entry"),
|
||||
jsonNames(pkg.DenoRemoteLockEntry{}, "deno-remote-lock-entry"),
|
||||
jsonNames(pkg.DotnetDepsEntry{}, "dotnet-deps-entry", "DotnetDepsMetadata"),
|
||||
jsonNames(pkg.DotnetPortableExecutableEntry{}, "dotnet-portable-executable-entry"),
|
||||
jsonNames(pkg.DpkgArchiveEntry{}, "dpkg-archive-entry"),
|
||||
|
||||
@ -105,7 +105,7 @@ func DefaultPackageTaskFactories() Factories {
|
||||
func(cfg CatalogingFactoryConfig) pkg.Cataloger {
|
||||
return javascript.NewLockCataloger(cfg.PackagesConfig.JavaScript)
|
||||
},
|
||||
pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, JavaScript, Node, NPM,
|
||||
pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, JavaScript, Node, NPM, "deno",
|
||||
),
|
||||
newSimplePackageTaskFactory(php.NewComposerLockCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "php", "composer"),
|
||||
newSimplePackageTaskFactory(php.NewPearCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, pkgcataloging.ImageTag, "php", "pear"),
|
||||
|
||||
4351
schema/json/schema-16.1.5.json
Normal file
4351
schema/json/schema-16.1.5.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.1.4/document",
|
||||
"$id": "anchore.io/schema/syft/json/16.1.5/document",
|
||||
"$ref": "#/$defs/Document",
|
||||
"$defs": {
|
||||
"AlpmDbEntry": {
|
||||
@ -748,6 +748,45 @@
|
||||
],
|
||||
"description": "DartPubspecLockEntry is a struct that represents a single entry found in the \"packages\" section in a Dart pubspec.lock file."
|
||||
},
|
||||
"DenoLockEntry": {
|
||||
"properties": {
|
||||
"integrity": {
|
||||
"type": "string",
|
||||
"description": "Integrity is the crpto hash of the package content for verification"
|
||||
},
|
||||
"dependencies": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array",
|
||||
"description": "Dependencies is the list of package specifiers that this package depends on"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"integrity",
|
||||
"dependencies"
|
||||
],
|
||||
"description": "DenoLockEntry is a struct that rep a single entry found in the \"packages\" section of a Deno deno.lock file"
|
||||
},
|
||||
"DenoRemoteLockEntry": {
|
||||
"properties": {
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL is the remote URL from which the module fetcef"
|
||||
},
|
||||
"integrity": {
|
||||
"type": "string",
|
||||
"description": "Integrity is the crpto hash of the package content for verification"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url",
|
||||
"integrity"
|
||||
],
|
||||
"description": "DenoRemoteLockEntry is a struct that rep a single entry found in the \"remote\" section of a Deno deno.lock file"
|
||||
},
|
||||
"Descriptor": {
|
||||
"properties": {
|
||||
"name": {
|
||||
@ -2658,6 +2697,12 @@
|
||||
{
|
||||
"$ref": "#/$defs/DartPubspecLockEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/DenoLockEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/DenoRemoteLockEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/DotnetDepsEntry"
|
||||
},
|
||||
|
||||
@ -57,6 +57,8 @@ func Test_OriginatorSupplier(t *testing.T) {
|
||||
pkg.YarnLockEntry{},
|
||||
pkg.TerraformLockProviderEntry{},
|
||||
pkg.GGUFFileHeader{},
|
||||
pkg.DenoLockEntry{},
|
||||
pkg.DenoRemoteLockEntry{},
|
||||
)
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
@ -22,6 +22,7 @@ catalogers:
|
||||
config: javascript.CatalogerConfig # AUTO-GENERATED
|
||||
selectors: # AUTO-GENERATED
|
||||
- declared
|
||||
- deno
|
||||
- directory
|
||||
- javascript
|
||||
- language
|
||||
@ -29,6 +30,44 @@ catalogers:
|
||||
- npm
|
||||
- package
|
||||
parsers: # AUTO-GENERATED structure
|
||||
- function: parseDenoLock
|
||||
detector: # AUTO-GENERATED
|
||||
method: glob # AUTO-GENERATED
|
||||
criteria: # AUTO-GENERATED
|
||||
- '**/deno.lock'
|
||||
metadata_types: # AUTO-GENERATED
|
||||
- pkg.DenoLockEntry
|
||||
- pkg.DenoRemoteLockEntry
|
||||
- pkg.NpmPackageLockEntry
|
||||
package_types: # AUTO-GENERATED
|
||||
- npm
|
||||
purl_types: # AUTO-GENERATED
|
||||
- npm
|
||||
json_schema_types: # AUTO-GENERATED
|
||||
- DenoLockEntry
|
||||
- DenoRemoteLockEntry
|
||||
- JavascriptNpmPackageLockEntry
|
||||
capabilities: # MANUAL - preserved across regeneration
|
||||
- name: license
|
||||
default: false
|
||||
- name: dependency.depth
|
||||
default:
|
||||
- direct
|
||||
- indirect
|
||||
- name: dependency.edges
|
||||
default: ""
|
||||
- name: dependency.kinds
|
||||
default:
|
||||
- runtime
|
||||
- name: package_manager.files.listing
|
||||
default: false
|
||||
- name: package_manager.files.digests
|
||||
default: false
|
||||
- name: package_manager.package_integrity_hash
|
||||
default: true
|
||||
evidence:
|
||||
- DenoLockEntry.Integrity
|
||||
- DenoRemoteLockEntry.Integrity
|
||||
- function: parseBunLock
|
||||
detector: # AUTO-GENERATED
|
||||
method: glob # AUTO-GENERATED
|
||||
|
||||
@ -20,9 +20,11 @@ func NewLockCataloger(cfg CatalogerConfig) pkg.Cataloger {
|
||||
packageLockAdapter := newGenericPackageLockAdapter(cfg)
|
||||
pnpmLockAdapter := newGenericPnpmLockAdapter(cfg)
|
||||
bunLockAdapter := newGenericBunLockAdapter(cfg)
|
||||
denoLockAdapter := newGenericDenoLockAdapter(cfg)
|
||||
return generic.NewCataloger("javascript-lock-cataloger").
|
||||
WithParserByGlobs(packageLockAdapter.parsePackageLock, "**/package-lock.json").
|
||||
WithParserByGlobs(yarnLockAdapter.parseYarnLock, "**/yarn.lock").
|
||||
WithParserByGlobs(pnpmLockAdapter.parsePnpmLock, "**/pnpm-lock.yaml").
|
||||
WithParserByGlobs(bunLockAdapter.parseBunLock, "**/bun.lock")
|
||||
WithParserByGlobs(bunLockAdapter.parseBunLock, "**/bun.lock").
|
||||
WithParserByGlobs(denoLockAdapter.parseDenoLock, "**/deno.lock")
|
||||
}
|
||||
|
||||
@ -173,6 +173,7 @@ func Test_LockCataloger_Globs(t *testing.T) {
|
||||
name: "obtain package files",
|
||||
fixture: "testdata/glob-paths",
|
||||
expected: []string{
|
||||
"src/deno.lock",
|
||||
"src/package-lock.json",
|
||||
"src/pnpm-lock.yaml",
|
||||
"src/yarn.lock",
|
||||
|
||||
296
syft/pkg/cataloger/javascript/parse_deno_lock.go
Normal file
296
syft/pkg/cataloger/javascript/parse_deno_lock.go
Normal file
@ -0,0 +1,296 @@
|
||||
package javascript
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/packageurl-go"
|
||||
"github.com/anchore/syft/internal/unknown"
|
||||
"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"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/internal/dependency"
|
||||
)
|
||||
|
||||
type denoLock struct {
|
||||
Version string `json:"version"`
|
||||
Jsr map[string]denoJsrPackage `json:"jsr"`
|
||||
Npm map[string]denoNpmPackage `json:"npm"`
|
||||
Remote map[string]string `json:"remote"`
|
||||
}
|
||||
|
||||
type denoJsrPackage struct {
|
||||
Integrity string `json:"integrity"`
|
||||
Dependencies []string `json:"dependencies"`
|
||||
}
|
||||
|
||||
type denoNpmPackage struct {
|
||||
Integrity string `json:"integrity"`
|
||||
Dependencies []string `json:"dependencies"`
|
||||
}
|
||||
|
||||
type genericDenoLockAdapter struct {
|
||||
cfg CatalogerConfig
|
||||
}
|
||||
|
||||
func newGenericDenoLockAdapter(cfg CatalogerConfig) genericDenoLockAdapter {
|
||||
return genericDenoLockAdapter{
|
||||
cfg: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
func (a genericDenoLockAdapter) parseDenoLock(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
var pkgs []pkg.Package
|
||||
dec := json.NewDecoder(reader)
|
||||
|
||||
var lock denoLock
|
||||
for {
|
||||
if err := dec.Decode(&lock); errors.Is(err, io.EOF) {
|
||||
break
|
||||
} else if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to parse deno.lock file: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
for nameVersion, pkgMeta := range lock.Jsr {
|
||||
name, version := parseDenoJsrNameVersion(nameVersion)
|
||||
if name == "" || version == "" {
|
||||
continue
|
||||
}
|
||||
pkgs = append(pkgs, newDenoJsrPackage(reader.Location, name, version, pkgMeta))
|
||||
}
|
||||
|
||||
for nameVersion, pkgMeta := range lock.Npm {
|
||||
name, version := parseDenoNpmNameVersion(nameVersion)
|
||||
if name == "" || version == "" {
|
||||
continue
|
||||
}
|
||||
pkgs = append(pkgs, newDenoNpmPackage(reader.Location, name, version, pkgMeta))
|
||||
}
|
||||
|
||||
for rawURL, integrity := range lock.Remote {
|
||||
name, version := parseDenoRemoteURL(rawURL)
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
pkgs = append(pkgs, newDenoRemotePackage(reader.Location, name, version, rawURL, integrity))
|
||||
}
|
||||
|
||||
pkg.Sort(pkgs)
|
||||
|
||||
return pkgs, dependency.Resolve(denoLockDependencySpecifier, pkgs), unknown.IfEmptyf(pkgs, "unable to determine packages")
|
||||
}
|
||||
|
||||
func parseDenoJsrNameVersion(nameVersion string) (name, version string) {
|
||||
idx := strings.LastIndex(nameVersion, "@")
|
||||
if idx <= 0 {
|
||||
return "", ""
|
||||
}
|
||||
return nameVersion[:idx], nameVersion[idx+1:]
|
||||
}
|
||||
|
||||
func parseDenoNpmNameVersion(nameVersion string) (name, version string) {
|
||||
if strings.HasPrefix(nameVersion, "@") {
|
||||
rest := nameVersion[1:]
|
||||
idx := strings.LastIndex(rest, "@")
|
||||
if idx <= 0 {
|
||||
return "", ""
|
||||
}
|
||||
return nameVersion[:idx+1], rest[idx+1:]
|
||||
}
|
||||
idx := strings.LastIndex(nameVersion, "@")
|
||||
if idx <= 0 {
|
||||
return "", ""
|
||||
}
|
||||
return nameVersion[:idx], nameVersion[idx+1:]
|
||||
}
|
||||
|
||||
func newDenoJsrPackage(location file.Location, name, version string, meta denoJsrPackage) pkg.Package {
|
||||
p := pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
Locations: file.NewLocationSet(location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
|
||||
PURL: denoJsrPackageURL(name, version),
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.DenoLockEntry{
|
||||
Integrity: meta.Integrity,
|
||||
Dependencies: meta.Dependencies,
|
||||
},
|
||||
}
|
||||
p.SetID()
|
||||
return p
|
||||
}
|
||||
|
||||
func newDenoNpmPackage(location file.Location, name, version string, meta denoNpmPackage) pkg.Package {
|
||||
p := pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
Locations: file.NewLocationSet(location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
|
||||
PURL: denoNpmPackageURL(name, version),
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.NpmPackageLockEntry{
|
||||
Integrity: meta.Integrity,
|
||||
},
|
||||
}
|
||||
p.SetID()
|
||||
return p
|
||||
}
|
||||
|
||||
func newDenoRemotePackage(location file.Location, name, version, rawURL, integrity string) pkg.Package {
|
||||
p := pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
Locations: file.NewLocationSet(location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
|
||||
PURL: denoRemotePackageURL(name, version, rawURL),
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.DenoRemoteLockEntry{
|
||||
URL: rawURL,
|
||||
Integrity: integrity,
|
||||
},
|
||||
}
|
||||
p.SetID()
|
||||
return p
|
||||
}
|
||||
|
||||
func parseDenoRemoteURL(rawURL string) (name, version string) {
|
||||
rawURL = strings.TrimPrefix(rawURL, "https://")
|
||||
rawURL = strings.TrimPrefix(rawURL, "http://")
|
||||
|
||||
atIdx := strings.Index(rawURL, "@")
|
||||
if atIdx == -1 {
|
||||
slashIdx := strings.Index(rawURL, "/")
|
||||
if slashIdx == -1 {
|
||||
return rawURL, ""
|
||||
}
|
||||
return rawURL[:slashIdx], ""
|
||||
}
|
||||
|
||||
name = rawURL[:atIdx]
|
||||
|
||||
rest := rawURL[atIdx+1:]
|
||||
slashIdx := strings.Index(rest, "/")
|
||||
if slashIdx == -1 {
|
||||
version = rest
|
||||
} else {
|
||||
version = rest[:slashIdx]
|
||||
}
|
||||
|
||||
return name, version
|
||||
}
|
||||
|
||||
func extractRepositoryBase(rawURL string) string {
|
||||
u, err := url.Parse(rawURL)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%s://%s", u.Scheme, u.Host)
|
||||
}
|
||||
|
||||
func denoRemotePackageURL(name, version, rawURL string) string {
|
||||
repositoryURL := extractRepositoryBase(rawURL)
|
||||
var qualifiers packageurl.Qualifiers
|
||||
if repositoryURL != "" {
|
||||
qualifiers = packageurl.Qualifiers{{Key: "repository_url", Value: repositoryURL}}
|
||||
}
|
||||
|
||||
return packageurl.NewPackageURL(
|
||||
packageurl.TypeNPM,
|
||||
"",
|
||||
name,
|
||||
version,
|
||||
qualifiers,
|
||||
"",
|
||||
).ToString()
|
||||
}
|
||||
|
||||
func denoJsrPackageURL(name, version string) string {
|
||||
var namespace string
|
||||
fields := strings.SplitN(name, "/", 2)
|
||||
if len(fields) > 1 {
|
||||
namespace = fields[0]
|
||||
name = fields[1]
|
||||
}
|
||||
|
||||
return packageurl.NewPackageURL(
|
||||
packageurl.TypeNPM,
|
||||
namespace,
|
||||
name,
|
||||
version,
|
||||
packageurl.Qualifiers{{Key: "repository_url", Value: "https://jsr.io"}},
|
||||
"",
|
||||
).ToString()
|
||||
}
|
||||
|
||||
func denoNpmPackageURL(name, version string) string {
|
||||
var namespace string
|
||||
fields := strings.SplitN(name, "/", 2)
|
||||
if len(fields) > 1 {
|
||||
namespace = fields[0]
|
||||
name = fields[1]
|
||||
}
|
||||
|
||||
return packageurl.NewPackageURL(
|
||||
packageurl.TypeNPM,
|
||||
namespace,
|
||||
name,
|
||||
version,
|
||||
nil,
|
||||
"",
|
||||
).ToString()
|
||||
}
|
||||
|
||||
func denoLockDependencySpecifier(p pkg.Package) dependency.Specification {
|
||||
meta, ok := p.Metadata.(pkg.DenoLockEntry)
|
||||
if !ok {
|
||||
return dependency.Specification{}
|
||||
}
|
||||
|
||||
provides := []string{p.Name}
|
||||
var requires []string
|
||||
|
||||
for _, dep := range meta.Dependencies {
|
||||
name := parseDenoDependencyName(dep)
|
||||
if name != "" {
|
||||
requires = append(requires, name)
|
||||
}
|
||||
}
|
||||
|
||||
return dependency.Specification{
|
||||
ProvidesRequires: dependency.ProvidesRequires{
|
||||
Provides: provides,
|
||||
Requires: requires,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func parseDenoDependencyName(dep string) string {
|
||||
if strings.HasPrefix(dep, "jsr:") {
|
||||
dep = strings.TrimPrefix(dep, "jsr:")
|
||||
} else if strings.HasPrefix(dep, "npm:") {
|
||||
dep = strings.TrimPrefix(dep, "npm:")
|
||||
}
|
||||
|
||||
if strings.HasPrefix(dep, "@") {
|
||||
rest := dep[1:]
|
||||
atIdx := strings.Index(rest, "@")
|
||||
if atIdx > 0 {
|
||||
return dep[:atIdx+1]
|
||||
}
|
||||
return dep
|
||||
}
|
||||
|
||||
idx := strings.Index(dep, "@")
|
||||
if idx > 0 {
|
||||
return dep[:idx]
|
||||
}
|
||||
return dep
|
||||
}
|
||||
83
syft/pkg/cataloger/javascript/parse_deno_lock_test.go
Normal file
83
syft/pkg/cataloger/javascript/parse_deno_lock_test.go
Normal file
@ -0,0 +1,83 @@
|
||||
package javascript
|
||||
|
||||
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 TestParseDenoLock(t *testing.T) {
|
||||
fixture := "test-fixtures/deno/deno.lock"
|
||||
|
||||
expectedPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "@std/bytes",
|
||||
Version: "1.0.2",
|
||||
PURL: "pkg:npm/%40std/bytes@1.0.2?repository_url=https%3A%2F%2Fjsr.io",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.DenoLockEntry{
|
||||
Integrity: "fbdee322bbd8c599a6af186a1603b3355e59a5fb1baa139f8f4c3c9a1b3e3d57",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "@std/encoding",
|
||||
Version: "1.0.5",
|
||||
PURL: "pkg:npm/%40std/encoding@1.0.5?repository_url=https%3A%2F%2Fjsr.io",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.DenoLockEntry{
|
||||
Integrity: "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04",
|
||||
Dependencies: []string{"jsr:@std/bytes@^1.0.0"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "chalk",
|
||||
Version: "5.3.0",
|
||||
PURL: "pkg:npm/chalk@5.3.0",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.NpmPackageLockEntry{
|
||||
Integrity: "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "deno.land/std",
|
||||
Version: "0.140.0",
|
||||
PURL: "pkg:npm/deno.land%2Fstd@0.140.0?repository_url=https%3A%2F%2Fdeno.land",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.DenoRemoteLockEntry{
|
||||
URL: "https://deno.land/std@0.140.0/path/mod.ts",
|
||||
Integrity: "d3e68d0abb393fb0bf94a6d07c46ec31dc755b544b13144dee931d8d5f06a52d",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i := range expectedPkgs {
|
||||
expectedPkgs[i].Locations.Add(file.NewLocation(fixture))
|
||||
}
|
||||
|
||||
// @std/encoding depends => @std/bytes
|
||||
expectedRelationships := []artifact.Relationship{
|
||||
{
|
||||
From: expectedPkgs[0], // @std/bytes main
|
||||
To: expectedPkgs[1], // @std/encoding dep
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
},
|
||||
}
|
||||
|
||||
adapter := newGenericDenoLockAdapter(DefaultCatalogerConfig())
|
||||
pkgtest.TestFileParser(t, fixture, adapter.parseDenoLock, expectedPkgs, expectedRelationships)
|
||||
}
|
||||
|
||||
func Test_corruptDenoLock(t *testing.T) {
|
||||
adapter := newGenericDenoLockAdapter(DefaultCatalogerConfig())
|
||||
pkgtest.NewCatalogTester().
|
||||
FromFile(t, "test-fixtures/deno/corrupt/deno.lock").
|
||||
WithError().
|
||||
TestParser(t, adapter.parseDenoLock)
|
||||
}
|
||||
4
syft/pkg/cataloger/javascript/test-fixtures/deno/corrupt/deno.lock
generated
Normal file
4
syft/pkg/cataloger/javascript/test-fixtures/deno/corrupt/deno.lock
generated
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"version": "4",
|
||||
this is not valid json
|
||||
}
|
||||
27
syft/pkg/cataloger/javascript/test-fixtures/deno/deno.lock
generated
Normal file
27
syft/pkg/cataloger/javascript/test-fixtures/deno/deno.lock
generated
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"version": "4",
|
||||
"specifiers": {
|
||||
"jsr:@std/bytes@^1.0.0": "1.0.2",
|
||||
"jsr:@std/encoding@^1.0.0": "1.0.5",
|
||||
"npm:chalk@5": "5.3.0"
|
||||
},
|
||||
"jsr": {
|
||||
"@std/bytes@1.0.2": {
|
||||
"integrity": "fbdee322bbd8c599a6af186a1603b3355e59a5fb1baa139f8f4c3c9a1b3e3d57"
|
||||
},
|
||||
"@std/encoding@1.0.5": {
|
||||
"integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04",
|
||||
"dependencies": [
|
||||
"jsr:@std/bytes@^1.0.0"
|
||||
]
|
||||
}
|
||||
},
|
||||
"npm": {
|
||||
"chalk@5.3.0": {
|
||||
"integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w=="
|
||||
}
|
||||
},
|
||||
"remote": {
|
||||
"https://deno.land/std@0.140.0/path/mod.ts": "d3e68d0abb393fb0bf94a6d07c46ec31dc755b544b13144dee931d8d5f06a52d"
|
||||
}
|
||||
}
|
||||
3
syft/pkg/cataloger/javascript/testdata/glob-paths/src/deno.lock
generated
vendored
Normal file
3
syft/pkg/cataloger/javascript/testdata/glob-paths/src/deno.lock
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"version": "4"
|
||||
}
|
||||
19
syft/pkg/deno.go
Normal file
19
syft/pkg/deno.go
Normal file
@ -0,0 +1,19 @@
|
||||
package pkg
|
||||
|
||||
// DenoLockEntry is a struct that rep a single entry found in the "packages" section of a Deno deno.lock file
|
||||
type DenoLockEntry struct {
|
||||
// Integrity is the crpto hash of the package content for verification
|
||||
Integrity string `mapstructure:"integrity" json:"integrity"`
|
||||
|
||||
// Dependencies is the list of package specifiers that this package depends on
|
||||
Dependencies []string `mapstructure:"dependencies" json:"dependencies"`
|
||||
}
|
||||
|
||||
// DenoRemoteLockEntry is a struct that rep a single entry found in the "remote" section of a Deno deno.lock file
|
||||
type DenoRemoteLockEntry struct {
|
||||
// URL is the remote URL from which the module fetcef
|
||||
URL string `mapstructure:"url" json:"url"`
|
||||
|
||||
// Integrity is the crpto hash of the package content for verification
|
||||
Integrity string `mapstructure:"integrity" json:"integrity"`
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user