testEncodeDecode(t, st, rt)
})
}
+
+func TestLocalRemoteTypesMismatch(t *testing.T) {
+ // Test data is from https://go.dev/issue/62117.
+ testData := []byte{9, 127, 3, 1, 2, 255, 128, 0, 0, 0, 3, 255, 128, 0}
+
+ var v []*struct{}
+ buf := bytes.NewBuffer(testData)
+ err := NewDecoder(buf).Decode(&v)
+ if err == nil {
+ t.Error("Encode/Decode: expected error but got err == nil")
+ }
+}
safeString(seen map[typeId]bool) string
}
-var types = make(map[reflect.Type]gobType, 32)
-var idToType = make([]gobType, 1, firstUserId)
-var builtinIdToTypeSlice [firstUserId]gobType // set in init() after builtins are established
+var (
+ types = make(map[reflect.Type]gobType, 32)
+ idToTypeSlice = make([]gobType, 1, firstUserId)
+ builtinIdToTypeSlice [firstUserId]gobType // set in init() after builtins are established
+)
+
+func idToType(id typeId) gobType {
+ if id < 0 || int(id) >= len(idToTypeSlice) {
+ return nil
+ }
+ return idToTypeSlice[id]
+}
func builtinIdToType(id typeId) gobType {
if id < 0 || int(id) >= len(builtinIdToTypeSlice) {
if typ.id() != 0 {
return
}
- nextId := typeId(len(idToType))
+ nextId := typeId(len(idToTypeSlice))
typ.setId(nextId)
- idToType = append(idToType, typ)
+ idToTypeSlice = append(idToTypeSlice, typ)
}
func (t typeId) gobType() gobType {
if t == 0 {
return nil
}
- return idToType[t]
+ return idToType(t)
}
// string returns the string representation of the type associated with the typeId.
checkId(21, mustGetTypeInfo(reflect.TypeFor[fieldType]()).id)
checkId(23, mustGetTypeInfo(reflect.TypeFor[mapType]()).id)
- copy(builtinIdToTypeSlice[:], idToType)
+ copy(builtinIdToTypeSlice[:], idToTypeSlice)
// Move the id space upwards to allow for growth in the predefined world
// without breaking existing files.
- if nextId := len(idToType); nextId > firstUserId {
+ if nextId := len(idToTypeSlice); nextId > firstUserId {
panic(fmt.Sprintln("nextId too large:", nextId))
}
- idToType = idToType[:firstUserId]
+ idToTypeSlice = idToTypeSlice[:firstUserId]
registerBasics()
wireTypeUserInfo = userType(wireTypeType)
}
case reflect.Struct:
st := newStructType(name)
types[rt] = st
- idToType[st.id()] = st
+ idToTypeSlice[st.id()] = st
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if !isSent(&f) {