mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +01:00
fix: encode and decode FileLicenses and FileContents in Syft JSON (#2083)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
This commit is contained in:
parent
3e16c6813f
commit
a46d12270f
@ -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 = "10.0.1"
|
||||
JSONSchemaVersion = "10.0.2"
|
||||
)
|
||||
|
||||
1976
schema/json/schema-10.0.2.json
Normal file
1976
schema/json/schema-10.0.2.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -9,8 +9,17 @@ import (
|
||||
|
||||
"github.com/go-test/deep"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
stereoscopeFile "github.com/anchore/stereoscope/pkg/file"
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/syft/cpe"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/formats/internal/testutils"
|
||||
"github.com/anchore/syft/syft/linux"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/sbom"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
)
|
||||
|
||||
func TestEncodeDecodeCycle(t *testing.T) {
|
||||
@ -86,3 +95,145 @@ func TestOutOfDateParser(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_encodeDecodeFileMetadata(t *testing.T) {
|
||||
p := pkg.Package{
|
||||
Name: "pkg",
|
||||
Version: "version",
|
||||
FoundBy: "something",
|
||||
Locations: file.NewLocationSet(file.Location{
|
||||
LocationData: file.LocationData{
|
||||
Coordinates: file.Coordinates{
|
||||
RealPath: "/somewhere",
|
||||
FileSystemID: "id",
|
||||
},
|
||||
},
|
||||
LocationMetadata: file.LocationMetadata{
|
||||
Annotations: map[string]string{
|
||||
"key": "value",
|
||||
},
|
||||
},
|
||||
}),
|
||||
Licenses: pkg.NewLicenseSet(pkg.License{
|
||||
Value: "MIT",
|
||||
SPDXExpression: "MIT",
|
||||
Type: "MIT",
|
||||
URLs: internal.NewStringSet("https://example.org/license"),
|
||||
Locations: file.LocationSet{},
|
||||
}),
|
||||
Language: "language",
|
||||
Type: "type",
|
||||
CPEs: []cpe.CPE{
|
||||
{
|
||||
Part: "a",
|
||||
Vendor: "vendor",
|
||||
Product: "product",
|
||||
Version: "version",
|
||||
Update: "update",
|
||||
},
|
||||
},
|
||||
PURL: "pkg:generic/pkg@version",
|
||||
MetadataType: "",
|
||||
Metadata: nil,
|
||||
}
|
||||
p.SetID()
|
||||
|
||||
c := file.Coordinates{
|
||||
RealPath: "some-file",
|
||||
FileSystemID: "some-fs-id",
|
||||
}
|
||||
|
||||
s := sbom.SBOM{
|
||||
Artifacts: sbom.Artifacts{
|
||||
Packages: pkg.NewCollection(p),
|
||||
FileMetadata: map[file.Coordinates]file.Metadata{
|
||||
c: {
|
||||
FileInfo: stereoscopeFile.ManualInfo{
|
||||
NameValue: c.RealPath,
|
||||
ModeValue: 0644,
|
||||
SizeValue: 7,
|
||||
},
|
||||
Path: c.RealPath,
|
||||
Type: stereoscopeFile.TypeRegular,
|
||||
UserID: 1,
|
||||
GroupID: 2,
|
||||
MIMEType: "text/plain",
|
||||
},
|
||||
},
|
||||
FileDigests: map[file.Coordinates][]file.Digest{
|
||||
c: {
|
||||
{
|
||||
Algorithm: "sha1",
|
||||
Value: "d34db33f",
|
||||
},
|
||||
},
|
||||
},
|
||||
FileContents: map[file.Coordinates]string{
|
||||
c: "some contents",
|
||||
},
|
||||
FileLicenses: map[file.Coordinates][]file.License{
|
||||
c: {
|
||||
{
|
||||
Value: "MIT",
|
||||
SPDXExpression: "MIT",
|
||||
Type: "MIT",
|
||||
LicenseEvidence: &file.LicenseEvidence{
|
||||
Confidence: 1,
|
||||
Offset: 2,
|
||||
Extent: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
LinuxDistribution: &linux.Release{
|
||||
PrettyName: "some os",
|
||||
Name: "os",
|
||||
ID: "os-id",
|
||||
IDLike: []string{"os"},
|
||||
Version: "version",
|
||||
VersionID: "version",
|
||||
VersionCodename: "codename",
|
||||
BuildID: "build-id",
|
||||
ImageID: "image-id",
|
||||
ImageVersion: "image-version",
|
||||
Variant: "variant",
|
||||
VariantID: "variant-id",
|
||||
HomeURL: "https://example.org/os",
|
||||
SupportURL: "https://example.org/os/support",
|
||||
BugReportURL: "https://example.org/os/bugs",
|
||||
PrivacyPolicyURL: "https://example.org/os/privacy",
|
||||
CPEName: "os-cpe",
|
||||
SupportEnd: "now",
|
||||
},
|
||||
},
|
||||
Relationships: nil,
|
||||
Source: source.Description{
|
||||
ID: "some-id",
|
||||
Name: "some-name",
|
||||
Version: "some-version",
|
||||
Metadata: source.FileSourceMetadata{
|
||||
Path: "/some-file-source-path",
|
||||
Digests: []file.Digest{
|
||||
{
|
||||
Algorithm: "sha1",
|
||||
Value: "d34db33f",
|
||||
},
|
||||
},
|
||||
MIMEType: "file/zip",
|
||||
},
|
||||
},
|
||||
Descriptor: sbom.Descriptor{
|
||||
Name: "syft",
|
||||
Version: "this-version",
|
||||
},
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
err := encoder(buf, s)
|
||||
require.NoError(t, err)
|
||||
|
||||
got, err := decoder(buf)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, s, *got)
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package model
|
||||
|
||||
import (
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/license"
|
||||
)
|
||||
|
||||
type File struct {
|
||||
@ -10,6 +11,7 @@ type File struct {
|
||||
Metadata *FileMetadataEntry `json:"metadata,omitempty"`
|
||||
Contents string `json:"contents,omitempty"`
|
||||
Digests []file.Digest `json:"digests,omitempty"`
|
||||
Licenses []FileLicense `json:"licenses,omitempty"`
|
||||
}
|
||||
|
||||
type FileMetadataEntry struct {
|
||||
@ -21,3 +23,16 @@ type FileMetadataEntry struct {
|
||||
MIMEType string `json:"mimeType"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
type FileLicense struct {
|
||||
Value string `json:"value"`
|
||||
SPDXExpression string `json:"spdxExpression"`
|
||||
Type license.Type `json:"type"`
|
||||
Evidence *FileLicenseEvidence `json:"evidence,omitempty"`
|
||||
}
|
||||
|
||||
type FileLicenseEvidence struct {
|
||||
Confidence int `json:"confidence"`
|
||||
Offset int `json:"offset"`
|
||||
Extent int `json:"extent"`
|
||||
}
|
||||
|
||||
@ -106,12 +106,31 @@ func toFile(s sbom.SBOM) []model.File {
|
||||
contents = contentsForLocation
|
||||
}
|
||||
|
||||
var licenses []model.FileLicense
|
||||
for _, l := range artifacts.FileLicenses[coordinates] {
|
||||
var evidence *model.FileLicenseEvidence
|
||||
if e := l.LicenseEvidence; e != nil {
|
||||
evidence = &model.FileLicenseEvidence{
|
||||
Confidence: e.Confidence,
|
||||
Offset: e.Offset,
|
||||
Extent: e.Extent,
|
||||
}
|
||||
}
|
||||
licenses = append(licenses, model.FileLicense{
|
||||
Value: l.Value,
|
||||
SPDXExpression: l.SPDXExpression,
|
||||
Type: l.Type,
|
||||
Evidence: evidence,
|
||||
})
|
||||
}
|
||||
|
||||
results = append(results, model.File{
|
||||
ID: string(coordinates.ID()),
|
||||
Location: coordinates,
|
||||
Metadata: toFileMetadataEntry(coordinates, metadata),
|
||||
Digests: digests,
|
||||
Contents: contents,
|
||||
Licenses: licenses,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -34,6 +34,8 @@ func toSyftModel(doc model.Document) (*sbom.SBOM, error) {
|
||||
Packages: catalog,
|
||||
FileMetadata: fileArtifacts.FileMetadata,
|
||||
FileDigests: fileArtifacts.FileDigests,
|
||||
FileContents: fileArtifacts.FileContents,
|
||||
FileLicenses: fileArtifacts.FileLicenses,
|
||||
LinuxDistribution: toSyftLinuxRelease(doc.Distro),
|
||||
},
|
||||
Source: *toSyftSourceData(doc.Source),
|
||||
@ -66,6 +68,8 @@ func toSyftFiles(files []model.File) sbom.Artifacts {
|
||||
ret := sbom.Artifacts{
|
||||
FileMetadata: make(map[file.Coordinates]file.Metadata),
|
||||
FileDigests: make(map[file.Coordinates][]file.Digest),
|
||||
FileContents: make(map[file.Coordinates]string),
|
||||
FileLicenses: make(map[file.Coordinates][]file.License),
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
@ -100,6 +104,27 @@ func toSyftFiles(files []model.File) sbom.Artifacts {
|
||||
Value: d.Value,
|
||||
})
|
||||
}
|
||||
|
||||
if f.Contents != "" {
|
||||
ret.FileContents[coord] = f.Contents
|
||||
}
|
||||
|
||||
for _, l := range f.Licenses {
|
||||
var evidence *file.LicenseEvidence
|
||||
if e := l.Evidence; e != nil {
|
||||
evidence = &file.LicenseEvidence{
|
||||
Confidence: e.Confidence,
|
||||
Offset: e.Offset,
|
||||
Extent: e.Extent,
|
||||
}
|
||||
}
|
||||
ret.FileLicenses[coord] = append(ret.FileLicenses[coord], file.License{
|
||||
Value: l.Value,
|
||||
SPDXExpression: l.SPDXExpression,
|
||||
Type: l.Type,
|
||||
LicenseEvidence: evidence,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
|
||||
@ -312,6 +312,8 @@ func Test_toSyftFiles(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tt.want.FileContents = make(map[file.Coordinates]string)
|
||||
tt.want.FileLicenses = make(map[file.Coordinates][]file.License)
|
||||
assert.Equal(t, tt.want, toSyftFiles(tt.files))
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user