Skip to content

Commit 54d12dd

Browse files
committed
feat(provider/util/jx): escape string values
json.Marshal implicitly escapes a small number of html-unsafe characters, which is _wrong_ but also valid and just the reality of the world
1 parent cbb2af1 commit 54d12dd

2 files changed

Lines changed: 74 additions & 1 deletion

File tree

internal/provider/util/jx.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ func EncodeJxRawMapOrdered(encoder *jx.Encoder, object map[string]jx.Raw) {
2121

2222
elem := object[k]
2323

24-
if len(elem) != 0 {
24+
dec := jx.DecodeBytes(elem)
25+
if str, err := dec.Str(); err == nil {
26+
encoder.StrEscape(str)
27+
} else {
2528
encoder.Raw(elem)
2629
}
2730
}

internal/provider/util/jx_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package util_test
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
7+
"github.com/cysp/terraform-provider-contentful/internal/provider/util"
8+
"github.com/go-faster/jx"
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestJsonMarshalEscaping(t *testing.T) {
13+
t.Parallel()
14+
15+
input := map[string]string{
16+
"a<b&c>d": "e<f&g>h",
17+
}
18+
19+
expected := []byte(`{"a\u003cb\u0026c\u003ed":"e\u003cf\u0026g\u003eh"}`)
20+
21+
actual, err := json.Marshal(input)
22+
23+
assert.Equal(t, expected, actual)
24+
assert.NoError(t, err)
25+
}
26+
27+
func TestEncodeJxRawMapOrdered(t *testing.T) {
28+
t.Parallel()
29+
30+
tests := map[string]struct {
31+
input map[string]jx.Raw
32+
expected string
33+
}{
34+
"empty": {
35+
input: map[string]jx.Raw{},
36+
expected: "{}",
37+
},
38+
"a=b": {
39+
input: map[string]jx.Raw{
40+
"a": jx.Raw(`"b"`),
41+
},
42+
expected: `{"a":"b"}`,
43+
},
44+
"a=2": {
45+
input: map[string]jx.Raw{
46+
"a": jx.Raw(`2`),
47+
},
48+
expected: `{"a":2}`,
49+
},
50+
"a<b&c>d=e<f&g>h": {
51+
input: map[string]jx.Raw{
52+
"a<b&c>d": jx.Raw(`"e<f&g>h"`),
53+
},
54+
// n.b. not applying escaping to keys, since i don't need that at this time
55+
expected: `{"a<b&c>d":"e\u003cf\u0026g\u003eh"}`,
56+
},
57+
}
58+
59+
for name, test := range tests {
60+
t.Run(name, func(t *testing.T) {
61+
t.Parallel()
62+
63+
encoder := jx.Encoder{}
64+
65+
util.EncodeJxRawMapOrdered(&encoder, test.input)
66+
67+
assert.Equal(t, test.expected, encoder.String())
68+
})
69+
}
70+
}

0 commit comments

Comments
 (0)