From 31541765fd837493828f782d12cf84f985d0d40b Mon Sep 17 00:00:00 2001 From: aler9 <46489434+aler9@users.noreply.github.com> Date: Tue, 27 Dec 2022 12:00:00 +0000 Subject: [PATCH] hls source: fix crash in case of invalid EXT-X-MEDIA-SEQUENCE --- internal/hls/client_downloader_stream.go | 2 +- internal/hls/client_test.go | 73 ++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/internal/hls/client_downloader_stream.go b/internal/hls/client_downloader_stream.go index aa506f15..bc3e398a 100644 --- a/internal/hls/client_downloader_stream.go +++ b/internal/hls/client_downloader_stream.go @@ -36,7 +36,7 @@ func findSegmentWithInvPosition(segments []*gm3u8.MediaSegment, pos int) *gm3u8. func findSegmentWithID(seqNo uint64, segments []*gm3u8.MediaSegment, id uint64) (*gm3u8.MediaSegment, int) { index := int(int64(id) - int64(seqNo)) - if index >= len(segments) { + if index < 0 || index >= len(segments) { return nil, 0 } diff --git a/internal/hls/client_test.go b/internal/hls/client_test.go index be42c7d8..3c71812f 100644 --- a/internal/hls/client_test.go +++ b/internal/hls/client_test.go @@ -252,3 +252,76 @@ func TestClient(t *testing.T) { }) } } + +func TestClientInvalidSequenceID(t *testing.T) { + router := gin.New() + firstPlaylist := true + + router.GET("/stream.m3u8", func(ctx *gin.Context) { + ctx.Writer.Header().Set("Content-Type", `application/x-mpegURL`) + + if firstPlaylist { + firstPlaylist = false + io.Copy(ctx.Writer, bytes.NewReader([]byte( + `#EXTM3U + #EXT-X-VERSION:3 + #EXT-X-ALLOW-CACHE:NO + #EXT-X-TARGETDURATION:2 + #EXT-X-MEDIA-SEQUENCE:2 + #EXTINF:2, + segment1.ts + #EXTINF:2, + segment1.ts + #EXTINF:2, + segment1.ts + `))) + } else { + io.Copy(ctx.Writer, bytes.NewReader([]byte( + `#EXTM3U + #EXT-X-VERSION:3 + #EXT-X-ALLOW-CACHE:NO + #EXT-X-TARGETDURATION:2 + #EXT-X-MEDIA-SEQUENCE:4 + #EXTINF:2, + segment1.ts + #EXTINF:2, + segment1.ts + #EXTINF:2, + segment1.ts + `))) + } + }) + + router.GET("/segment1.ts", func(ctx *gin.Context) { + ctx.Writer.Header().Set("Content-Type", `video/MP2T`) + mpegtsSegment(ctx.Writer) + }) + + s, err := newTestHLSServer(router, false) + require.NoError(t, err) + defer s.close() + + packetRecv := make(chan struct{}) + + c, err := NewClient( + "http://localhost:5780/stream.m3u8", + "", + func(*format.H264, *format.MPEG4Audio) error { + return nil + }, + func(pts time.Duration, nalus [][]byte) { + close(packetRecv) + }, + nil, + testLogger{}, + ) + require.NoError(t, err) + + <-packetRecv + + // c.Close() + err = <-c.Wait() + require.EqualError(t, err, "following segment not found or not ready yet") + + c.Close() +}