}
}
}
+
+// 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)
+ }
+ }
+}
// 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 {
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)
}