]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: Only allow string option for valid types
authorLarz Conwell <larzconwell@gmail.com>
Sun, 17 May 2015 03:01:39 +0000 (23:01 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 15 Jul 2015 01:35:56 +0000 (01:35 +0000)
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>
src/encoding/json/decode_test.go
src/encoding/json/encode.go

index f208ee8a7cac5425455899aeb74dba8589300596..4834c062ccca2b415086aef7a754d75a82164f8c 100644 (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)
+       }
+}
index 08bb67134e9843fefe01abe8149439040b70e383..90782deb70be7aedbcc837d5427a201bb7ff35da 100644 (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,