Skip to content

Commit

Permalink
Fix deserialization of implementations of interface T with a custom s…
Browse files Browse the repository at this point in the history
…erializer

If the implementation is a pointer, and the pointer type
is not a named type but the pointed at type is, the
serialization layer incorrectly returns the interface type T
when deserializing the implementation of type T.

Fix the issue by keeping just enough type information
on the opaque types to be able to recreate the right type
at deser time.
  • Loading branch information
chriso committed Nov 21, 2023
1 parent 7e7dc19 commit 2856d05
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 4 deletions.
3 changes: 3 additions & 0 deletions types/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,9 @@ func (t *Type) Format(s fmt.State, v rune) {
if name == "" {
name = fmt.Sprintf("<anon %s>", t.Kind())
}
if t.typ.Kind == coroutinev1.Kind_KIND_POINTER {
name = "*" + name
}
s.Write([]byte(name))
return
}
Expand Down
23 changes: 19 additions & 4 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,22 @@ func (m *typemap) ToReflect(id typeid) reflect.Type {
panic(fmt.Sprintf("type %d not found", id))
}

if t.MemoryOffset != 0 {
return typeForOffset(namedTypeOffset(t.MemoryOffset))
}

if t.CustomSerializer > 0 {
if t.MemoryOffset != 0 {
et := typeForOffset(namedTypeOffset(t.MemoryOffset))
if t.Kind == coroutinev1.Kind_KIND_POINTER {
et = reflect.PointerTo(et)
}
return et
}
id := serdeid(t.CustomSerializer)
return m.serdes.serdeByID(id).typ
}

if t.MemoryOffset != 0 {
return typeForOffset(namedTypeOffset(t.MemoryOffset))
}

var x reflect.Type
switch t.Kind {
case coroutinev1.Kind_KIND_BOOL:
Expand Down Expand Up @@ -205,6 +212,14 @@ func (m *typemap) ToType(t reflect.Type) typeid {

// Types with custom serializers are opaque.
if s, ok := m.serdes.serdeByType(t); ok {
if t.Name() == "" && t.Kind() == reflect.Pointer {
if et := t.Elem(); et.Name() != "" {
ti.Kind = coroutinev1.Kind_KIND_POINTER
ti.MemoryOffset = uint64(offsetForType(et))
ti.Name = m.strings.Intern(et.Name())
ti.Package = m.strings.Intern(et.PkgPath())
}
}
ti.CustomSerializer = s.id
return id
}
Expand Down

0 comments on commit 2856d05

Please sign in to comment.