1
0
mirror of https://github.com/golang/go synced 2024-11-23 07:20:06 -07:00

encoding/json: Only allow string option for valid types

The "string" option only applies for strings, floats, integers, and
booleans as per the documentation. So when decoding ignore the "string"
option if the value is not of one of the types mentioned. This matches
the Marshal step which also ignores the "string" option for invalid
types.

Fixes #9812

Change-Id: I0fb2b43d0668bc0e2985886d989abbf2252070e2
Reviewed-on: https://go-review.googlesource.com/10183
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
Larz Conwell 2015-05-16 23:01:39 -04:00 committed by Russ Cox
parent e66d04ea59
commit 1a4e1770f6
2 changed files with 38 additions and 1 deletions

View File

@ -1393,3 +1393,27 @@ func TestInvalidUnmarshal(t *testing.T) {
}
}
}
// Test that string option is ignored for invalid types.
// Issue 9812.
func TestInvalidStringOption(t *testing.T) {
num := 0
item := struct {
T time.Time `json:",string"`
M map[string]string `json:",string"`
S []string `json:",string"`
A [1]string `json:",string"`
I interface{} `json:",string"`
P *int `json:",string"`
}{M: make(map[string]string), S: make([]string, 0), I: num, P: &num}
data, err := Marshal(item)
if err != nil {
t.Fatalf("Marshal: %v", err)
}
err = Unmarshal(data, &item)
if err != nil {
t.Fatalf("Unmarshal: %v", err)
}
}

View File

@ -1043,6 +1043,19 @@ func typeFields(t reflect.Type) []field {
ft = ft.Elem()
}
// Only strings, floats, integers, and booleans can be quoted.
quoted := false
if opts.Contains("string") {
switch ft.Kind() {
case reflect.Bool,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float32, reflect.Float64,
reflect.String:
quoted = true
}
}
// Record found field and index sequence.
if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
tagged := name != ""
@ -1055,7 +1068,7 @@ func typeFields(t reflect.Type) []field {
index: index,
typ: ft,
omitEmpty: opts.Contains("omitempty"),
quoted: opts.Contains("string"),
quoted: quoted,
}))
if count[f.typ] > 1 {
// If there were multiple instances, add a second,