From: Russ Cox Date: Tue, 29 Jan 2013 21:34:18 +0000 (-0800) Subject: encoding/json: add test for Unmarshal of malformed data X-Git-Tag: go1.1rc2~1259 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=ad37081b672a22f573f91aca7a5828e2c9718314;p=gostls13.git encoding/json: add test for Unmarshal of malformed data Roll back CL making primitive type unmarshal faster, because it broke the Unmarshal of malformed data. Add benchmarks for unmarshal of primitive types. Update #3949. R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/7228061 --- diff --git a/src/pkg/encoding/json/bench_test.go b/src/pkg/encoding/json/bench_test.go index 333c1c0ce9..29dbc26d41 100644 --- a/src/pkg/encoding/json/bench_test.go +++ b/src/pkg/encoding/json/bench_test.go @@ -153,5 +153,37 @@ func BenchmarkCodeUnmarshalReuse(b *testing.B) { b.Fatal("Unmmarshal:", err) } } - b.SetBytes(int64(len(codeJSON))) +} + +func BenchmarkUnmarshalString(b *testing.B) { + data := []byte(`"hello, world"`) + var s string + + for i := 0; i < b.N; i++ { + if err := Unmarshal(data, &s); err != nil { + b.Fatal("Unmarshal:", err) + } + } +} + +func BenchmarkUnmarshalFloat64(b *testing.B) { + var f float64 + data := []byte(`3.14`) + + for i := 0; i < b.N; i++ { + if err := Unmarshal(data, &f); err != nil { + b.Fatal("Unmarshal:", err) + } + } +} + +func BenchmarkUnmarshalInt64(b *testing.B) { + var x int64 + data := []byte(`3`) + + for i := 0; i < b.N; i++ { + if err := Unmarshal(data, &x); err != nil { + b.Fatal("Unmarshal:", err) + } + } } diff --git a/src/pkg/encoding/json/decode.go b/src/pkg/encoding/json/decode.go index 6e6815ff13..95e9120918 100644 --- a/src/pkg/encoding/json/decode.go +++ b/src/pkg/encoding/json/decode.go @@ -52,25 +52,6 @@ import ( // an UnmarshalTypeError describing the earliest such error. // func Unmarshal(data []byte, v interface{}) error { - - // skip heavy processing for primitive values - var first byte - var i int - for i, first = range data { - if !isSpace(rune(first)) { - break - } - } - if first != '{' && first != '[' { - rv := reflect.ValueOf(v) - if rv.Kind() != reflect.Ptr || rv.IsNil() { - return &InvalidUnmarshalError{reflect.TypeOf(v)} - } - var d decodeState - d.literalStore(data[i:], rv.Elem(), false) - return d.savedError - } - d := new(decodeState).init(data) // Quick check for well-formedness. diff --git a/src/pkg/encoding/json/decode_test.go b/src/pkg/encoding/json/decode_test.go index 97f2a41eb7..a91c6da01d 100644 --- a/src/pkg/encoding/json/decode_test.go +++ b/src/pkg/encoding/json/decode_test.go @@ -1059,12 +1059,33 @@ func TestUnmarshalTypeError(t *testing.T) { for _, item := range decodeTypeErrorTests { err := Unmarshal([]byte(item.src), item.dest) if _, ok := err.(*UnmarshalTypeError); !ok { - t.Errorf("expected type error for Unmarshal(%q, type %T): got %v instead", + t.Errorf("expected type error for Unmarshal(%q, type %T): got %T", item.src, item.dest, err) } } } +var unmarshalSyntaxTests = []string{ + "tru", + "fals", + "nul", + "123e", + `"hello`, + `[1,2,3`, + `{"key":1`, + `{"key":1,`, +} + +func TestUnmarshalSyntax(t *testing.T) { + var x interface{} + for _, src := range unmarshalSyntaxTests { + err := Unmarshal([]byte(src), &x) + if _, ok := err.(*SyntaxError); !ok { + t.Errorf("expected syntax error for Unmarshal(%q): got %T", src, err) + } + } +} + // Test handling of unexported fields that should be ignored. // Issue 4660 type unexportedFields struct {