Fix: unmarshal key values in Java, Go, and Conan metadata (#2603)

Previously, Syft represented several metadata fields as map[string]string,
however this representation erased ordering, so Syft now represents these values
as []KeyValue. Add custom unmarshaling so that JSON that was written by
older versions of Syft using the map[string]string representation can be parsed
into the new []KeyValue representation.

Signed-off-by: Will Murphy <will.murphy@anchore.com>
This commit is contained in:
William Murphy
2024-02-07 11:26:23 -05:00
committed by GitHub
parent bbd34f61fd
commit ce67927a98
5 changed files with 340 additions and 1 deletions
+42
View File
@@ -1,5 +1,11 @@
package pkg
import (
"encoding/json"
"fmt"
"sort"
)
type KeyValue struct {
Key string `json:"key"`
Value string `json:"value"`
@@ -26,3 +32,39 @@ func (k KeyValues) MustGet(key string) string {
return ""
}
func keyValuesFromMap(m map[string]string) KeyValues {
var result KeyValues
var mapKeys []string
for k := range m {
mapKeys = append(mapKeys, k)
}
sort.Strings(mapKeys)
for _, k := range mapKeys {
result = append(result, KeyValue{
Key: k,
Value: m[k],
})
}
return result
}
func (k *KeyValues) UnmarshalJSON(b []byte) error {
var kvs []KeyValue
if err := json.Unmarshal(b, &kvs); err != nil {
var legacyMap map[string]string
if err := json.Unmarshal(b, &legacyMap); err != nil {
return fmt.Errorf("unable to unmarshal KeyValues: %w", err)
}
var keys []string
for k := range legacyMap {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
kvs = append(kvs, KeyValue{Key: k, Value: legacyMap[k]})
}
}
*k = kvs
return nil
}