aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-12-14 06:58:53 +0900
committerOphestra <cat@gensokyo.uk>2025-12-14 06:58:53 +0900
commit17248d7d6116a4a0b85ed0d90cb382a25eed16b5 (patch)
tree0832e1f3ad4a747801a22b28a317d1ef2559135f
parent41e5628c67ba566f158fac418790b6e0f8276cd8 (diff)
internal/pipewire: unmarshal nil pointer correctly
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>
-rw-r--r--internal/pipewire/pod.go38
1 files changed, 29 insertions, 9 deletions
diff --git a/internal/pipewire/pod.go b/internal/pipewire/pod.go
index f8a824cb..103154aa 100644
--- a/internal/pipewire/pod.go
+++ b/internal/pipewire/pod.go
@@ -384,19 +384,16 @@ func unmarshalValue(data []byte, v reflect.Value, wireSizeP *Word) error {
return nil
case reflect.Pointer:
- if len(data) < SizePrefix {
- return ErrEOFPrefix
- }
- switch SPAKind(binary.NativeEndian.Uint32(data[SizeSPrefix:])) {
- case SPA_TYPE_None:
+ if ok, err := unmarshalHandleNone(&data, wireSizeP); err != nil {
+ return err
+ } else if ok {
v.SetZero()
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:
*wireSizeP = 0
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
// in data passed to [Unmarshal].
type InconsistentSizeError struct{ Prefix, Expect Word }