mirror of
https://github.com/anchore/syft.git
synced 2026-11-02 15:36:41 +01:00
Remove MetadataType from core package object and normalize JSON metadataType values (#1983)
* [wip] Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * distinct the package metadata functions Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * remove metadata type from package core model Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * incorporate review feedback for names Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add RPM archive metadata and split parser helpers Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * clarify the python package metadata type Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * rename the KB metadata type Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * break hackage and composer types by use case Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * linting fix Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix encoding and decoding for syft-json and cyclonedx Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * bump json schema to 11 Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * update cyclonedx-json snapshots Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * update cyclonedx-xml snapshots Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * update spdx-json snapshots Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * update spdx-tv snapshots Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * update syft-json snapshots Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * correct metadata type in stack yaml parser test Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix bom-ref redactor for cyclonedx-xml Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add tests for legacy package metadata names Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * regenerate json schema v11 Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix legacy HackageMetadataType reflect type value check Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix linting Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * packagemetadata discovery should account for type shadowing Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix linting Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix cli tests Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * bump json schema version to v12 Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * update json schema to incorporate changes from main Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add syft-json legacy config option Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add tests around v11-v12 json decoding Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add docs for SYFT_JSON_LEGACY Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * rename structs to be compliant with new naming scheme Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
+115
@@ -0,0 +1,115 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/scylladb/go-set/strset"
|
||||
|
||||
"github.com/anchore/syft/syft/file"
|
||||
)
|
||||
|
||||
const ApkDBGlob = "**/lib/apk/db/installed"
|
||||
|
||||
var _ FileOwner = (*ApkDBEntry)(nil)
|
||||
|
||||
// ApkDBEntry represents all captured data for the alpine linux package manager flat-file store.
|
||||
// See the following sources for more information:
|
||||
// - https://wiki.alpinelinux.org/wiki/Apk_spec
|
||||
// - https://git.alpinelinux.org/apk-tools/tree/src/package.c
|
||||
// - https://git.alpinelinux.org/apk-tools/tree/src/database.c
|
||||
type ApkDBEntry struct {
|
||||
Package string `mapstructure:"P" json:"package"`
|
||||
OriginPackage string `mapstructure:"o" json:"originPackage" cyclonedx:"originPackage"`
|
||||
Maintainer string `mapstructure:"m" json:"maintainer"`
|
||||
Version string `mapstructure:"V" json:"version"`
|
||||
Architecture string `mapstructure:"A" json:"architecture"`
|
||||
URL string `mapstructure:"U" json:"url"`
|
||||
Description string `mapstructure:"T" json:"description"`
|
||||
Size int `mapstructure:"S" json:"size" cyclonedx:"size"`
|
||||
InstalledSize int `mapstructure:"I" json:"installedSize" cyclonedx:"installedSize"`
|
||||
Dependencies []string `mapstructure:"D" json:"pullDependencies" cyclonedx:"pullDependencies"`
|
||||
Provides []string `mapstructure:"p" json:"provides" cyclonedx:"provides"`
|
||||
Checksum string `mapstructure:"C" json:"pullChecksum" cyclonedx:"pullChecksum"`
|
||||
GitCommit string `mapstructure:"c" json:"gitCommitOfApkPort" cyclonedx:"gitCommitOfApkPort"`
|
||||
Files []ApkFileRecord `json:"files"`
|
||||
}
|
||||
|
||||
type spaceDelimitedStringSlice []string
|
||||
|
||||
func (m *ApkDBEntry) UnmarshalJSON(data []byte) error {
|
||||
var fields []reflect.StructField
|
||||
t := reflect.TypeOf(ApkDBEntry{})
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
if f.Name == "Dependencies" {
|
||||
f.Type = reflect.TypeOf(spaceDelimitedStringSlice{})
|
||||
}
|
||||
fields = append(fields, f)
|
||||
}
|
||||
apkMetadata := reflect.StructOf(fields)
|
||||
inst := reflect.New(apkMetadata)
|
||||
if err := json.Unmarshal(data, inst.Interface()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return mapstructure.Decode(inst.Elem().Interface(), m)
|
||||
}
|
||||
|
||||
func (a *spaceDelimitedStringSlice) UnmarshalJSON(data []byte) error {
|
||||
var jsonObj interface{}
|
||||
|
||||
if err := json.Unmarshal(data, &jsonObj); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch obj := jsonObj.(type) {
|
||||
case string:
|
||||
if obj == "" {
|
||||
*a = nil
|
||||
} else {
|
||||
*a = strings.Split(obj, " ")
|
||||
}
|
||||
return nil
|
||||
case []interface{}:
|
||||
s := make([]string, 0, len(obj))
|
||||
for _, v := range obj {
|
||||
value, ok := v.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid type for string array element: %T", v)
|
||||
}
|
||||
s = append(s, value)
|
||||
}
|
||||
*a = s
|
||||
return nil
|
||||
case nil:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("invalid type for string array: %T", obj)
|
||||
}
|
||||
}
|
||||
|
||||
// ApkFileRecord represents a single file listing and metadata from a APK DB entry (which may have many of these file records).
|
||||
type ApkFileRecord struct {
|
||||
Path string `json:"path"`
|
||||
OwnerUID string `json:"ownerUid,omitempty"`
|
||||
OwnerGID string `json:"ownerGid,omitempty"`
|
||||
Permissions string `json:"permissions,omitempty"`
|
||||
Digest *file.Digest `json:"digest,omitempty"`
|
||||
}
|
||||
|
||||
func (m ApkDBEntry) OwnedFiles() (result []string) {
|
||||
s := strset.New()
|
||||
for _, f := range m.Files {
|
||||
if f.Path != "" {
|
||||
s.Add(f.Path)
|
||||
}
|
||||
}
|
||||
result = s.List()
|
||||
sort.Strings(result)
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user