From 23c92d998d712fcf707bc5d8cdcf419f01730737 Mon Sep 17 00:00:00 2001 From: Will Murphy Date: Wed, 10 May 2023 16:20:33 -0400 Subject: [PATCH 1/3] feat: warn if parsing newer SBOM If syft is ask to parse an SBOM that was written by a newer version of syft, emit a warning. Signed-off-by: Will Murphy --- go.mod | 1 + go.sum | 2 ++ syft/formats/syftjson/decoder.go | 25 +++++++++++++++++++++++++ syft/formats/syftjson/decoder_test.go | 26 ++++++++++++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/go.mod b/go.mod index ce12af73fc6..8c988e1bc0d 100644 --- a/go.mod +++ b/go.mod @@ -50,6 +50,7 @@ require ( require ( github.com/CycloneDX/cyclonedx-go v0.7.1 + github.com/Masterminds/semver v1.5.0 github.com/Masterminds/sprig/v3 v3.2.3 github.com/anchore/go-logger v0.0.0-20220728155337-03b66a5207d8 github.com/anchore/stereoscope v0.0.0-20230412183729-8602f1afc574 diff --git a/go.sum b/go.sum index e96635aad6a..f7c61e853b5 100644 --- a/go.sum +++ b/go.sum @@ -62,6 +62,8 @@ github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= diff --git a/syft/formats/syftjson/decoder.go b/syft/formats/syftjson/decoder.go index b6286bd97c6..53e33d28fdd 100644 --- a/syft/formats/syftjson/decoder.go +++ b/syft/formats/syftjson/decoder.go @@ -5,6 +5,10 @@ import ( "fmt" "io" + "github.com/Masterminds/semver" + + "github.com/anchore/syft/internal" + "github.com/anchore/syft/internal/log" "github.com/anchore/syft/syft/formats/syftjson/model" "github.com/anchore/syft/syft/sbom" ) @@ -18,5 +22,26 @@ func decoder(reader io.Reader) (*sbom.SBOM, error) { return nil, fmt.Errorf("unable to decode syft-json: %w", err) } + if err := outOfDateParser(doc.Schema.Version, internal.JSONSchemaVersion); err != nil { + log.Warn(err) + } + return toSyftModel(doc) } + +func outOfDateParser(documentVerion string, parserVersion string) error { + documentV, err := semver.NewVersion(documentVerion) + if err != nil { + return err + } + parserV, err := semver.NewVersion(parserVersion) + if err != nil { + return err + } + + if documentV.GreaterThan(parserV) { + return fmt.Errorf("document has schema version %s, but parser has older schema version (%s)", documentVerion, parserVersion) + } + + return nil +} diff --git a/syft/formats/syftjson/decoder_test.go b/syft/formats/syftjson/decoder_test.go index de9ab7bcf7c..e3cf3ecd8ba 100644 --- a/syft/formats/syftjson/decoder_test.go +++ b/syft/formats/syftjson/decoder_test.go @@ -2,6 +2,7 @@ package syftjson import ( "bytes" + "fmt" "strings" "testing" @@ -49,3 +50,28 @@ func TestEncodeDecodeCycle(t *testing.T) { } } } + +func TestOutOfDateParser(t *testing.T) { + tests := []struct { + name string + documentVersion string + parserVersion string + want error + }{{ + name: "no warning when doc version is older", + documentVersion: "1.0.9", + parserVersion: "3.1.0", + }, { + name: "warning when parser is older", + documentVersion: "4.3.2", + parserVersion: "3.1.0", + want: fmt.Errorf("document has schema version %s, but parser has older schema version (%s)", "4.3.2", "3.1.0"), + }} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := outOfDateParser(tt.documentVersion, tt.parserVersion) + assert.Equal(t, tt.want, got) + }) + } +} From e0bc2e4857577b93739e41b6add56fc37a2a0bc3 Mon Sep 17 00:00:00 2001 From: Will Murphy Date: Wed, 10 May 2023 19:01:13 -0400 Subject: [PATCH 2/3] wrap semver parse errors Signed-off-by: Will Murphy --- syft/formats/syftjson/decoder.go | 5 +++-- syft/formats/syftjson/decoder_test.go | 11 +++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/syft/formats/syftjson/decoder.go b/syft/formats/syftjson/decoder.go index 53e33d28fdd..68826220ff1 100644 --- a/syft/formats/syftjson/decoder.go +++ b/syft/formats/syftjson/decoder.go @@ -32,11 +32,12 @@ func decoder(reader io.Reader) (*sbom.SBOM, error) { func outOfDateParser(documentVerion string, parserVersion string) error { documentV, err := semver.NewVersion(documentVerion) if err != nil { - return err + return fmt.Errorf("error comparing document schema version with parser schema version: %w", err) } + parserV, err := semver.NewVersion(parserVersion) if err != nil { - return err + return fmt.Errorf("error comparing document schema version with parser schema version: %w", err) } if documentV.GreaterThan(parserV) { diff --git a/syft/formats/syftjson/decoder_test.go b/syft/formats/syftjson/decoder_test.go index e3cf3ecd8ba..cf2268f7e3d 100644 --- a/syft/formats/syftjson/decoder_test.go +++ b/syft/formats/syftjson/decoder_test.go @@ -2,6 +2,7 @@ package syftjson import ( "bytes" + "errors" "fmt" "strings" "testing" @@ -66,6 +67,16 @@ func TestOutOfDateParser(t *testing.T) { documentVersion: "4.3.2", parserVersion: "3.1.0", want: fmt.Errorf("document has schema version %s, but parser has older schema version (%s)", "4.3.2", "3.1.0"), + }, { + name: "warning when document version is unparseable", + documentVersion: "some-nonsense", + parserVersion: "3.1.0", + want: fmt.Errorf("error comparing document schema version with parser schema version: %w", errors.New("Invalid Semantic Version")), + }, { + name: "warning when parser version is unparseable", + documentVersion: "7.1.0", + parserVersion: "some-nonsense", + want: fmt.Errorf("error comparing document schema version with parser schema version: %w", errors.New("Invalid Semantic Version")), }} for _, tt := range tests { From 3577eb58237732105cfe9a523983cbc4e4d608a3 Mon Sep 17 00:00:00 2001 From: Will Murphy Date: Wed, 10 May 2023 19:06:02 -0400 Subject: [PATCH 3/3] rename method based on feedback Signed-off-by: Will Murphy --- syft/formats/syftjson/decoder.go | 4 ++-- syft/formats/syftjson/decoder_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/syft/formats/syftjson/decoder.go b/syft/formats/syftjson/decoder.go index 68826220ff1..845c1fc0ba3 100644 --- a/syft/formats/syftjson/decoder.go +++ b/syft/formats/syftjson/decoder.go @@ -22,14 +22,14 @@ func decoder(reader io.Reader) (*sbom.SBOM, error) { return nil, fmt.Errorf("unable to decode syft-json: %w", err) } - if err := outOfDateParser(doc.Schema.Version, internal.JSONSchemaVersion); err != nil { + if err := checkSupportedSchema(doc.Schema.Version, internal.JSONSchemaVersion); err != nil { log.Warn(err) } return toSyftModel(doc) } -func outOfDateParser(documentVerion string, parserVersion string) error { +func checkSupportedSchema(documentVerion string, parserVersion string) error { documentV, err := semver.NewVersion(documentVerion) if err != nil { return fmt.Errorf("error comparing document schema version with parser schema version: %w", err) diff --git a/syft/formats/syftjson/decoder_test.go b/syft/formats/syftjson/decoder_test.go index cf2268f7e3d..e0de5fffbc4 100644 --- a/syft/formats/syftjson/decoder_test.go +++ b/syft/formats/syftjson/decoder_test.go @@ -81,7 +81,7 @@ func TestOutOfDateParser(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := outOfDateParser(tt.documentVersion, tt.parserVersion) + got := checkSupportedSchema(tt.documentVersion, tt.parserVersion) assert.Equal(t, tt.want, got) }) }