From b344b5323dc69ba95535ca6cd93c54073450216a Mon Sep 17 00:00:00 2001 From: Louis Chmn Date: Wed, 5 Nov 2025 18:23:55 +0100 Subject: [PATCH 1/2] fix(collaboration): Replace NonExisting* check on `NodeDeletedEvent` by a try/catch Deleted nodes are always non existing, but some of them have a fileInfo. This ensure that we still run the cleanup but in a safe way. Signed-off-by: Louis Chmn --- .../Reference/File/FileReferenceEventListener.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/private/Collaboration/Reference/File/FileReferenceEventListener.php b/lib/private/Collaboration/Reference/File/FileReferenceEventListener.php index 9c18531c8e7..0b2385a0555 100644 --- a/lib/private/Collaboration/Reference/File/FileReferenceEventListener.php +++ b/lib/private/Collaboration/Reference/File/FileReferenceEventListener.php @@ -8,21 +8,22 @@ declare(strict_types=1); namespace OC\Collaboration\Reference\File; -use OC\Files\Node\NonExistingFile; -use OC\Files\Node\NonExistingFolder; use OCP\Collaboration\Reference\IReferenceManager; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventDispatcher; use OCP\EventDispatcher\IEventListener; use OCP\Files\Events\Node\NodeDeletedEvent; use OCP\Files\Events\Node\NodeRenamedEvent; +use OCP\Files\NotFoundException; use OCP\Share\Events\ShareCreatedEvent; use OCP\Share\Events\ShareDeletedEvent; +use Psr\Log\LoggerInterface; /** @template-implements IEventListener */ class FileReferenceEventListener implements IEventListener { public function __construct( private IReferenceManager $manager, + private LoggerInterface $logger, ) { } @@ -38,11 +39,12 @@ class FileReferenceEventListener implements IEventListener { */ public function handle(Event $event): void { if ($event instanceof NodeDeletedEvent) { - if ($event->getNode() instanceof NonExistingFolder || $event->getNode() instanceof NonExistingFile) { - return; + try { + $this->manager->invalidateCache((string)$event->getNode()->getId()); + } catch (NotFoundException $e) { + // Non existing node might not have an id + $this->logger->debug('Could not invalidate reference cache for deleted node', ['exception' => $e]); } - - $this->manager->invalidateCache((string)$event->getNode()->getId()); } if ($event instanceof NodeRenamedEvent) { $this->manager->invalidateCache((string)$event->getTarget()->getId()); From 73c6b17fae9df158c478c4f6c17efa1e25e2c5bb Mon Sep 17 00:00:00 2001 From: Louis Chmn Date: Thu, 6 Nov 2025 10:57:19 +0100 Subject: [PATCH 2/2] fix(View): Normalize path in `getAbsolutePath` This allow to match files more consistently in HookConnector::getNodeForPath Signed-off-by: Louis Chmn --- lib/private/Files/View.php | 9 ++------- tests/lib/Files/ViewTest.php | 4 ++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php index ecf2f438edb..c1068d2349b 100644 --- a/lib/private/Files/View.php +++ b/lib/private/Files/View.php @@ -11,6 +11,7 @@ use Icewind\Streams\CallbackWrapper; use OC\Files\Mount\MoveableMount; use OC\Files\Storage\Storage; use OC\Files\Storage\Wrapper\Quota; +use OC\Files\Utils\PathHelper; use OC\Share\Share; use OC\User\LazyUser; use OC\User\Manager as UserManager; @@ -92,13 +93,7 @@ class View { return null; } $this->assertPathLength($path); - if ($path === '') { - $path = '/'; - } - if ($path[0] !== '/') { - $path = '/' . $path; - } - return $this->fakeRoot . $path; + return PathHelper::normalizePath($this->fakeRoot . '/' . $path); } /** diff --git a/tests/lib/Files/ViewTest.php b/tests/lib/Files/ViewTest.php index 57424107401..b9f6b1a7373 100644 --- a/tests/lib/Files/ViewTest.php +++ b/tests/lib/Files/ViewTest.php @@ -917,11 +917,11 @@ class ViewTest extends \Test\TestCase { public static function absolutePathProvider(): array { return [ - ['/files/', ''], + ['/files', ''], ['/files/0', '0'], ['/files/false', 'false'], ['/files/true', 'true'], - ['/files/', '/'], + ['/files', '/'], ['/files/test', 'test'], ['/files/test', '/test'], ];