From e980d5919178f0d2cf5b83636f0b425ac40b604a Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Mon, 15 Jul 2024 13:40:37 +0900 Subject: [PATCH] audio: bug fix: crash with uncomparable source Closes #3039 --- audio/audio.go | 7 ++++++- audio/audio_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/audio/audio.go b/audio/audio.go index ba8c5f2ba..1e29faf12 100644 --- a/audio/audio.go +++ b/audio/audio.go @@ -37,6 +37,7 @@ import ( "errors" "fmt" "io" + "reflect" "runtime" "sync" "time" @@ -188,11 +189,15 @@ func (c *Context) addPlayingPlayer(p *playerImpl) { defer c.m.Unlock() c.playingPlayers[p] = struct{}{} + if !reflect.ValueOf(p.sourceIdent()).Comparable() { + return + } + // Check the source duplication srcs := map[any]struct{}{} for p := range c.playingPlayers { if _, ok := srcs[p.sourceIdent()]; ok { - c.err = errors.New("audio: a same source is used by multiple Player") + c.err = errors.New("audio: the same source must not be used by multiple Player objects") return } srcs[p.sourceIdent()] = struct{}{} diff --git a/audio/audio_test.go b/audio/audio_test.go index 6aa0c95a3..7ce175fb9 100644 --- a/audio/audio_test.go +++ b/audio/audio_test.go @@ -16,6 +16,7 @@ package audio_test import ( "bytes" + "io" "os" "runtime" "testing" @@ -147,4 +148,32 @@ func TestNonSeekableSource(t *testing.T) { p.Play() p.Pause() + + if err := audio.UpdateForTesting(); err != nil { + t.Error(err) + } +} + +type uncomparableSource []int + +func (uncomparableSource) Read(buf []byte) (int, error) { + return 0, io.EOF +} + +// Issue #3039 +func TestUncomparableSource(t *testing.T) { + setup() + defer teardown() + + p, err := context.NewPlayer(uncomparableSource{}) + if err != nil { + t.Fatal(err) + } + + p.Play() + p.Pause() + + if err := audio.UpdateForTesting(); err != nil { + t.Error(err) + } }