Skip to content

Commit

Permalink
🐛 fix json escaping (#2570)
Browse files Browse the repository at this point in the history
* fix json escaping

Signed-off-by: Ivan Milchev <ivan@mondoo.com>

* add tests

Signed-off-by: Ivan Milchev <ivan@mondoo.com>

---------

Signed-off-by: Ivan Milchev <ivan@mondoo.com>
  • Loading branch information
imilchev authored Nov 14, 2023
1 parent bbd6ecd commit c17370d
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 15 deletions.
69 changes: 55 additions & 14 deletions llx/rawdata_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,12 @@ func float2json(f float64) string {
}

// Takes care of escaping the given string
func string2json(s string) string {
return fmt.Sprintf("%#v", s)
func string2json(s string) (string, error) {
b, err := json.Marshal(s)
if err != nil {
return "", err
}
return string(b), nil
}

func label(ref string, bundle *CodeBundle, isResource bool) string {
Expand Down Expand Up @@ -96,7 +100,11 @@ func refMapJSON(typ types.Type, data map[string]interface{}, codeID string, bund
for i, k := range keys {
v := data[k]
label := label(k, bundle, true)
buf.WriteString(string2json(label))
str, err := string2json(label)
if err != nil {
return err
}
buf.WriteString(str)
buf.WriteString(":")

val := v.(*RawData)
Expand Down Expand Up @@ -134,7 +142,11 @@ func rawDictJSON(typ types.Type, raw interface{}, buf *bytes.Buffer) error {
return nil

case string:
buf.WriteString(string2json(data))
str, err := string2json(data)
if err != nil {
return err
}
buf.WriteString(str)
return nil

case time.Time:
Expand Down Expand Up @@ -167,7 +179,11 @@ func rawDictJSON(typ types.Type, raw interface{}, buf *bytes.Buffer) error {
last := len(keys) - 1
for i, k := range keys {
v := data[k]
buf.WriteString(string2json(k) + ":")
str, err := string2json(k)
if err != nil {
return err
}
buf.WriteString(str + ":")

if v == nil {
buf.WriteString("null")
Expand Down Expand Up @@ -222,9 +238,12 @@ func rawStringMapJSON(typ types.Type, data map[string]interface{}, codeID string
childType := typ.Child()
keys := sortx.Keys(data)

var err error
for i, key := range keys {
buf.WriteString(string2json(key) + ":")
str, err := string2json(key)
if err != nil {
return err
}
buf.WriteString(str + ":")

err = rawDataJSON(childType, data[key], codeID, bundle, buf)
if err != nil {
Expand All @@ -250,9 +269,12 @@ func rawIntMapJSON(typ types.Type, data map[int]interface{}, codeID string, bund
keys := intKeys(data)
sort.Ints(keys)

var err error
for i, key := range keys {
buf.WriteString(string2json(strconv.Itoa(key)) + ":")
str, err := string2json(strconv.Itoa(key))
if err != nil {
return err
}
buf.WriteString(str + ":")

err = rawDataJSON(childType, data[key], codeID, bundle, buf)
if err != nil {
Expand Down Expand Up @@ -324,11 +346,18 @@ func rawDataJSON(typ types.Type, data interface{}, codeID string, bundle *CodeBu
return nil

case types.String:
buf.WriteString(string2json(data.(string)))
str, err := string2json(data.(string))
if err != nil {
return err
}
buf.WriteString(str)
return nil

case types.Regex:
raw := string2json(data.(string))
raw, err := string2json(data.(string))
if err != nil {
return err
}
buf.WriteByte(raw[0])
buf.WriteByte('/')
buf.WriteString(raw[1 : len(raw)-1])
Expand Down Expand Up @@ -383,7 +412,11 @@ func rawDataJSON(typ types.Type, data interface{}, codeID string, bundle *CodeBu
idline += " id = " + id
}

buf.WriteString(string2json(idline))
str, err := string2json(idline)
if err != nil {
return err
}
buf.WriteString(str)
return nil

default:
Expand All @@ -394,7 +427,11 @@ func rawDataJSON(typ types.Type, data interface{}, codeID string, bundle *CodeBu
}

func JSONerror(err error) []byte {
return []byte("{\"error\":" + string2json(err.Error()) + "}")
str, err := string2json(err.Error())
if err != nil {
return []byte("{\"error\":\"" + err.Error() + "\"}")
}
return []byte("{\"error\":" + str + "}")
}

func (r *RawData) JSON(codeID string, bundle *CodeBundle) []byte {
Expand All @@ -412,5 +449,9 @@ func (r *RawData) JSON(codeID string, bundle *CodeBundle) []byte {
func (r *RawData) JSONfield(codeID string, bundle *CodeBundle) []byte {
label := label(codeID, bundle, true)
value := r.JSON(codeID, bundle)
return []byte(string2json(label) + ":" + string(value))
str, err := string2json(label)
if err != nil {
return JSONerror(err)
}
return []byte(str + ":" + string(value))
}
9 changes: 8 additions & 1 deletion llx/rawdata_json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,14 @@ func TestRawDataJson_removeUnderscoreKeys(t *testing.T) {
func TestRawDataJson_nevertime(t *testing.T) {
never := NeverPastTime
var res bytes.Buffer
rawDataJSON(types.Time, &never, "blfbjef", &CodeBundle{}, &res)
require.NoError(t, rawDataJSON(types.Time, &never, "blfbjef", &CodeBundle{}, &res))
require.Equal(t, res.String(), "\"Never\"")
require.True(t, json.Valid(res.Bytes()))
}

func TestRawDataJson_Umlauts(t *testing.T) {
var res bytes.Buffer
require.NoError(t, rawDataJSON(types.String, "Systemintegrit\x84t", "blfbjef", &CodeBundle{}, &res))
require.Equal(t, res.String(), "\"Systemintegrit\\ufffdt\"")
require.True(t, json.Valid(res.Bytes()))
}

0 comments on commit c17370d

Please sign in to comment.