diff options
Diffstat (limited to 'internal/pipewire/pod.go')
| -rw-r--r-- | internal/pipewire/pod.go | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/internal/pipewire/pod.go b/internal/pipewire/pod.go index ff82c72f..cf018ccd 100644 --- a/internal/pipewire/pod.go +++ b/internal/pipewire/pod.go @@ -135,6 +135,12 @@ func marshalValueAppendRaw(data []byte, v reflect.Value) ([]byte, error) { } return marshalValueAppendRaw(data, v.Elem()) + case reflect.String: + data = binary.NativeEndian.AppendUint32(data, SPA_TYPE_String) + data = append(data, []byte(v.String())...) + data = append(data, 0) + return data, nil + default: return data, &UnsupportedTypeError{v.Type()} } @@ -183,6 +189,14 @@ func (e *TrailingGarbageError) Error() string { return "data has extra values starting with type " + strconv.Itoa(int(binary.NativeEndian.Uint32(e.Data[4:]))) } +// A StringTerminationError describes an incorrectly terminated string +// encountered during [Unmarshal]. +type StringTerminationError struct{ Value byte } + +func (e StringTerminationError) Error() string { + return "got byte " + strconv.Itoa(int(e.Value)) + " instead of NUL" +} + // unmarshalValue implements [Unmarshal] on [reflect.Value]. func unmarshalValue(data []byte, v reflect.Value, sizeP *Word) error { switch v.Kind() { @@ -236,6 +250,25 @@ func unmarshalValue(data []byte, v reflect.Value, sizeP *Word) error { return unmarshalValue(data, v.Elem(), sizeP) } + case reflect.String: + if err := unmarshalCheckTypeBounds(&data, SPA_TYPE_String, sizeP); err != nil { + return err + } + + // string size, one extra NUL byte + size := int(*sizeP) + if len(data) < size { + return io.ErrUnexpectedEOF + } + + // the serialised strings still include NUL termination + if data[size-1] != 0 { + return StringTerminationError{data[size-1]} + } + + v.SetString(string(data[:size-1])) + return nil + default: return &UnsupportedTypeError{v.Type()} } |
