ITADN

`PreviewController::getFileIdForAlbums()` crashes with "Call to a member function getOwner() on null" → all album previews return HTTP 500`

#3501Openjhchein 创建于 2026-05-04
bug0. Needs triage
J
jhcheincommented
## Describe the bug `OCA\Photos\Controller\PreviewController::getFileIdForAlbums()` does not handle the case where neither `AlbumMapper::getForAlbumIdAndFileId()` nor `FiltersManager::getFilesBasedOnFilters()` return a result for an album in the iteration. When this happens, `$albumFile` stays `null`, and the next line dereferences it: ```php $nodes = $this->rootFolder ->getUserFolder($albumFile->getOwner()) // crashes here (line 135) ->getById($fileId); ``` Result: `Error: Call to a member function getOwner() on null`. Because this aborts the iteration over all albums visible to the user, **every** preview request via `/apps/photos/api/v1/preview/<fileId>` returns HTTP 500 for that user as soon as more than one album is involved — even though the underlying file and all album data are valid. This also breaks `nextcloud/memories`, which uses the Photos preview endpoint as a tile source — the entire grid stays grey. ## Steps to reproduce 1. Owner user creates several albums (mix of own and shared-with-other-user) and adds photos. 2. Share the albums with another user (collaborator). 3. Log in as the collaborator. 4. Open Memories or any UI that requests `/apps/photos/api/v1/preview/<fileId>?x=512&y=512`. 5. Server returns 500 for every tile. In the affected setup, all 11 visible albums had `file_count == resolvable_count` (verified via `oc_photos_albums_files` join `oc_filecache`). Data is clean — the crash is purely a missing null guard in the iteration. ## Expected behavior If a given album does not contain or cannot resolve the requested `$fileId`, skip that album and continue iterating, exactly as the surrounding `if (\count($nodes) === 0)` logic already anticipates. ## Actual behavior First album in the loop where neither `getForAlbumIdAndFileId()` nor `getFilesBasedOnFilters()` produces a result causes a fatal `Error`, returning HTTP 500 for the whole request. ## Stacktrace (Nextcloud log, level 3) ``` Call to a member function getOwner() on null in apps/photos/lib/Controller/PreviewController.php line 135 Trace: apps/photos/lib/Controller/PreviewController.php:95 OCA\Photos\Controller\PreviewController->getFileIdForAlbums( <fileId>, [11 × OCA\Photos\Album\AlbumInfo] ) lib/private/AppFramework/Http/Dispatcher.php:204 ...->index(<fileId>, 512, 512) ``` Preceding notice (level 2): ``` Undefined array key 0 at apps/photos/lib/Album/AlbumMapper.php#209 ``` ## Suggested fix Add a null guard after `array_pop($albumFiles)` in `getFileIdForAlbums()`: ```diff protected function getFileIdForAlbums(int $fileId, array $albums): array { foreach ($albums as $album) { $albumFile = $this->albumMapper->getForAlbumIdAndFileId($album->getId(), $fileId); if ($albumFile === null) { $albumFiles = $this->filtersManager->getFilesBasedOnFilters($album->getUserId(), $album->getDecodedFilters(), $fileId); $albumFile = array_pop($albumFiles); + if ($albumFile === null) { + continue; + } } $nodes = $this->rootFolder ->getUserFolder($albumFile->getOwner()) ->getById($fileId); if (\count($nodes) !== 0) { return $nodes; } } return []; } ``` Verified: with this single line applied, the preview endpoint returns 200 with the expected image, and Memories tiles render correctly. Album functionality is fully restored. The notice in `AlbumMapper.php:209` (`Undefined array key 0`) likely deserves a defensive check on its own, but the `PreviewController` patch alone resolves the user-visible crash. ## Platform - Nextcloud: 32.0.1.2 - Photos app: 5.0.0-dev.1 - PHP: (please fill — `docker exec nextcloud php -v`) - Reverse proxy: Traefik behind Cloudflare - Browsers reproduced in: Safari 18.0.1 (macOS), Firefox, Chrome — server-side issue, browser-independent
0 条评论