diff --git a/CHANGELOG.md b/CHANGELOG.md index f4c4426b..2575b80e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * `msgpack`: Now uses string encoding instead of float encoding for a whole number that is too large to fit in any of MessagePack's integer types. * `function/stdlib`: Type conversion functions (constructed with `MakeToFunc`) can now convert null values of unknown type into null values of the target type, rather than returning an unknown value in that case. +* `json`: Will now correctly reject attempts to encode `cty.DynamicVal`, whereas before it would just produce an invalid JSON document without any error. (This is invalid because JSON encoding cannot support unknown values at all; `cty.DynamicVal` is a special case of unknown value where even the _type_ isn't known.) # 1.14.3 (February 29, 2024) diff --git a/cty/json/marshal.go b/cty/json/marshal.go index 7a14ce81..07d9f331 100644 --- a/cty/json/marshal.go +++ b/cty/json/marshal.go @@ -12,6 +12,9 @@ func marshal(val cty.Value, t cty.Type, path cty.Path, b *bytes.Buffer) error { if val.IsMarked() { return path.NewErrorf("value has marks, so it cannot be serialized as JSON") } + if !val.IsKnown() { + return path.NewErrorf("value is not known") + } // If we're going to decode as DynamicPseudoType then we need to save // dynamic type information to recover the real type. @@ -24,10 +27,6 @@ func marshal(val cty.Value, t cty.Type, path cty.Path, b *bytes.Buffer) error { return nil } - if !val.IsKnown() { - return path.NewErrorf("value is not known") - } - // The caller should've guaranteed that the given val is conformant with // the given type t, so we'll proceed under that assumption here. @@ -185,7 +184,10 @@ func marshalDynamic(val cty.Value, path cty.Path, b *bytes.Buffer) error { return path.NewErrorf("failed to serialize type: %s", err) } b.WriteString(`{"value":`) - marshal(val, val.Type(), path, b) + err = marshal(val, val.Type(), path, b) + if err != nil { + return path.NewErrorf("failed to serialize value: %s", err) + } b.WriteString(`,"type":`) b.Write(typeJSON) b.WriteRune('}')