diff options
| author | Egor Bakanov <33174871+EgorBakanov@users.noreply.github.com> | 2023-01-08 01:48:14 +0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-01-07 11:48:14 -0700 |
| commit | 46e9f5ad2e1f61cefe719d03f5a8986434fbb7b6 (patch) | |
| tree | ddc400c208c05ca8e1ebf0dfd81f1917696b197a /MediaBrowser.Controller/Entities/Folder.cs | |
| parent | a2b792e38697d8b11453254c77be62a2116a6e6a (diff) | |
Fix recursive children lookup of folders (#8678)
Fixes https://github.com/jellyfin/jellyfin/issues/6193
Fixes https://github.com/jellyfin/jellyfin/issues/7226
Diffstat (limited to 'MediaBrowser.Controller/Entities/Folder.cs')
| -rw-r--r-- | MediaBrowser.Controller/Entities/Folder.cs | 54 |
1 files changed, 26 insertions, 28 deletions
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index e586205c3..bccb4107f 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -1300,8 +1300,15 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// Adds the children to list. /// </summary> - private void AddChildren(User user, bool includeLinkedChildren, Dictionary<Guid, BaseItem> result, bool recursive, InternalItemsQuery query) + private void AddChildren(User user, bool includeLinkedChildren, Dictionary<Guid, BaseItem> result, bool recursive, InternalItemsQuery query, HashSet<Folder> visitedFolders = null) { + // Prevent infinite recursion of nested folders + visitedFolders ??= new HashSet<Folder>(); + if (!visitedFolders.Add(this)) + { + return; + } + // If Query.AlbumFolders is set, then enforce the format as per the db in that it permits sub-folders in music albums. IEnumerable<BaseItem> children = null; if ((query?.DisplayAlbumFolders ?? false) && (this is MusicAlbum)) @@ -1316,42 +1323,33 @@ namespace MediaBrowser.Controller.Entities children = GetEligibleChildrenForRecursiveChildren(user); } - foreach (var child in children) + AddChildrenFromCollection(children, user, includeLinkedChildren, result, recursive, query, visitedFolders); + + if (includeLinkedChildren) { - bool? isVisibleToUser = null; + AddChildrenFromCollection(GetLinkedChildren(user), user, includeLinkedChildren, result, recursive, query, visitedFolders); + } + } - if (query is null || UserViewBuilder.FilterItem(child, query)) + private void AddChildrenFromCollection(IEnumerable<BaseItem> children, User user, bool includeLinkedChildren, Dictionary<Guid, BaseItem> result, bool recursive, InternalItemsQuery query, HashSet<Folder> visitedFolders) + { + foreach (var child in children) + { + if (!child.IsVisible(user)) { - isVisibleToUser = child.IsVisible(user); - - if (isVisibleToUser.Value) - { - result[child.Id] = child; - } + continue; } - if (isVisibleToUser ?? child.IsVisible(user)) + if (query is null || UserViewBuilder.FilterItem(child, query)) { - if (recursive && child.IsFolder) - { - var folder = (Folder)child; - - folder.AddChildren(user, includeLinkedChildren, result, true, query); - } + result[child.Id] = child; } - } - if (includeLinkedChildren) - { - foreach (var child in GetLinkedChildren(user)) + if (recursive && child.IsFolder) { - if (query is null || UserViewBuilder.FilterItem(child, query)) - { - if (child.IsVisible(user)) - { - result[child.Id] = child; - } - } + var folder = (Folder)child; + + folder.AddChildren(user, includeLinkedChildren, result, true, query, visitedFolders); } } } |
