Skip to content

Commit 1c4a7e8

Browse files
committed
fix(scanner): prevent infinite recursion in pid configuration
closes #4920 Signed-off-by: Deluan <[email protected]>
1 parent b1b488b commit 1c4a7e8

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

model/metadata/persistent_ids.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/navidrome/navidrome/conf"
1010
"github.com/navidrome/navidrome/consts"
11+
"github.com/navidrome/navidrome/log"
1112
"github.com/navidrome/navidrome/model"
1213
"github.com/navidrome/navidrome/model/id"
1314
"github.com/navidrome/navidrome/utils"
@@ -26,10 +27,14 @@ type getPIDFunc = func(mf model.MediaFile, md Metadata, spec string, prependLibI
2627

2728
func createGetPID(hash hashFunc) getPIDFunc {
2829
var getPID getPIDFunc
29-
getAttr := func(mf model.MediaFile, md Metadata, attr string, prependLibId bool) string {
30+
getAttr := func(mf model.MediaFile, md Metadata, attr string, prependLibId bool, spec string) string {
3031
attr = strings.TrimSpace(strings.ToLower(attr))
3132
switch attr {
3233
case "albumid":
34+
if spec == conf.Server.PID.Album {
35+
log.Error("Recursive PID definition detected, ignoring `albumid`", "spec", spec)
36+
return ""
37+
}
3338
return getPID(mf, md, conf.Server.PID.Album, prependLibId)
3439
case "folder":
3540
return filepath.Dir(mf.Path)
@@ -49,7 +54,7 @@ func createGetPID(hash hashFunc) getPIDFunc {
4954
attributes := strings.Split(field, ",")
5055
hasValue := false
5156
values := slice.Map(attributes, func(attr string) string {
52-
v := getAttr(mf, md, attr, prependLibId)
57+
v := getAttr(mf, md, attr, prependLibId, spec)
5358
if v != "" {
5459
hasValue = true
5560
}

model/metadata/persistent_ids_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,24 @@ var _ = Describe("getPID", func() {
114114
Expect(getPID(mf, md, spec, false)).To(Equal("(album name)"))
115115
})
116116
})
117+
118+
When("albumid configuration refers to albumid recursively", func() {
119+
It("should avoid infinite recursion", func() {
120+
// Reproduce the issue from #4920
121+
conf.Server.PID.Album = "albumid,album,albumversion,releasedate"
122+
spec := conf.Server.PID.Album
123+
md.tags = map[model.TagName][]string{
124+
"album": {"Album Name"},
125+
"albumversion": {"Version"},
126+
"releasedate": {"2022"},
127+
}
128+
// Should not panic and return a valid PID ignoring the recursive "albumid"
129+
Expect(func() {
130+
pid := getPID(mf, md, spec, false)
131+
Expect(pid).To(Equal("(\\album name\\Version\\2022)"))
132+
}).To(Not(Panic()))
133+
})
134+
})
117135
})
118136

119137
Context("edge cases", func() {

0 commit comments

Comments
 (0)