From 0e93ebfc73eea68d56ddf23ff6febec820b56b91 Mon Sep 17 00:00:00 2001 From: Deluan Date: Wed, 4 Feb 2026 18:32:01 -0500 Subject: [PATCH] fix(subsonic): add library filter and dedupe IDs in Exists Addresses code review feedback: apply library-level access control via applyLibraryFilter and handle duplicate IDs correctly using slice.Unique. This prevents users from verifying existence of tracks outside their accessible libraries and ensures duplicate IDs don't cause false negatives. Signed-off-by: Deluan --- persistence/mediafile_repository.go | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/persistence/mediafile_repository.go b/persistence/mediafile_repository.go index 18d2cfec0..9e041f561 100644 --- a/persistence/mediafile_repository.go +++ b/persistence/mediafile_repository.go @@ -143,19 +143,29 @@ func (r *mediaFileRepository) CountBySuffix(options ...model.QueryOptions) (map[ return counts, nil } -// Exists checks if all given media file IDs exist in the database. If no IDs are provided, it returns true. -// If any of the IDs do not exist, it returns false. It returns an error if the database query fails. +// Exists checks if all given media file IDs exist in the database and are accessible to the current user. +// If no IDs are provided, it returns true. Duplicate IDs are handled correctly. +// If any of the IDs do not exist or are not accessible, it returns false. func (r *mediaFileRepository) Exists(ids ...string) (bool, error) { if len(ids) == 0 { return true, nil } - existsQuery := Select("count(*) as exist").From("media_file").Where(Eq{"media_file.id": ids}) - var res struct{ Exist int64 } - err := r.queryOne(existsQuery, &res) - if err != nil { - return false, err + uniqueIds := slice.Unique(ids) + + // Process in batches to avoid hitting SQLITE_MAX_VARIABLE_NUMBER limit (default 999) + const batchSize = 300 + var totalCount int64 + for batch := range slices.Chunk(uniqueIds, batchSize) { + existsQuery := Select("count(*) as exist").From("media_file").Where(Eq{"media_file.id": batch}) + existsQuery = r.applyLibraryFilter(existsQuery) + var res struct{ Exist int64 } + err := r.queryOne(existsQuery, &res) + if err != nil { + return false, err + } + totalCount += res.Exist } - return res.Exist == int64(len(ids)), nil + return totalCount == int64(len(uniqueIds)), nil } func (r *mediaFileRepository) Put(m *model.MediaFile) error {