From 43a93353557c8b827d66b37620907d33b4478e02 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 14 Jan 2026 16:59:54 +0100 Subject: [PATCH] fix: attempt to make share conflict resolution more resilient to false positives Signed-off-by: Robin Appelman --- .../lib/ShareTargetValidator.php | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/lib/ShareTargetValidator.php b/apps/files_sharing/lib/ShareTargetValidator.php index c2f00d27ccb..f063f77f96d 100644 --- a/apps/files_sharing/lib/ShareTargetValidator.php +++ b/apps/files_sharing/lib/ShareTargetValidator.php @@ -85,6 +85,7 @@ class ShareTargetValidator { } $newAbsoluteMountPoint = $this->generateUniqueTarget( + $share, Filesystem::normalizePath($absoluteParent . '/' . $mountPoint), $parentMount, $allCachedMounts, @@ -107,7 +108,12 @@ class ShareTargetValidator { /** * @param ICachedMountInfo[] $allCachedMounts */ - private function generateUniqueTarget(string $absolutePath, IMountPoint $parentMount, array $allCachedMounts): string { + private function generateUniqueTarget( + IShare $share, + string $absolutePath, + IMountPoint $parentMount, + array $allCachedMounts, + ): string { $pathInfo = pathinfo($absolutePath); $ext = isset($pathInfo['extension']) ? '.' . $pathInfo['extension'] : ''; $name = $pathInfo['filename']; @@ -116,7 +122,7 @@ class ShareTargetValidator { $i = 2; $parentCache = $parentMount->getStorage()->getCache(); $internalPath = $parentMount->getInternalPath($absolutePath); - while ($parentCache->inCache($internalPath) || isset($allCachedMounts[$absolutePath . '/'])) { + while ($parentCache->inCache($internalPath) || $this->hasConflictingMount($share, $allCachedMounts, $absolutePath)) { $absolutePath = Filesystem::normalizePath($dir . '/' . $name . ' (' . $i . ')' . $ext); $internalPath = $parentMount->getInternalPath($absolutePath); $i++; @@ -125,6 +131,23 @@ class ShareTargetValidator { return $absolutePath; } + /** + * @param ICachedMountInfo[] $allCachedMounts + */ + private function hasConflictingMount(IShare $share, array $allCachedMounts, string $absolutePath): bool { + if (!isset($allCachedMounts[$absolutePath . '/'])) { + return false; + } + + $mount = $allCachedMounts[$absolutePath . '/']; + if ($mount->getMountProvider() === MountProvider::class && $mount->getRootId() === $share->getNodeId()) { + // "conflicting" mount is a mount for the current share + return false; + } + + return true; + } + /** * update fileTarget in the database if the mount point changed *