Skip to content

Commit

Permalink
fix: DecoderCollection discarding input from non-seekable Readers (#2878
Browse files Browse the repository at this point in the history
)

Signed-off-by: Russell Haering <russellhaering@gmail.com>
  • Loading branch information
russellhaering committed May 16, 2024
1 parent 15c9fe0 commit 1bec1fc
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 4 deletions.
23 changes: 19 additions & 4 deletions syft/format/decoders_collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"io"

"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/format/internal/stream"
"github.com/anchore/syft/syft/sbom"
)

Expand All @@ -20,10 +22,16 @@ func NewDecoderCollection(decoders ...sbom.FormatDecoder) sbom.FormatDecoder {
}

// Decode takes a set of bytes and attempts to decode it into an SBOM relative to the decoders in the collection.
func (c *DecoderCollection) Decode(reader io.Reader) (*sbom.SBOM, sbom.FormatID, string, error) {
if reader == nil {
func (c *DecoderCollection) Decode(r io.Reader) (*sbom.SBOM, sbom.FormatID, string, error) {
if r == nil {
return nil, "", "", fmt.Errorf("no SBOM bytes provided")
}

reader, err := stream.SeekableReader(r)
if err != nil {
return nil, "", "", fmt.Errorf("unable to create a seekable reader: %w", err)
}

var bestID sbom.FormatID
for _, d := range c.decoders {
id, version := d.Identify(reader)
Expand All @@ -45,10 +53,17 @@ func (c *DecoderCollection) Decode(reader io.Reader) (*sbom.SBOM, sbom.FormatID,
}

// Identify takes a set of bytes and attempts to identify the format of the SBOM relative to the decoders in the collection.
func (c *DecoderCollection) Identify(reader io.Reader) (sbom.FormatID, string) {
if reader == nil {
func (c *DecoderCollection) Identify(r io.Reader) (sbom.FormatID, string) {
if r == nil {
return "", ""
}

reader, err := stream.SeekableReader(r)
if err != nil {
log.Debugf("unable to create a seekable reader: %v", err)
return "", ""
}

for _, d := range c.decoders {
id, version := d.Identify(reader)
if id != "" && version != "" {
Expand Down
13 changes: 13 additions & 0 deletions syft/format/decoders_collection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package format

import (
"fmt"
"io"
"os"
"strings"
"testing"

"github.com/stretchr/testify/assert"

"github.com/anchore/syft/syft/format/spdxjson"
"github.com/anchore/syft/syft/format/syftjson"
"github.com/anchore/syft/syft/sbom"
)
Expand Down Expand Up @@ -37,6 +39,17 @@ func TestIdentify(t *testing.T) {
}
}

func TestDecodeUnseekable(t *testing.T) {
reader, err := os.Open("spdxjson/test-fixtures/spdx/example7-go-module.spdx.json")
assert.NoError(t, err)

// io.NopCloser wraps the reader in a non-seekable type
unseekableReader := io.NopCloser(reader)
_, formatID, _, err := Decode(unseekableReader)
assert.NoError(t, err)
assert.Equal(t, spdxjson.ID, formatID)
}

func TestFormats_EmptyInput(t *testing.T) {
for _, format := range Decoders() {
name := strings.Split(fmt.Sprintf("%#v", format), "{")[0]
Expand Down

0 comments on commit 1bec1fc

Please sign in to comment.