internal/pipewire: unmarshal nil pointer correctly
All checks were successful
Test / Create distribution (push) Successful in 35s
Test / Sandbox (push) Successful in 2m21s
Test / Hakurei (push) Successful in 3m27s
Test / Sandbox (race detector) (push) Successful in 4m21s
Test / Hpkg (push) Successful in 4m28s
Test / Hakurei (race detector) (push) Successful in 5m21s
Test / Flake checks (push) Successful in 1m41s

This now calls unmarshalCheckTypeBounds to advance to the next message. Additionally, handling for None value is relocated to a function for reuse by other types.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2025-12-14 06:58:53 +09:00
parent 41e5628c67
commit 17248d7d61

View File

@@ -384,19 +384,16 @@ func unmarshalValue(data []byte, v reflect.Value, wireSizeP *Word) error {
return nil return nil
case reflect.Pointer: case reflect.Pointer:
if len(data) < SizePrefix { if ok, err := unmarshalHandleNone(&data, wireSizeP); err != nil {
return ErrEOFPrefix return err
} } else if ok {
switch SPAKind(binary.NativeEndian.Uint32(data[SizeSPrefix:])) {
case SPA_TYPE_None:
v.SetZero() v.SetZero()
return nil return nil
default:
v.Set(reflect.New(v.Type().Elem()))
return unmarshalValue(data, v.Elem(), wireSizeP)
} }
v.Set(reflect.New(v.Type().Elem()))
return unmarshalValue(data, v.Elem(), wireSizeP)
case reflect.String: case reflect.String:
*wireSizeP = 0 *wireSizeP = 0
if err := unmarshalCheckTypeBounds(&data, SPA_TYPE_String, wireSizeP); err != nil { if err := unmarshalCheckTypeBounds(&data, SPA_TYPE_String, wireSizeP); err != nil {
@@ -422,6 +419,29 @@ func unmarshalValue(data []byte, v reflect.Value, wireSizeP *Word) error {
} }
} }
// unmarshalHandleNone establishes prefix bounds and, for a value of type [SPA_TYPE_None],
// validates its size and skips the header. This is for unmarshalling values that can be nil.
func unmarshalHandleNone(data *[]byte, wireSizeP *Word) (bool, error) {
if len(*data) < SizePrefix {
return false, ErrEOFPrefix
}
if SPAKind(binary.NativeEndian.Uint32((*data)[SizeSPrefix:])) != SPA_TYPE_None {
return false, nil
}
*wireSizeP = 0
if err := unmarshalCheckTypeBounds(data, SPA_TYPE_None, wireSizeP); err != nil {
return true, err
}
if len(*data) != 0 {
return true, TrailingGarbageError(*data)
}
return true, nil
}
// An InconsistentSizeError describes an inconsistent size prefix encountered // An InconsistentSizeError describes an inconsistent size prefix encountered
// in data passed to [Unmarshal]. // in data passed to [Unmarshal].
type InconsistentSizeError struct{ Prefix, Expect Word } type InconsistentSizeError struct{ Prefix, Expect Word }