fix: Decode binary and unknown metadata (#1307)

This commit is contained in:
Keith Zantow 2022-11-01 17:26:00 -04:00 committed by GitHub
parent ba57f3db51
commit 95c7378109
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 116 deletions

View File

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"reflect"
"github.com/anchore/syft/internal/log" "github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/pkg"
@ -71,130 +72,31 @@ func (p *Package) UnmarshalJSON(b []byte) error {
return err return err
} }
//nolint:funlen,gocognit,gocyclo
func unpackMetadata(p *Package, unpacker packageMetadataUnpacker) error { func unpackMetadata(p *Package, unpacker packageMetadataUnpacker) error {
p.MetadataType = pkg.CleanMetadataType(unpacker.MetadataType) p.MetadataType = pkg.CleanMetadataType(unpacker.MetadataType)
switch p.MetadataType { typ, ok := pkg.MetadataTypeByName[p.MetadataType]
case "": if ok {
// there is no metadata, skip val := reflect.New(typ).Interface()
break if err := json.Unmarshal(unpacker.Metadata, val); err != nil {
case pkg.AlpmMetadataType:
var payload pkg.AlpmMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err return err
} }
p.Metadata = payload p.Metadata = reflect.ValueOf(val).Elem().Interface()
case pkg.ApkMetadataType: return nil
var payload pkg.ApkMetadata }
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
// capture unknown metadata as a generic struct
if len(unpacker.Metadata) > 0 {
var val interface{}
if err := json.Unmarshal(unpacker.Metadata, &val); err != nil {
return err return err
} }
p.Metadata = payload p.Metadata = val
case pkg.RpmMetadataType: }
var payload pkg.RpmMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil { if p.MetadataType != "" {
return err
}
p.Metadata = payload
case pkg.DpkgMetadataType:
var payload pkg.DpkgMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.JavaMetadataType:
var payload pkg.JavaMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.RustCargoPackageMetadataType:
var payload pkg.CargoPackageMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.GemMetadataType:
var payload pkg.GemMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.KbPackageMetadataType:
var payload pkg.KbPackageMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.PythonPackageMetadataType:
var payload pkg.PythonPackageMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.NpmPackageJSONMetadataType:
var payload pkg.NpmPackageJSONMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.PhpComposerJSONMetadataType:
var payload pkg.PhpComposerJSONMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.GolangBinMetadataType:
var payload pkg.GolangBinMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.DartPubMetadataType:
var payload pkg.DartPubMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.CocoapodsMetadataType:
var payload pkg.CocoapodsMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.ConanMetadataType:
var payload pkg.ConanMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.ConanLockMetadataType:
var payload pkg.ConanLockMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.DotnetDepsMetadataType:
var payload pkg.DotnetDepsMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.PortageMetadataType:
var payload pkg.PortageMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.HackageMetadataType:
var payload pkg.HackageMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
default:
return errUnknownMetadataType return errUnknownMetadataType
} }
return nil return nil
} }

View File

@ -2,6 +2,7 @@ package model
import ( import (
"encoding/json" "encoding/json"
"reflect"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -87,6 +88,7 @@ func Test_unpackMetadata(t *testing.T) {
name string name string
packageData []byte packageData []byte
metadataType pkg.MetadataType metadataType pkg.MetadataType
wantMetadata interface{}
wantErr require.ErrorAssertionFunc wantErr require.ErrorAssertionFunc
}{ }{
{ {
@ -196,6 +198,20 @@ func Test_unpackMetadata(t *testing.T) {
"metadataType": "BOGOSITY" "metadataType": "BOGOSITY"
}`), }`),
}, },
{
name: "unknown metadata type",
packageData: []byte(`{
"metadataType": "NewMetadataType",
"metadata": {
"thing": "thing-1"
}
}`),
wantErr: require.Error,
metadataType: "NewMetadataType",
wantMetadata: map[string]interface{}{
"thing": "thing-1",
},
},
} }
for _, test := range tests { for _, test := range tests {
@ -215,6 +231,10 @@ func Test_unpackMetadata(t *testing.T) {
err := unpackMetadata(p, unpacker) err := unpackMetadata(p, unpacker)
assert.Equal(t, test.metadataType, p.MetadataType) assert.Equal(t, test.metadataType, p.MetadataType)
test.wantErr(t, err) test.wantErr(t, err)
if test.wantMetadata != nil {
assert.True(t, reflect.DeepEqual(test.wantMetadata, p.Metadata))
}
}) })
} }
} }