]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: roll back Unmarshal optimization + test
authorRuss Cox <rsc@golang.org>
Thu, 14 Feb 2013 19:46:15 +0000 (14:46 -0500)
committerRuss Cox <rsc@golang.org>
Thu, 14 Feb 2013 19:46:15 +0000 (14:46 -0500)
The second attempt at the Unmarshal optimization allowed
panics to get out of the json package. Add test for that bug
and remove the optimization.

Let's stop trying to optimize Unmarshal.

Fixes #4784.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/7300108

src/pkg/encoding/json/decode.go
src/pkg/encoding/json/decode_test.go

index 1d723af12b5b9e4f7e57c5b2559c66add8434f02..ffe9d77b7ab112fe6168ca48bb462c5b810f23b1 100644 (file)
@@ -56,8 +56,7 @@ import (
 // an UnmarshalTypeError describing the earliest such error.
 //
 func Unmarshal(data []byte, v interface{}) error {
-
-       // Quick check for well-formedness.
+       // Check for well-formedness.
        // Avoids filling out half a data structure
        // before discovering a JSON syntax error.
        var d decodeState
@@ -66,23 +65,6 @@ func Unmarshal(data []byte, v interface{}) error {
                return err
        }
 
-       // skip heavy processing for primitive values
-       var first byte
-       var i int
-       for i, first = range data {
-               if first > ' ' || !isSpace(rune(first)) {
-                       break
-               }
-       }
-       if first != '{' && first != '[' {
-               rv := reflect.ValueOf(v)
-               if rv.Kind() != reflect.Ptr || rv.IsNil() {
-                       return &InvalidUnmarshalError{reflect.TypeOf(v)}
-               }
-               d.literalStore(data[i:], rv.Elem(), false)
-               return d.savedError
-       }
-
        d.init(data)
        return d.unmarshal(v)
 }
index b65687e4a405cca2eba4612961c50dfd0308f2d4..524a9989fe74743b76bd09d317f0ffbd7475ec12 100644 (file)
@@ -11,6 +11,7 @@ import (
        "reflect"
        "strings"
        "testing"
+       "time"
 )
 
 type T struct {
@@ -1113,3 +1114,30 @@ func TestUnmarshalUnexported(t *testing.T) {
                t.Errorf("got %q, want %q", out, want)
        }
 }
+
+// Time3339 is a time.Time which encodes to and from JSON
+// as an RFC 3339 time in UTC.
+type Time3339 time.Time
+
+func (t *Time3339) UnmarshalJSON(b []byte) error {
+       if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' {
+               return fmt.Errorf("types: failed to unmarshal non-string value %q as an RFC 3339 time")
+       }
+       tm, err := time.Parse(time.RFC3339, string(b[1:len(b)-1]))
+       if err != nil {
+               return err
+       }
+       *t = Time3339(tm)
+       return nil
+}
+
+func TestUnmarshalJSONLiteralError(t *testing.T) {
+       var t3 Time3339
+       err := Unmarshal([]byte(`"0000-00-00T00:00:00Z"`), &t3)
+       if err == nil {
+               t.Fatalf("expected error; got time %v", time.Time(t3))
+       }
+       if !strings.Contains(err.Error(), "range") {
+               t.Errorf("got err = %v; want out of range error", err)
+       }
+}