From 95d23b23a12f7aaa661243814a0505f493052298 Mon Sep 17 00:00:00 2001 From: pedro Date: Thu, 4 Apr 2024 01:56:27 +0200 Subject: [PATCH 1/5] add amf0 strict array decode --- internal/protocols/rtmp/amf0/unmarshal.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/internal/protocols/rtmp/amf0/unmarshal.go b/internal/protocols/rtmp/amf0/unmarshal.go index 54f49246..26eb0558 100644 --- a/internal/protocols/rtmp/amf0/unmarshal.go +++ b/internal/protocols/rtmp/amf0/unmarshal.go @@ -183,6 +183,23 @@ func unmarshal(buf []byte) (interface{}, []byte, error) { case markerNull: return nil, buf, nil + case markerStrictArray: + if len(buf) < 4 { + return nil, nil, errBufferTooShort + } + keyLen := uint32(buf[0])<<24 | uint32(buf[1])<<16 | uint32(buf[2])<<8 | uint32(buf[3]) + buf = buf[4:] + for i := 0; i < int(keyLen); i++ { + var buffData []byte + var err error + _, buffData, err = unmarshal(buf) + if err != nil { + return nil, nil, err + } + buf = buffData + } + return nil, buf, nil + default: return nil, nil, fmt.Errorf("unsupported marker 0x%.2x", marker) } From 31f83019d4102613d0ac2ed6461f9d6a39a9e191 Mon Sep 17 00:00:00 2001 From: pedro Date: Thu, 4 Apr 2024 02:03:21 +0200 Subject: [PATCH 2/5] add amf0 long string decode --- internal/protocols/rtmp/amf0/unmarshal.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/internal/protocols/rtmp/amf0/unmarshal.go b/internal/protocols/rtmp/amf0/unmarshal.go index 26eb0558..a5b1c81e 100644 --- a/internal/protocols/rtmp/amf0/unmarshal.go +++ b/internal/protocols/rtmp/amf0/unmarshal.go @@ -200,6 +200,18 @@ func unmarshal(buf []byte) (interface{}, []byte, error) { } return nil, buf, nil + case markerLongString: + if len(buf) < 4 { + return nil, nil, errBufferTooShort + } + keyLen := uint32(buf[0])<<24 | uint32(buf[1])<<16 | uint32(buf[2])<<8 | uint32(buf[3]) + buf = buf[4:] + if len(buf) < int(keyLen) { + return nil, nil, errBufferTooShort + } + + return string(buf[:keyLen]), buf[keyLen:], nil + default: return nil, nil, fmt.Errorf("unsupported marker 0x%.2x", marker) } From 27ac4985cecda7d111d041e13b85c4224a344afe Mon Sep 17 00:00:00 2001 From: pedro Date: Thu, 4 Apr 2024 02:16:12 +0200 Subject: [PATCH 3/5] support amf0 types undefined, unsupported, xmldocument and date --- internal/protocols/rtmp/amf0/unmarshal.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/internal/protocols/rtmp/amf0/unmarshal.go b/internal/protocols/rtmp/amf0/unmarshal.go index a5b1c81e..08db1032 100644 --- a/internal/protocols/rtmp/amf0/unmarshal.go +++ b/internal/protocols/rtmp/amf0/unmarshal.go @@ -180,7 +180,7 @@ func unmarshal(buf []byte) (interface{}, []byte, error) { return out, buf[1:], nil - case markerNull: + case markerNull, markerUnsupported, markerUndefined: return nil, buf, nil case markerStrictArray: @@ -200,7 +200,7 @@ func unmarshal(buf []byte) (interface{}, []byte, error) { } return nil, buf, nil - case markerLongString: + case markerLongString, markerXMLDocument: if len(buf) < 4 { return nil, nil, errBufferTooShort } @@ -212,6 +212,16 @@ func unmarshal(buf []byte) (interface{}, []byte, error) { return string(buf[:keyLen]), buf[keyLen:], nil + case markerDate: + if len(buf) < 10 { + return nil, nil, errBufferTooShort + } + date := math.Float64frombits(uint64(buf[0])<<56 | uint64(buf[1])<<48 | uint64(buf[2])<<40 | uint64(buf[3])<<32 | + uint64(buf[4])<<24 | uint64(buf[5])<<16 | uint64(buf[6])<<8 | uint64(buf[7])) + buf = buf[8:] + //timeZone := uint16(buf[0])<<8 | uint16(buf[1]) + buf = buf[2:] // skip timeZone + return date, buf, nil default: return nil, nil, fmt.Errorf("unsupported marker 0x%.2x", marker) } From f030913cb195eb75da835cd79743d862fac84143 Mon Sep 17 00:00:00 2001 From: pedro Date: Sat, 6 Apr 2024 22:08:47 +0200 Subject: [PATCH 4/5] fix error and add tests --- internal/protocols/rtmp/amf0/unmarshal.go | 2 +- .../protocols/rtmp/amf0/unmarshal_test.go | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/internal/protocols/rtmp/amf0/unmarshal.go b/internal/protocols/rtmp/amf0/unmarshal.go index 08db1032..10fcdc34 100644 --- a/internal/protocols/rtmp/amf0/unmarshal.go +++ b/internal/protocols/rtmp/amf0/unmarshal.go @@ -219,7 +219,7 @@ func unmarshal(buf []byte) (interface{}, []byte, error) { date := math.Float64frombits(uint64(buf[0])<<56 | uint64(buf[1])<<48 | uint64(buf[2])<<40 | uint64(buf[3])<<32 | uint64(buf[4])<<24 | uint64(buf[5])<<16 | uint64(buf[6])<<8 | uint64(buf[7])) buf = buf[8:] - //timeZone := uint16(buf[0])<<8 | uint16(buf[1]) + // timeZone := uint16(buf[0])<<8 | uint16(buf[1]) buf = buf[2:] // skip timeZone return date, buf, nil default: diff --git a/internal/protocols/rtmp/amf0/unmarshal_test.go b/internal/protocols/rtmp/amf0/unmarshal_test.go index b4564ec9..4c5a6f94 100644 --- a/internal/protocols/rtmp/amf0/unmarshal_test.go +++ b/internal/protocols/rtmp/amf0/unmarshal_test.go @@ -311,3 +311,40 @@ func FuzzUnmarshal(f *testing.F) { Unmarshal(b) //nolint:errcheck }) } + +func TestStrictArray(t *testing.T) { + data := []byte{ + 0x0a, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x06, + 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x00, 0x40, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + } + t.Run("strictArray", func(t *testing.T) { + dec, err := Unmarshal(data) + require.NoError(t, err) + require.Equal(t, []interface{}{nil}, dec) + }) +} + +func TestLongString(t *testing.T) { + data := []byte{ + 0x0c, 0x00, 0x00, 0x00, 0x06, 0x72, 0x61, 0x6e, 0x64, + 0x6f, 0x6d, + } + t.Run("longString", func(t *testing.T) { + dec, err := Unmarshal(data) + require.NoError(t, err) + require.Equal(t, []interface{}{"random"}, dec) + }) +} + +func TestDate(t *testing.T) { + data := []byte{ + 0x0b, 0x40, 0xa3, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + } + t.Run("date", func(t *testing.T) { + dec, err := Unmarshal(data) + require.NoError(t, err) + require.Equal(t, []interface{}{float64(2500)}, dec) + }) +} From bd6214433b69f0ce1bc0ba49543e439e0934ec6e Mon Sep 17 00:00:00 2001 From: pedro Date: Sat, 6 Apr 2024 22:32:20 +0200 Subject: [PATCH 5/5] modify tests to follow original way to test --- .../protocols/rtmp/amf0/unmarshal_test.go | 68 +++++++++---------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/internal/protocols/rtmp/amf0/unmarshal_test.go b/internal/protocols/rtmp/amf0/unmarshal_test.go index 4c5a6f94..99e8ea7d 100644 --- a/internal/protocols/rtmp/amf0/unmarshal_test.go +++ b/internal/protocols/rtmp/amf0/unmarshal_test.go @@ -290,6 +290,37 @@ var cases = []struct { float64(0), }, }, + { + "strictArray", + []byte{ + 0x0a, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x06, + 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x00, 0x40, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + []interface{}{ + nil, + }, + }, + { + "longString", + []byte{ + 0x0c, 0x00, 0x00, 0x00, 0x06, 0x72, 0x61, 0x6e, 0x64, + 0x6f, 0x6d, + }, + []interface{}{ + "random", + }, + }, + { + "date", + []byte{ + 0x0b, 0x40, 0xa3, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + }, + []interface{}{ + float64(2500), + }, + }, } func TestUnmarshal(t *testing.T) { @@ -311,40 +342,3 @@ func FuzzUnmarshal(f *testing.F) { Unmarshal(b) //nolint:errcheck }) } - -func TestStrictArray(t *testing.T) { - data := []byte{ - 0x0a, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x06, - 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x00, 0x40, - 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - } - t.Run("strictArray", func(t *testing.T) { - dec, err := Unmarshal(data) - require.NoError(t, err) - require.Equal(t, []interface{}{nil}, dec) - }) -} - -func TestLongString(t *testing.T) { - data := []byte{ - 0x0c, 0x00, 0x00, 0x00, 0x06, 0x72, 0x61, 0x6e, 0x64, - 0x6f, 0x6d, - } - t.Run("longString", func(t *testing.T) { - dec, err := Unmarshal(data) - require.NoError(t, err) - require.Equal(t, []interface{}{"random"}, dec) - }) -} - -func TestDate(t *testing.T) { - data := []byte{ - 0x0b, 0x40, 0xa3, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - } - t.Run("date", func(t *testing.T) { - dec, err := Unmarshal(data) - require.NoError(t, err) - require.Equal(t, []interface{}{float64(2500)}, dec) - }) -}