1
0
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:
Russ Cox 2013-01-29 13:34:18 -08:00
parent ec1948a44d
commit ad37081b67
3 changed files with 55 additions and 21 deletions

View File

@ -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)
}
}
}

View File

@ -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.

View File

@ -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 {