mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-08 02:17:25 +02:00
fix(artwork): reject a nil reader in the resize cache instead of panicking
resizedItem.Reader closes what open() hands back, so an open() that reports "no image" as (nil, nil) rather than an error takes the request down with a nil-pointer panic. Every caller returns an error today, and no test covered it: the resolution e2e harness stubs the resize reader out entirely, so no e2e path reaches this code at all. Guard it and cover Reader directly.
This commit is contained in:
parent
b8e38b4435
commit
d9dc6fc55f
2 changed files with 45 additions and 0 deletions
|
|
@ -55,6 +55,10 @@ func (r *resizedItem) Reader(ctx context.Context) (io.ReadCloser, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// An open() that reports "no image" as a nil reader would otherwise panic on the Close below.
|
||||
if orig == nil {
|
||||
return nil, ErrUnavailable
|
||||
}
|
||||
defer orig.Close()
|
||||
data, err := readCapped(orig)
|
||||
if err != nil {
|
||||
|
|
|
|||
41
core/artwork/image_cache_test.go
Normal file
41
core/artwork/image_cache_test.go
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
package artwork
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("resizedItem", func() {
|
||||
Describe("Reader", func() {
|
||||
newItem := func(open func() (io.ReadCloser, error)) *resizedItem {
|
||||
return &resizedItem{hash: "abc123", size: 300, open: open}
|
||||
}
|
||||
|
||||
It("reports a nil reader as unavailable instead of panicking on it", func() {
|
||||
// Every caller is expected to report "no image" as an error, but a nil reader reaches
|
||||
// the deferred Close as a nil interface, which takes the whole request down.
|
||||
_, err := newItem(func() (io.ReadCloser, error) { return nil, nil }).Reader(context.Background())
|
||||
Expect(err).To(MatchError(ErrUnavailable))
|
||||
})
|
||||
|
||||
It("propagates the open error", func() {
|
||||
boom := errors.New("boom")
|
||||
_, err := newItem(func() (io.ReadCloser, error) { return nil, boom }).Reader(context.Background())
|
||||
Expect(err).To(MatchError(boom))
|
||||
})
|
||||
|
||||
It("serves the original bytes when they cannot be resized", func() {
|
||||
rc, err := newItem(func() (io.ReadCloser, error) {
|
||||
return io.NopCloser(strings.NewReader("not an image")), nil
|
||||
}).Reader(context.Background())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
defer rc.Close()
|
||||
Expect(io.ReadAll(rc)).To(Equal([]byte("not an image")))
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue