mirror of
https://github.com/anchore/syft
synced 2024-11-10 06:14:16 +00:00
fix: DecoderCollection discarding input from non-seekable Readers (#2878)
Signed-off-by: Russell Haering <russellhaering@gmail.com>
This commit is contained in:
parent
15c9fe092a
commit
1bec1fc5d3
2 changed files with 32 additions and 4 deletions
|
@ -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"
|
||||
)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 != "" {
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
@ -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]
|
||||
|
|
Loading…
Reference in a new issue