Skip to content

Commit

Permalink
fix: Decode binary and unknown metadata (#1307)
Browse files Browse the repository at this point in the history
  • Loading branch information
kzantow authored Nov 1, 2022
1 parent ba57f3d commit 95c7378
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 116 deletions.
134 changes: 18 additions & 116 deletions syft/formats/syftjson/model/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"reflect"

"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/pkg"
Expand Down Expand Up @@ -71,130 +72,31 @@ func (p *Package) UnmarshalJSON(b []byte) error {
return err
}

//nolint:funlen,gocognit,gocyclo
func unpackMetadata(p *Package, unpacker packageMetadataUnpacker) error {
p.MetadataType = pkg.CleanMetadataType(unpacker.MetadataType)

switch p.MetadataType {
case "":
// there is no metadata, skip
break
case pkg.AlpmMetadataType:
var payload pkg.AlpmMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
typ, ok := pkg.MetadataTypeByName[p.MetadataType]
if ok {
val := reflect.New(typ).Interface()
if err := json.Unmarshal(unpacker.Metadata, val); err != nil {
return err
}
p.Metadata = payload
case pkg.ApkMetadataType:
var payload pkg.ApkMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
return err
}
p.Metadata = payload
case pkg.RpmMetadataType:
var payload pkg.RpmMetadata
if err := json.Unmarshal(unpacker.Metadata, &payload); err != nil {
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 {
p.Metadata = reflect.ValueOf(val).Elem().Interface()
return 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
}
p.Metadata = payload
default:
p.Metadata = val
}

if p.MetadataType != "" {
return errUnknownMetadataType
}

return nil
}
20 changes: 20 additions & 0 deletions syft/formats/syftjson/model/package_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package model

import (
"encoding/json"
"reflect"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -87,6 +88,7 @@ func Test_unpackMetadata(t *testing.T) {
name string
packageData []byte
metadataType pkg.MetadataType
wantMetadata interface{}
wantErr require.ErrorAssertionFunc
}{
{
Expand Down Expand Up @@ -196,6 +198,20 @@ func Test_unpackMetadata(t *testing.T) {
"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 {
Expand All @@ -215,6 +231,10 @@ func Test_unpackMetadata(t *testing.T) {
err := unpackMetadata(p, unpacker)
assert.Equal(t, test.metadataType, p.MetadataType)
test.wantErr(t, err)

if test.wantMetadata != nil {
assert.True(t, reflect.DeepEqual(test.wantMetadata, p.Metadata))
}
})
}
}

0 comments on commit 95c7378

Please sign in to comment.