diff options
| author | Keith Randall <khr@golang.org> | 2015-05-28 13:49:20 -0700 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2015-05-28 13:51:18 -0700 |
| commit | 067e8dfd82163ddcbde248dbe5a1187a417e5d36 (patch) | |
| tree | 7bfb46b901d03498c7739c92bec21d81d3a2c485 /src/encoding | |
| parent | 247786c1745abc0c7185f7c15ca256edf68ed6d6 (diff) | |
| parent | ccc037699e2966b7c79ba84c67471cef5e67a3b8 (diff) | |
| download | go-067e8dfd82163ddcbde248dbe5a1187a417e5d36.tar.xz | |
[dev.ssa] Merge remote-tracking branch 'origin/master' into mergebranch
Semi-regular merge of tip to dev.ssa.
Complicated a bit by the move of cmd/internal/* to cmd/compile/internal/*.
Change-Id: I1c66d3c29bb95cce4a53c5a3476373aa5245303d
Diffstat (limited to 'src/encoding')
| -rw-r--r-- | src/encoding/gob/doc.go | 18 | ||||
| -rw-r--r-- | src/encoding/gob/encoder.go | 6 | ||||
| -rw-r--r-- | src/encoding/gob/encoder_test.go | 18 | ||||
| -rw-r--r-- | src/encoding/json/decode.go | 2 | ||||
| -rw-r--r-- | src/encoding/json/decode_test.go | 21 | ||||
| -rw-r--r-- | src/encoding/json/encode.go | 2 | ||||
| -rw-r--r-- | src/encoding/json/scanner_test.go | 1 |
7 files changed, 56 insertions, 12 deletions
diff --git a/src/encoding/gob/doc.go b/src/encoding/gob/doc.go index d0acaba1ad..31223b6d43 100644 --- a/src/encoding/gob/doc.go +++ b/src/encoding/gob/doc.go @@ -6,7 +6,7 @@ Package gob manages streams of gobs - binary values exchanged between an Encoder (transmitter) and a Decoder (receiver). A typical use is transporting arguments and results of remote procedure calls (RPCs) such as those provided by -package "rpc". +package "net/rpc". The implementation compiles a custom codec for each data type in the stream and is most efficient when a single Encoder is used to transmit a stream of values, @@ -83,7 +83,7 @@ allocated. Regardless, the length of the resulting slice reports the number of elements decoded. Functions and channels will not be sent in a gob. Attempting to encode such a value -at top the level will fail. A struct field of chan or func type is treated exactly +at the top level will fail. A struct field of chan or func type is treated exactly like an unexported field and is ignored. Gob can encode a value of any type implementing the GobEncoder or @@ -111,11 +111,11 @@ A signed integer, i, is encoded within an unsigned integer, u. Within u, bits 1 upward contain the value; bit 0 says whether they should be complemented upon receipt. The encode algorithm looks like this: - uint u; + var u uint if i < 0 { - u = (^i << 1) | 1 // complement i, bit 0 is 1 + u = (^uint(i) << 1) | 1 // complement i, bit 0 is 1 } else { - u = (i << 1) // do not complement i, bit 0 is 0 + u = (uint(i) << 1) // do not complement i, bit 0 is 0 } encodeUnsigned(u) @@ -137,9 +137,9 @@ All other slices and arrays are sent as an unsigned count followed by that many elements using the standard gob encoding for their type, recursively. Maps are sent as an unsigned count followed by that many key, element -pairs. Empty but non-nil maps are sent, so if the sender has allocated -a map, the receiver will allocate a map even if no elements are -transmitted. +pairs. Empty but non-nil maps are sent, so if the receiver has not allocated +one already, one will always be allocated on receipt unless the transmitted map +is nil and not at the top level. Structs are sent as a sequence of (field number, field value) pairs. The field value is sent using the standard gob encoding for its type, recursively. If a @@ -246,7 +246,7 @@ where * signifies zero or more repetitions and the type id of a value must be predefined or be defined before the value in the stream. See "Gobs of data" for a design discussion of the gob wire format: -http://golang.org/doc/articles/gobs_of_data.html +http://blog.golang.org/gobs-of-data */ package gob diff --git a/src/encoding/gob/encoder.go b/src/encoding/gob/encoder.go index a340e47b5e..62d0f42e81 100644 --- a/src/encoding/gob/encoder.go +++ b/src/encoding/gob/encoder.go @@ -5,6 +5,7 @@ package gob import ( + "errors" "io" "reflect" "sync" @@ -65,6 +66,11 @@ func (enc *Encoder) writeMessage(w io.Writer, b *encBuffer) { // it by hand. message := b.Bytes() messageLen := len(message) - maxLength + // Length cannot be bigger than the decoder can handle. + if messageLen >= tooBig { + enc.setError(errors.New("gob: encoder: message too big")) + return + } // Encode the length. enc.countState.b.Reset() enc.countState.encodeUint(uint64(messageLen)) diff --git a/src/encoding/gob/encoder_test.go b/src/encoding/gob/encoder_test.go index c0bd379c93..8a72a3118c 100644 --- a/src/encoding/gob/encoder_test.go +++ b/src/encoding/gob/encoder_test.go @@ -976,3 +976,21 @@ func TestBadData(t *testing.T) { } } } + +// TestHugeWriteFails tests that enormous messages trigger an error. +func TestHugeWriteFails(t *testing.T) { + if testing.Short() { + // Requires allocating a monster, so don't do this from all.bash. + t.Skip("skipping huge allocation in short mode") + } + huge := make([]byte, tooBig) + huge[0] = 7 // Make sure it's not all zeros. + buf := new(bytes.Buffer) + err := NewEncoder(buf).Encode(huge) + if err == nil { + t.Fatalf("expected error for huge slice") + } + if !strings.Contains(err.Error(), "message too big") { + t.Fatalf("expected 'too big' error; got %s\n", err.Error()) + } +} diff --git a/src/encoding/json/decode.go b/src/encoding/json/decode.go index f26a7d49f0..613641afbb 100644 --- a/src/encoding/json/decode.go +++ b/src/encoding/json/decode.go @@ -739,7 +739,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool default: d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) case reflect.Slice: - if v.Type() != byteSliceType { + if v.Type().Elem().Kind() != reflect.Uint8 { d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) break } diff --git a/src/encoding/json/decode_test.go b/src/encoding/json/decode_test.go index 7ecc8f4402..f208ee8a7c 100644 --- a/src/encoding/json/decode_test.go +++ b/src/encoding/json/decode_test.go @@ -1207,7 +1207,28 @@ func TestStringKind(t *testing.T) { if !reflect.DeepEqual(m1, m2) { t.Error("Items should be equal after encoding and then decoding") } +} + +// Custom types with []byte as underlying type could not be marshalled +// and then unmarshalled. +// Issue 8962. +func TestByteKind(t *testing.T) { + type byteKind []byte + + a := byteKind("hello") + data, err := Marshal(a) + if err != nil { + t.Error(err) + } + var b byteKind + err = Unmarshal(data, &b) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(a, b) { + t.Errorf("expected %v == %v", a, b) + } } var decodeTypeErrorTests = []struct { diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go index 4db9f35e69..7789bb5141 100644 --- a/src/encoding/json/encode.go +++ b/src/encoding/json/encode.go @@ -275,8 +275,6 @@ func (e *encodeState) error(err error) { panic(err) } -var byteSliceType = reflect.TypeOf([]byte(nil)) - func isEmptyValue(v reflect.Value) bool { switch v.Kind() { case reflect.Array, reflect.Map, reflect.Slice, reflect.String: diff --git a/src/encoding/json/scanner_test.go b/src/encoding/json/scanner_test.go index 7880342902..66383ef0ef 100644 --- a/src/encoding/json/scanner_test.go +++ b/src/encoding/json/scanner_test.go @@ -209,6 +209,7 @@ var benchScan scanner func BenchmarkSkipValue(b *testing.B) { initBig() + b.ResetTimer() for i := 0; i < b.N; i++ { nextValue(jsonBig, &benchScan) } |
