Skip to content

Commit

Permalink
Merge pull request #891 from WnP/json-no-escape-html
Browse files Browse the repository at this point in the history
Add an optional boolean to not escape html during json encoding
  • Loading branch information
joaopapereira authored Mar 13, 2024
2 parents 6d2001d + cc432b6 commit 6cad190
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 12 deletions.
5 changes: 3 additions & 2 deletions pkg/template/core/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import (
"github.com/k14s/starlark-go/starlark"
)

func BoolArg(kwargs []starlark.Tuple, keyToFind string) (bool, error) {
// BoolArg return a boolean value from starlark.Tupe based on a given key, defaults to defaultValue.
func BoolArg(kwargs []starlark.Tuple, keyToFind string, defaultValue bool) (bool, error) {
for _, arg := range kwargs {
key, err := NewStarlarkValue(arg.Index(0)).AsString()
if err != nil {
Expand All @@ -19,7 +20,7 @@ func BoolArg(kwargs []starlark.Tuple, keyToFind string) (bool, error) {
return NewStarlarkValue(arg.Index(1)).AsBool()
}
}
return false, nil
return defaultValue, nil
}

func Int64Arg(kwargs []starlark.Tuple, keyToFind string) (int64, error) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/workspace/library_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func (l *libraryValue) WithDataValues(thread *starlark.Thread, f *starlark.Built
return starlark.None, err
}

usePlainMerge, err := core.BoolArg(kwargs, "plain")
usePlainMerge, err := core.BoolArg(kwargs, "plain", false)
if err != nil {
return starlark.None, err
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/yamltemplate/filetests/ytt-library/json.tpltest
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ encode:
indent:
test1: #@ json.encode({"a": [1,2,3,{"c":456}], "b": "str"}, indent=4)
test2: #@ json.encode({"a": [1,2,3,{"c":456}], "b": "str"}, indent=0)
escape_html:
test1: #@ json.encode({"a": "<123>"})
test2: #@ json.encode({"a": "<123>"}, escape_html=False)
decode:
test1: #@ json.decode("{}")
test2: #@ json.decode('{"a":[1,2,3,{"c":456}],"b":"str"}')
Expand All @@ -40,6 +43,9 @@ encode:
"b": "str"
}
test2: '{"a":[1,2,3,{"c":456}],"b":"str"}'
escape_html:
test1: '{"a":"\u003c123\u003e"}'
test2: '{"a":"<123>"}'
decode:
test1: {}
test2:
Expand Down
6 changes: 3 additions & 3 deletions pkg/yttlibrary/base64.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,23 +70,23 @@ func (b base64Module) Decode(thread *starlark.Thread, f *starlark.Builtin, args
func (b base64Module) buildEncoding(kwargs []starlark.Tuple) (*base64.Encoding, error) {
var encoding *base64.Encoding = base64.StdEncoding

isURL, err := core.BoolArg(kwargs, "url")
isURL, err := core.BoolArg(kwargs, "url", false)
if err != nil {
return nil, err
}
if isURL {
encoding = base64.URLEncoding
}

isRaw, err := core.BoolArg(kwargs, "raw")
isRaw, err := core.BoolArg(kwargs, "raw", false)
if err != nil {
return nil, err
}
if isRaw {
encoding = encoding.WithPadding(base64.NoPadding)
}

isStrict, err := core.BoolArg(kwargs, "strict")
isStrict, err := core.BoolArg(kwargs, "strict", false)
if err != nil {
return nil, err
}
Expand Down
21 changes: 15 additions & 6 deletions pkg/yttlibrary/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package yttlibrary

import (
"bytes"
"encoding/json"
"fmt"
"strings"
Expand Down Expand Up @@ -37,6 +38,7 @@ func (b jsonModule) Encode(thread *starlark.Thread, f *starlark.Builtin, args st
}
allowedKWArgs := map[string]struct{}{
"indent": {},
"escape_html": {},
}
if err := core.CheckArgNames(kwargs, allowedKWArgs); err != nil {
return starlark.None, err
Expand All @@ -49,26 +51,33 @@ func (b jsonModule) Encode(thread *starlark.Thread, f *starlark.Builtin, args st
val = orderedmap.Conversion{yamlmeta.NewGoFromAST(val)}.AsUnorderedStringMaps()

var valBs []byte
buffer := bytes.NewBuffer(valBs)
indent, err := core.Int64Arg(kwargs, "indent")
if err != nil {
return starlark.None, err
}

if indent < 0 || indent > 8 {
// mitigate https://cwe.mitre.org/data/definitions/409.html
return starlark.None, fmt.Errorf("indent value must be between 0 and 8")
}

escapeHTML, err := core.BoolArg(kwargs, "escape_html", true)
if err != nil {
return starlark.None, err
}

encoder := json.NewEncoder(buffer)
if indent > 0 {
valBs, err = json.MarshalIndent(val, "", strings.Repeat(" ", int(indent)))
} else {
valBs, err = json.Marshal(val)
encoder.SetIndent("", strings.Repeat(" ", int(indent)))
}
if err != nil {
encoder.SetEscapeHTML(escapeHTML)

if err := encoder.Encode(val); err != nil {
return starlark.None, err
}

return starlark.String(string(valBs)), nil
res := strings.TrimSuffix(buffer.String(), "\n")
return starlark.String(res), nil
}

// Decode is a core.StarlarkFunc that parses the provided input from JSON format into dicts, lists, and scalars
Expand Down

0 comments on commit 6cad190

Please sign in to comment.