Skip to content

Commit

Permalink
util/Unmarshal: if it's JSON, skip YAMLtoJSON (#4681)
Browse files Browse the repository at this point in the history
This helper accepts JSON or YAML, and used to do this:

1. For YAML input, yaml.YAMLToJSON would parse it as yaml, marshal it to
   JSON, and pass that back out to be passed to UnmarshalJSON
2. For JSON input, yaml.YAMLToJSON would also parse it as yaml, marshal it
   to JSON, and pass that back out to UnmarshalJSON

Issue #4673 has shown that the theoretical "superset" propery of YAML doesn't
seem to hold in all cases.

So now, we'll do this:

1. For YAML input, yaml.YAMLToJSON would parse it as yaml, marshal it to
   JSON, and pass that back out to be passed to UnmarshalJSON
2. For JSON input, json.Valid will determine that it's JSON, and we'll
   feed it into UnmarshalJSON as-is.

The YAML path (1.) still seems suboptimal, but I also suspect that JSON is
more common. Also, this change shouldn't make the YAML path much worse:
determining that yaml string isn't valid JSON should be quick.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
  • Loading branch information
srenatus committed May 12, 2022
1 parent 9674f8c commit 61b8c14
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 0 deletions.
3 changes: 3 additions & 0 deletions util/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ func Reference(x interface{}) *interface{} {

// Unmarshal decodes a YAML or JSON value into the specified type.
func Unmarshal(bs []byte, v interface{}) error {
if json.Valid(bs) {
return UnmarshalJSON(bs, v)
}
bs, err := yaml.YAMLToJSON(bs)
if err != nil {
return err
Expand Down
10 changes: 10 additions & 0 deletions util/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,13 @@ func TestReference(t *testing.T) {
})
}
}

// There's valid JSON that doesn't pass through yaml.YAMLToJSON.
// See https://github.com/open-policy-agent/opa/issues/4673
func TestInvalidYAMLValidJSON(t *testing.T) {
x := []byte{0x22, 0x3a, 0xc2, 0x9a, 0x22}
y := ""
if err := util.Unmarshal(x, &y); err != nil {
t.Fatal(err)
}
}

0 comments on commit 61b8c14

Please sign in to comment.