mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 08:53:15 +01:00
Support encoding map types to CycloneDX properties (#1332)
This commit is contained in:
parent
5ed002e1a9
commit
f3528132a7
@ -85,6 +85,7 @@ func Sorted(values map[string]string) (out []NameValue) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//nolint:funlen
|
||||||
func encode(out map[string]string, value reflect.Value, prefix string, fn FieldName) {
|
func encode(out map[string]string, value reflect.Value, prefix string, fn FieldName) {
|
||||||
if !value.IsValid() || value.Type() == nil {
|
if !value.IsValid() || value.Type() == nil {
|
||||||
return
|
return
|
||||||
@ -130,6 +131,11 @@ func encode(out map[string]string, value reflect.Value, prefix string, fn FieldN
|
|||||||
}
|
}
|
||||||
encode(out, pv, name, fn)
|
encode(out, pv, name, fn)
|
||||||
}
|
}
|
||||||
|
case reflect.Map:
|
||||||
|
// currently only map[string]string is really supported
|
||||||
|
for _, key := range value.MapKeys() {
|
||||||
|
encode(out, value.MapIndex(key), fmt.Sprintf("%s:%v", prefix, key.Interface()), fn)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
log.Warnf("skipping encoding of unsupported property: %s", prefix)
|
log.Warnf("skipping encoding of unsupported property: %s", prefix)
|
||||||
}
|
}
|
||||||
@ -284,6 +290,55 @@ func decode(vals map[string]string, value reflect.Value, prefix string, fn Field
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
case reflect.Map:
|
||||||
|
values := false
|
||||||
|
keyType := typ.Key()
|
||||||
|
valueType := typ.Elem()
|
||||||
|
outMap := reflect.MakeMap(typ)
|
||||||
|
str := fmt.Sprintf("%s:", prefix)
|
||||||
|
keyVals := map[string]string{}
|
||||||
|
// iterate through all keys to find those prefixed with a reference to this map
|
||||||
|
// NOTE: this will not work for nested maps
|
||||||
|
for key := range vals {
|
||||||
|
// test for map prefix
|
||||||
|
if strings.HasPrefix(key, str) {
|
||||||
|
keyVals[key] = strings.TrimPrefix(key, str)
|
||||||
|
// create new placeholder and decode key
|
||||||
|
newKeyType := keyType
|
||||||
|
if keyType.Kind() == reflect.Ptr {
|
||||||
|
newKeyType = keyType.Elem()
|
||||||
|
}
|
||||||
|
k := reflect.New(newKeyType)
|
||||||
|
if !decode(keyVals, k.Elem(), key, fn) {
|
||||||
|
log.Debugf("unable to decode key for: %s", key)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if keyType.Kind() != reflect.Ptr {
|
||||||
|
k = k.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new placeholder and decode value
|
||||||
|
newValueType := valueType
|
||||||
|
if valueType.Kind() == reflect.Ptr {
|
||||||
|
newValueType = valueType.Elem()
|
||||||
|
}
|
||||||
|
v := reflect.New(newValueType)
|
||||||
|
if decode(vals, v.Elem(), key, fn) {
|
||||||
|
if valueType.Kind() != reflect.Ptr {
|
||||||
|
v = v.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
// set in map
|
||||||
|
outMap.SetMapIndex(k, v)
|
||||||
|
values = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if values {
|
||||||
|
value.Set(outMap)
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
values := false
|
values := false
|
||||||
for i := 0; i < typ.NumField(); i++ {
|
for i := 0; i < typ.NumField(); i++ {
|
||||||
|
|||||||
@ -37,6 +37,10 @@ type T4 struct {
|
|||||||
IntPtr *int
|
IntPtr *int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type T5 struct {
|
||||||
|
Map map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
func Test_EncodeDecodeCycle(t *testing.T) {
|
func Test_EncodeDecodeCycle(t *testing.T) {
|
||||||
val := 99
|
val := 99
|
||||||
|
|
||||||
@ -118,6 +122,15 @@ func Test_EncodeDecodeCycle(t *testing.T) {
|
|||||||
{"t2 elem 1"},
|
{"t2 elem 1"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "map of strings",
|
||||||
|
value: &T5{
|
||||||
|
Map: map[string]string{
|
||||||
|
"key1": "value1",
|
||||||
|
"key2": "value2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user