internal: fix unmarshalling attestation version numbers from JSON (#2187)

* Fix unmarshalling attestation version numbers from JSON

* Add unit test for UnmarshalJSON

---------

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
Daniel Weiße 2023-08-09 15:11:14 +02:00 committed by GitHub
parent 656cdbb4bb
commit c9cae643e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 154 additions and 53 deletions

View file

@ -58,15 +58,24 @@ func (v AttestationVersion) MarshalJSON() ([]byte, error) {
// UnmarshalJSON implements a custom unmarshaller to resolve "latest" values.
func (v *AttestationVersion) UnmarshalJSON(data []byte) (err error) {
var rawUnmarshal string
if err := json.Unmarshal(data, &rawUnmarshal); err != nil {
return fmt.Errorf("raw unmarshal: %w", err)
// JSON has two distinct ways to represent numbers and strings.
// This means we cannot simply unmarshal to string, like with YAML.
// Unmarshalling to `any` causes Go to unmarshal numbers to float64.
// Therefore, try to unmarshal to string, and then to int, instead of using type assertions.
var unmarshalString string
if err := json.Unmarshal(data, &unmarshalString); err != nil {
var unmarshalInt int64
if err := json.Unmarshal(data, &unmarshalInt); err != nil {
return fmt.Errorf("unable to unmarshal to string or int: %w", err)
}
unmarshalString = strconv.FormatInt(unmarshalInt, 10)
}
return v.parseRawUnmarshal(rawUnmarshal)
return v.parseRawUnmarshal(unmarshalString)
}
func (v *AttestationVersion) parseRawUnmarshal(str string) error {
if strings.HasPrefix(str, "0") {
if strings.HasPrefix(str, "0") && len(str) != 1 {
return fmt.Errorf("no format with prefixed 0 (octal, hexadecimal) allowed: %s", str)
}
if strings.ToLower(str) == "latest" {