mirror of
https://github.com/golang/go
synced 2024-11-18 15:54:42 -07:00
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
This commit is contained in:
parent
ec1948a44d
commit
ad37081b67
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user