Split the sbom.Format interface by encode and decode use cases (#2186)

* split up sbom.Format into encode and decode ops

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update cmd pkg to inject format configs

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* bump cyclonedx schema to 1.5

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* redact image metadata from github encoder tests

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add more testing around format decoder identify

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add test case for format version options

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix cli tests

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix CLI test

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* [wip] - review comments

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* keep encoder creation out of post load function

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* keep decider and identify functions

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add a few more doc comments

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* remove format encoder default function helpers

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* address PR feedback

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* move back to streaming based decode functions

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* with common convention for encoder constructors

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix tests and allow for encoders to be created from cli options

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix cli tests

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix linting

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* buffer reads from stdin to support seeking

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Alex Goodman
2023-10-25 13:43:06 +00:00
committed by GitHub
parent 7315f83f9d
commit 7392d607b6
254 changed files with 10450 additions and 2714 deletions
+24 -2
View File
@@ -1,10 +1,14 @@
package sbom
import (
"bytes"
"fmt"
"io"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/formats"
"github.com/anchore/syft/syft/format"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/pkg/cataloger/generic"
)
@@ -30,7 +34,11 @@ func NewSBOMCataloger() *generic.Cataloger {
}
func parseSBOM(_ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
s, _, err := formats.Decode(reader)
readSeeker, err := adaptToReadSeeker(reader)
if err != nil {
return nil, nil, fmt.Errorf("unable to read SBOM file %q: %w", reader.Location.RealPath, err)
}
s, _, _, err := format.Decode(readSeeker)
if err != nil {
return nil, nil, err
}
@@ -62,3 +70,17 @@ func parseSBOM(_ file.Resolver, _ *generic.Environment, reader file.LocationRead
return pkgs, relationships, nil
}
func adaptToReadSeeker(reader io.Reader) (io.ReadSeeker, error) {
// with the stereoscope API and default file.Resolver implementation here in syft, odds are very high that
// the underlying reader is already a ReadSeeker, so we can just return it as-is. We still want to
if rs, ok := reader.(io.ReadSeeker); ok {
return rs, nil
}
log.Debug("SBOM cataloger reader is not a ReadSeeker, reading entire SBOM into memory")
var buff bytes.Buffer
_, err := io.Copy(&buff, reader)
return bytes.NewReader(buff.Bytes()), err
}
@@ -8,10 +8,8 @@ import (
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/cpe"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/formats/syftjson"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
"github.com/anchore/syft/syft/sbom"
)
func mustCPEs(s ...string) (c []cpe.CPE) {
@@ -405,7 +403,6 @@ func Test_parseSBOM(t *testing.T) {
tests := []struct {
name string
format sbom.Format
fixture string
wantPkgs []pkg.Package
wantRelationships []artifact.Relationship
@@ -413,7 +410,6 @@ func Test_parseSBOM(t *testing.T) {
}{
{
name: "parse syft JSON",
format: syftjson.Format(),
fixture: "test-fixtures/alpine/syft-json",
wantPkgs: expectedPkgs,
wantRelationships: expectedRelationships,