Skip to content

Commit 924958b

Browse files
author
Liam Cervante
authored
plan renderer: ensure JSON strings are completely JSON (#34959)
1 parent c1342f4 commit 924958b

File tree

3 files changed

+32
-12
lines changed

3 files changed

+32
-12
lines changed

internal/command/jsonformat/computed/renderers/renderer_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ null -> jsonencode(
111111
)
112112
`,
113113
},
114+
"primitive_create_fake_json": {
115+
diff: computed.Diff{
116+
Renderer: Primitive(nil, "[\"hello\"] and some more", cty.String),
117+
Action: plans.Create,
118+
},
119+
expected: `"[\"hello\"] and some more"`,
120+
},
114121
"primitive_create_null_string": {
115122
diff: computed.Diff{
116123
Renderer: Primitive(nil, nil, cty.String),

internal/command/jsonformat/computed/renderers/string.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
package renderers
55

66
import (
7-
"encoding/json"
87
"fmt"
98
"strings"
109

1110
"github.com/hashicorp/terraform/internal/command/jsonformat/computed"
11+
"github.com/hashicorp/terraform/internal/command/jsonformat/structured"
1212
)
1313

1414
type evaluatedString struct {
@@ -30,12 +30,8 @@ func evaluatePrimitiveString(value interface{}, opts computed.RenderHumanOpts) e
3030
str := value.(string)
3131

3232
if strings.HasPrefix(str, "{") || strings.HasPrefix(str, "[") {
33-
34-
decoder := json.NewDecoder(strings.NewReader(str))
35-
decoder.UseNumber()
36-
37-
var jv interface{}
38-
if err := decoder.Decode(&jv); err == nil {
33+
jv, err := structured.ParseJson(strings.NewReader(str))
34+
if err == nil {
3935
return evaluatedString{
4036
String: str,
4137
Json: jv,

internal/command/jsonformat/structured/change.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ package structured
66
import (
77
"bytes"
88
"encoding/json"
9+
"fmt"
10+
"io"
911
"reflect"
1012

1113
"github.com/hashicorp/terraform/internal/command/jsonformat/structured/attribute_path"
@@ -282,11 +284,8 @@ func unmarshalGeneric(raw json.RawMessage) interface{} {
282284
return nil
283285
}
284286

285-
decoder := json.NewDecoder(bytes.NewReader(raw))
286-
decoder.UseNumber() // We support very big (> 2^64) numbers.
287-
288-
var out interface{}
289-
if err := decoder.Decode(&out); err != nil {
287+
out, err := ParseJson(bytes.NewReader(raw))
288+
if err != nil {
290289
panic("unrecognized json type: " + err.Error())
291290
}
292291
return out
@@ -299,3 +298,21 @@ func unwrapAttributeValues(values jsonstate.AttributeValues) map[string]interfac
299298
}
300299
return out
301300
}
301+
302+
func ParseJson(reader io.Reader) (interface{}, error) {
303+
decoder := json.NewDecoder(reader)
304+
decoder.UseNumber()
305+
306+
var jv interface{}
307+
if err := decoder.Decode(&jv); err != nil {
308+
return nil, err
309+
}
310+
311+
// The JSON decoder should have consumed the entire input stream, so
312+
// we should be at EOF now.
313+
if token, err := decoder.Token(); err != io.EOF {
314+
return nil, fmt.Errorf("unexpected token after valid JSON: %v", token)
315+
}
316+
317+
return jv, nil
318+
}

0 commit comments

Comments
 (0)