fix(voice): bound header slice when seeking truncated audio

This commit is contained in:
ayn2op 2026-10-16 17:59:55 -04:00
parent f647d96fab
commit 9c1a39ca76
2 changed files with 34 additions and 19 deletions

View file

@ -125,7 +125,7 @@ func (p *Player) seek(position time.Duration) error {
offset += size
}
decoder, err := oggopus.NewDecoder(io.MultiReader(bytes.NewReader(p.audio[:headers]), bytes.NewReader(p.audio[min(start, len(p.audio)):])))
decoder, err := oggopus.NewDecoder(io.MultiReader(bytes.NewReader(p.audio[:min(headers, len(p.audio))]), bytes.NewReader(p.audio[min(start, len(p.audio)):])))
if err != nil {
return err
}

View file

@ -12,6 +12,7 @@ import (
)
func TestPlayerSeek(t *testing.T) {
t.Run("valid", func(t *testing.T) {
const seconds = 10
var audio bytes.Buffer
@ -36,4 +37,18 @@ func TestPlayerSeek(t *testing.T) {
t.Errorf("seek to %v: %v is left, want %v", position, got, want)
}
}
})
// A page whose segment table claims far more bytes than the file holds must not make seek read out of bounds.
t.Run("truncated page", func(t *testing.T) {
page := make([]byte, oggHeaderSize+255)
copy(page, "OggS")
page[oggSegmentsOffset] = 255
for i := range page[oggHeaderSize:] {
page[oggHeaderSize+i] = 255
}
p := Player{audio: page}
_ = p.seek(0)
})
}