diff options
| author | Andrew Wilkins <axwalk@gmail.com> | 2016-03-15 05:36:43 +0000 |
|---|---|---|
| committer | Andrew Wilkins <axwalk@gmail.com> | 2016-03-15 05:36:43 +0000 |
| commit | 6436a4abd7a2f3a60b230453295dba199d8a59c3 (patch) | |
| tree | 125aef80fc2cf46c5d1758a8ece1fde14e7b13fd /llgo/third_party/gofrontend/libgo/go/encoding/gob | |
| parent | 36761bf92427846ce40fdd849615732c852e44dd (diff) | |
| download | bcm5719-llvm-6436a4abd7a2f3a60b230453295dba199d8a59c3.tar.gz bcm5719-llvm-6436a4abd7a2f3a60b230453295dba199d8a59c3.zip | |
[llgo] Roll gofrontend forward
Switch gofrontend to using go.googlesource.com, and
update to 81eb6a3f425b2158c67ee32c0cc973a72ce9d6be.
There are various changes required to update to the
go 1.5 runtime:
typemap.go is changed to accommodate the change in representation for equal/hash algorithms, and the removal of the zero value/type.
CMakeLists.txt is updated to add the build tree to the package search path, so internal packages, which are not installed, are found.
various files changes due to removal of __go_new_nopointers; the same change as in D11863, but with NoUnwindAttribute added to the added runtime functions which are called with "callOnly".
minor cleanups in ssa.go while investigating issues with unwinding/panic handling.
Differential Revisision: http://reviews.llvm.org/D15188
llvm-svn: 263536
Diffstat (limited to 'llgo/third_party/gofrontend/libgo/go/encoding/gob')
5 files changed, 187 insertions, 67 deletions
diff --git a/llgo/third_party/gofrontend/libgo/go/encoding/gob/codec_test.go b/llgo/third_party/gofrontend/libgo/go/encoding/gob/codec_test.go index 56a7298fa55..c2583bfee33 100644 --- a/llgo/third_party/gofrontend/libgo/go/encoding/gob/codec_test.go +++ b/llgo/third_party/gofrontend/libgo/go/encoding/gob/codec_test.go @@ -1473,3 +1473,22 @@ func TestFuzzOneByte(t *testing.T) { } } } + +// Don't crash, just give error with invalid type id. +// Issue 9649. +func TestErrorInvalidTypeId(t *testing.T) { + data := []byte{0x01, 0x00, 0x01, 0x00} + d := NewDecoder(bytes.NewReader(data)) + // When running d.Decode(&foo) the first time the decoder stops + // after []byte{0x01, 0x00} and reports an errBadType. Running + // d.Decode(&foo) again on exactly the same input sequence should + // give another errBadType, but instead caused a panic because + // decoderMap wasn't cleaned up properly after the first error. + for i := 0; i < 2; i++ { + var foo struct{} + err := d.Decode(&foo) + if err != errBadType { + t.Fatal("decode: expected %s, got %s", errBadType, err) + } + } +} diff --git a/llgo/third_party/gofrontend/libgo/go/encoding/gob/decode.go b/llgo/third_party/gofrontend/libgo/go/encoding/gob/decode.go index a5bef93141b..e913f15c545 100644 --- a/llgo/third_party/gofrontend/libgo/go/encoding/gob/decode.go +++ b/llgo/third_party/gofrontend/libgo/go/encoding/gob/decode.go @@ -182,6 +182,17 @@ func (state *decoderState) decodeInt() int64 { return int64(x >> 1) } +// getLength decodes the next uint and makes sure it is a possible +// size for a data item that follows, which means it must fit in a +// non-negative int and fit in the buffer. +func (state *decoderState) getLength() (int, bool) { + n := int(state.decodeUint()) + if n < 0 || state.b.Len() < n || tooBig <= n { + return 0, false + } + return n, true +} + // decOp is the signature of a decoding operator for a given type. type decOp func(i *decInstr, state *decoderState, v reflect.Value) @@ -363,16 +374,9 @@ func decComplex128(i *decInstr, state *decoderState, value reflect.Value) { // describing the data. // uint8 slices are encoded as an unsigned count followed by the raw bytes. func decUint8Slice(i *decInstr, state *decoderState, value reflect.Value) { - u := state.decodeUint() - n := int(u) - if n < 0 || uint64(n) != u { - errorf("length of %s exceeds input size (%d bytes)", value.Type(), u) - } - if n > state.b.Len() { - errorf("%s data too long for buffer: %d", value.Type(), n) - } - if n > tooBig { - errorf("byte slice too big: %d", n) + n, ok := state.getLength() + if !ok { + errorf("bad %s slice length: %d", value.Type(), n) } if value.Cap() < n { value.Set(reflect.MakeSlice(value.Type(), n, n)) @@ -388,13 +392,9 @@ func decUint8Slice(i *decInstr, state *decoderState, value reflect.Value) { // describing the data. // Strings are encoded as an unsigned count followed by the raw bytes. func decString(i *decInstr, state *decoderState, value reflect.Value) { - u := state.decodeUint() - n := int(u) - if n < 0 || uint64(n) != u || n > state.b.Len() { - errorf("length of %s exceeds input size (%d bytes)", value.Type(), u) - } - if n > state.b.Len() { - errorf("%s data too long for buffer: %d", value.Type(), n) + n, ok := state.getLength() + if !ok { + errorf("bad %s slice length: %d", value.Type(), n) } // Read the data. data := make([]byte, n) @@ -406,7 +406,11 @@ func decString(i *decInstr, state *decoderState, value reflect.Value) { // ignoreUint8Array skips over the data for a byte slice value with no destination. func ignoreUint8Array(i *decInstr, state *decoderState, value reflect.Value) { - b := make([]byte, state.decodeUint()) + n, ok := state.getLength() + if !ok { + errorf("slice length too large") + } + b := make([]byte, n) state.b.Read(b) } @@ -571,6 +575,9 @@ func (dec *Decoder) decodeMap(mtyp reflect.Type, state *decoderState, value refl func (dec *Decoder) ignoreArrayHelper(state *decoderState, elemOp decOp, length int) { instr := &decInstr{elemOp, 0, nil, errors.New("no error")} for i := 0; i < length; i++ { + if state.b.Len() == 0 { + errorf("decoding array or slice: length exceeds input size (%d elements)", length) + } elemOp(instr, state, noValue) } } @@ -678,7 +685,11 @@ func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, valu // ignoreInterface discards the data for an interface value with no destination. func (dec *Decoder) ignoreInterface(state *decoderState) { // Read the name of the concrete type. - b := make([]byte, state.decodeUint()) + n, ok := state.getLength() + if !ok { + errorf("bad interface encoding: name too large for buffer") + } + b := make([]byte, n) _, err := state.b.Read(b) if err != nil { error_(err) @@ -688,14 +699,22 @@ func (dec *Decoder) ignoreInterface(state *decoderState) { error_(dec.err) } // At this point, the decoder buffer contains a delimited value. Just toss it. - state.b.Drop(int(state.decodeUint())) + n, ok = state.getLength() + if !ok { + errorf("bad interface encoding: data length too large for buffer") + } + state.b.Drop(n) } // decodeGobDecoder decodes something implementing the GobDecoder interface. // The data is encoded as a byte slice. func (dec *Decoder) decodeGobDecoder(ut *userTypeInfo, state *decoderState, value reflect.Value) { // Read the bytes for the value. - b := make([]byte, state.decodeUint()) + n, ok := state.getLength() + if !ok { + errorf("GobDecoder: length too large for buffer") + } + b := make([]byte, n) _, err := state.b.Read(b) if err != nil { error_(err) @@ -717,7 +736,11 @@ func (dec *Decoder) decodeGobDecoder(ut *userTypeInfo, state *decoderState, valu // ignoreGobDecoder discards the data for a GobDecoder value with no destination. func (dec *Decoder) ignoreGobDecoder(state *decoderState) { // Read the bytes for the value. - b := make([]byte, state.decodeUint()) + n, ok := state.getLength() + if !ok { + errorf("GobDecoder: length too large for buffer") + } + b := make([]byte, n) _, err := state.b.Read(b) if err != nil { error_(err) @@ -840,16 +863,22 @@ func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProg } // decIgnoreOpFor returns the decoding op for a field that has no destination. -func (dec *Decoder) decIgnoreOpFor(wireId typeId) decOp { +func (dec *Decoder) decIgnoreOpFor(wireId typeId, inProgress map[typeId]*decOp) *decOp { + // If this type is already in progress, it's a recursive type (e.g. map[string]*T). + // Return the pointer to the op we're already building. + if opPtr := inProgress[wireId]; opPtr != nil { + return opPtr + } op, ok := decIgnoreOpMap[wireId] if !ok { + inProgress[wireId] = &op if wireId == tInterface { // Special case because it's a method: the ignored item might // define types and we need to record their state in the decoder. op = func(i *decInstr, state *decoderState, value reflect.Value) { state.dec.ignoreInterface(state) } - return op + return &op } // Special cases wire := dec.wireType[wireId] @@ -858,25 +887,25 @@ func (dec *Decoder) decIgnoreOpFor(wireId typeId) decOp { errorf("bad data: undefined type %s", wireId.string()) case wire.ArrayT != nil: elemId := wire.ArrayT.Elem - elemOp := dec.decIgnoreOpFor(elemId) + elemOp := dec.decIgnoreOpFor(elemId, inProgress) op = func(i *decInstr, state *decoderState, value reflect.Value) { - state.dec.ignoreArray(state, elemOp, wire.ArrayT.Len) + state.dec.ignoreArray(state, *elemOp, wire.ArrayT.Len) } case wire.MapT != nil: keyId := dec.wireType[wireId].MapT.Key elemId := dec.wireType[wireId].MapT.Elem - keyOp := dec.decIgnoreOpFor(keyId) - elemOp := dec.decIgnoreOpFor(elemId) + keyOp := dec.decIgnoreOpFor(keyId, inProgress) + elemOp := dec.decIgnoreOpFor(elemId, inProgress) op = func(i *decInstr, state *decoderState, value reflect.Value) { - state.dec.ignoreMap(state, keyOp, elemOp) + state.dec.ignoreMap(state, *keyOp, *elemOp) } case wire.SliceT != nil: elemId := wire.SliceT.Elem - elemOp := dec.decIgnoreOpFor(elemId) + elemOp := dec.decIgnoreOpFor(elemId, inProgress) op = func(i *decInstr, state *decoderState, value reflect.Value) { - state.dec.ignoreSlice(state, elemOp) + state.dec.ignoreSlice(state, *elemOp) } case wire.StructT != nil: @@ -899,7 +928,7 @@ func (dec *Decoder) decIgnoreOpFor(wireId typeId) decOp { if op == nil { errorf("bad data: ignore can't handle type %s", wireId.string()) } - return op + return &op } // gobDecodeOpFor returns the op for a type that is known to implement @@ -1033,9 +1062,9 @@ func (dec *Decoder) compileSingle(remoteId typeId, ut *userTypeInfo) (engine *de func (dec *Decoder) compileIgnoreSingle(remoteId typeId) (engine *decEngine, err error) { engine = new(decEngine) engine.instr = make([]decInstr, 1) // one item - op := dec.decIgnoreOpFor(remoteId) + op := dec.decIgnoreOpFor(remoteId, make(map[typeId]*decOp)) ovfl := overflow(dec.typeString(remoteId)) - engine.instr[0] = decInstr{op, 0, nil, ovfl} + engine.instr[0] = decInstr{*op, 0, nil, ovfl} engine.numInstr = 1 return } @@ -1043,6 +1072,7 @@ func (dec *Decoder) compileIgnoreSingle(remoteId typeId) (engine *decEngine, err // compileDec compiles the decoder engine for a value. If the value is not a struct, // it calls out to compileSingle. func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEngine, err error) { + defer catchError(&err) rt := ut.base srt := rt if srt.Kind() != reflect.Struct || ut.externalDec != 0 { @@ -1077,8 +1107,8 @@ func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEn localField, present := srt.FieldByName(wireField.Name) // TODO(r): anonymous names if !present || !isExported(wireField.Name) { - op := dec.decIgnoreOpFor(wireField.Id) - engine.instr[fieldnum] = decInstr{op, fieldnum, nil, ovfl} + op := dec.decIgnoreOpFor(wireField.Id, make(map[typeId]*decOp)) + engine.instr[fieldnum] = decInstr{*op, fieldnum, nil, ovfl} continue } if !dec.compatibleType(localField.Type, wireField.Id, make(map[reflect.Type]typeId)) { @@ -1116,7 +1146,7 @@ type emptyStruct struct{} var emptyStructType = reflect.TypeOf(emptyStruct{}) -// getDecEnginePtr returns the engine for the specified type when the value is to be discarded. +// getIgnoreEnginePtr returns the engine for the specified type when the value is to be discarded. func (dec *Decoder) getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, err error) { var ok bool if enginePtr, ok = dec.ignorerCache[wireId]; !ok { @@ -1155,8 +1185,9 @@ func (dec *Decoder) decodeValue(wireId typeId, value reflect.Value) { value = decAlloc(value) engine := *enginePtr if st := base; st.Kind() == reflect.Struct && ut.externalDec == 0 { + wt := dec.wireType[wireId] if engine.numInstr == 0 && st.NumField() > 0 && - dec.wireType[wireId] != nil && len(dec.wireType[wireId].StructT.Field) > 0 { + wt != nil && len(wt.StructT.Field) > 0 { name := base.Name() errorf("type mismatch: no fields matched compiling decoder for %s", name) } diff --git a/llgo/third_party/gofrontend/libgo/go/encoding/gob/doc.go b/llgo/third_party/gofrontend/libgo/go/encoding/gob/doc.go index d0acaba1adc..4d3d0076fbc 100644 --- a/llgo/third_party/gofrontend/libgo/go/encoding/gob/doc.go +++ b/llgo/third_party/gofrontend/libgo/go/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 +https://blog.golang.org/gobs-of-data */ package gob diff --git a/llgo/third_party/gofrontend/libgo/go/encoding/gob/encoder.go b/llgo/third_party/gofrontend/libgo/go/encoding/gob/encoder.go index a340e47b5ed..62d0f42e81a 100644 --- a/llgo/third_party/gofrontend/libgo/go/encoding/gob/encoder.go +++ b/llgo/third_party/gofrontend/libgo/go/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/llgo/third_party/gofrontend/libgo/go/encoding/gob/encoder_test.go b/llgo/third_party/gofrontend/libgo/go/encoding/gob/encoder_test.go index 0ea4c0ec8e5..dc657348223 100644 --- a/llgo/third_party/gofrontend/libgo/go/encoding/gob/encoder_test.go +++ b/llgo/third_party/gofrontend/libgo/go/encoding/gob/encoder_test.go @@ -6,8 +6,8 @@ package gob import ( "bytes" + "encoding/hex" "fmt" - "io" "reflect" "strings" "testing" @@ -187,24 +187,6 @@ func TestWrongTypeDecoder(t *testing.T) { badTypeCheck(new(ET4), true, "different type of field", t) } -func corruptDataCheck(s string, err error, t *testing.T) { - b := bytes.NewBufferString(s) - dec := NewDecoder(b) - err1 := dec.Decode(new(ET2)) - if err1 != err { - t.Errorf("from %q expected error %s; got %s", s, err, err1) - } -} - -// Check that we survive bad data. -func TestBadData(t *testing.T) { - corruptDataCheck("", io.EOF, t) - corruptDataCheck("\x7Fhi", io.ErrUnexpectedEOF, t) - corruptDataCheck("\x03now is the time for all good men", errBadType, t) - // issue 6323. - corruptDataCheck("\x04\x24foo", errRange, t) -} - // Types not supported at top level by the Encoder. var unsupportedValues = []interface{}{ make(chan int), @@ -545,6 +527,30 @@ func TestDecodeIntoNothing(t *testing.T) { } } +func TestIgnoreRecursiveType(t *testing.T) { + // It's hard to build a self-contained test for this because + // we can't build compatible types in one package with + // different items so something is ignored. Here is + // some data that represents, according to debug.go: + // type definition { + // slice "recursiveSlice" id=106 + // elem id=106 + // } + data := []byte{ + 0x1d, 0xff, 0xd3, 0x02, 0x01, 0x01, 0x0e, 0x72, + 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, + 0x53, 0x6c, 0x69, 0x63, 0x65, 0x01, 0xff, 0xd4, + 0x00, 0x01, 0xff, 0xd4, 0x00, 0x00, 0x07, 0xff, + 0xd4, 0x00, 0x02, 0x01, 0x00, 0x00, + } + dec := NewDecoder(bytes.NewReader(data)) + // Issue 10415: This caused infinite recursion. + err := dec.Decode(nil) + if err != nil { + t.Fatal(err) + } +} + // Another bug from golang-nuts, involving nested interfaces. type Bug0Outer struct { Bug0Field interface{} @@ -951,6 +957,64 @@ func TestErrorForHugeSlice(t *testing.T) { t.Fatal("decode: no error") } if !strings.Contains(err.Error(), "slice too big") { - t.Fatal("decode: expected slice too big error, got %s", err.Error()) + t.Fatalf("decode: expected slice too big error, got %s", err.Error()) + } +} + +type badDataTest struct { + input string // The input encoded as a hex string. + error string // A substring of the error that should result. + data interface{} // What to decode into. +} + +var badDataTests = []badDataTest{ + {"", "EOF", nil}, + {"7F6869", "unexpected EOF", nil}, + {"036e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e", "unknown type id", new(ET2)}, + {"0424666f6f", "field numbers out of bounds", new(ET2)}, // Issue 6323. + {"05100028557b02027f8302", "interface encoding", nil}, // Issue 10270. + // Issue 10273. + {"130a00fb5dad0bf8ff020263e70002fa28020202a89859", "slice length too large", nil}, + {"0f1000fb285d003316020735ff023a65c5", "interface encoding", nil}, + {"03fffb0616fffc00f902ff02ff03bf005d02885802a311a8120228022c028ee7", "GobDecoder", nil}, + // Issue 10491. + {"10fe010f020102fe01100001fe010e000016fe010d030102fe010e00010101015801fe01100000000bfe011000f85555555555555555", "length exceeds input size", nil}, +} + +// TestBadData tests that various problems caused by malformed input +// are caught as errors and do not cause panics. +func TestBadData(t *testing.T) { + for i, test := range badDataTests { + data, err := hex.DecodeString(test.input) + if err != nil { + t.Fatalf("#%d: hex error: %s", i, err) + } + d := NewDecoder(bytes.NewReader(data)) + err = d.Decode(test.data) + if err == nil { + t.Errorf("decode: no error") + continue + } + if !strings.Contains(err.Error(), test.error) { + t.Errorf("#%d: decode: expected %q error, got %s", i, test.error, err.Error()) + } + } +} + +// 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()) } } |

