diff options
Diffstat (limited to 'lib/private/Files/Utils')
-rw-r--r-- | lib/private/Files/Utils/PathHelper.php | 2 | ||||
-rw-r--r-- | lib/private/Files/Utils/Scanner.php | 25 |
2 files changed, 23 insertions, 4 deletions
diff --git a/lib/private/Files/Utils/PathHelper.php b/lib/private/Files/Utils/PathHelper.php index a6ae029b957..db1294bcc10 100644 --- a/lib/private/Files/Utils/PathHelper.php +++ b/lib/private/Files/Utils/PathHelper.php @@ -37,6 +37,8 @@ class PathHelper { if ($path === '' or $path === '/') { return '/'; } + // No null bytes + $path = str_replace(chr(0), '', $path); //no windows style slashes $path = str_replace('\\', '/', $path); //add leading slash diff --git a/lib/private/Files/Utils/Scanner.php b/lib/private/Files/Utils/Scanner.php index bcc54dea0dc..576cb66b3cf 100644 --- a/lib/private/Files/Utils/Scanner.php +++ b/lib/private/Files/Utils/Scanner.php @@ -23,11 +23,13 @@ use OCP\Files\Events\FileScannedEvent; use OCP\Files\Events\FolderScannedEvent; use OCP\Files\Events\NodeAddedToCache; use OCP\Files\Events\NodeRemovedFromCache; +use OCP\Files\Mount\IMountPoint; use OCP\Files\NotFoundException; use OCP\Files\Storage\IStorage; use OCP\Files\StorageNotAvailableException; use OCP\IDBConnection; use OCP\Lock\ILockingProvider; +use OCP\Lock\LockedException; use Psr\Log\LoggerInterface; /** @@ -85,7 +87,7 @@ class Scanner extends PublicEmitter { * get all storages for $dir * * @param string $dir - * @return \OC\Files\Mount\MountPoint[] + * @return array<string, IMountPoint> */ protected function getMounts($dir) { //TODO: move to the node based fileapi once that's done @@ -96,8 +98,9 @@ class Scanner extends PublicEmitter { $mounts = $mountManager->findIn($dir); $mounts[] = $mountManager->find($dir); $mounts = array_reverse($mounts); //start with the mount of $dir + $mountPoints = array_map(fn ($mount) => $mount->getMountPoint(), $mounts); - return $mounts; + return array_combine($mountPoints, $mounts); } /** @@ -106,6 +109,7 @@ class Scanner extends PublicEmitter { * @param \OC\Files\Mount\MountPoint $mount */ protected function attachListener($mount) { + /** @var \OC\Files\Cache\Scanner $scanner */ $scanner = $mount->getStorage()->getScanner(); $scanner->listen('\OC\Files\Cache\Scanner', 'scanFile', function ($path) use ($mount) { $this->emit('\OC\Files\Utils\Scanner', 'scanFile', [$mount->getMountPoint() . $path]); @@ -145,6 +149,7 @@ class Scanner extends PublicEmitter { continue; } + /** @var \OC\Files\Cache\Scanner $scanner */ $scanner = $storage->getScanner(); $this->attachListener($mount); @@ -200,7 +205,10 @@ class Scanner extends PublicEmitter { foreach (['', 'files'] as $path) { if (!$storage->isCreatable($path)) { $fullPath = $storage->getSourcePath($path); - if (!$storage->is_dir($path) && $storage->getCache()->inCache($path)) { + if (isset($mounts[$mount->getMountPoint() . $path . '/'])) { + // /<user>/files is overwritten by a mountpoint, so this check is irrelevant + break; + } elseif (!$storage->is_dir($path) && $storage->getCache()->inCache($path)) { throw new NotFoundException("User folder $fullPath exists in cache but not on disk"); } elseif ($storage->is_dir($path)) { $ownerUid = fileowner($fullPath); @@ -221,6 +229,7 @@ class Scanner extends PublicEmitter { continue; } $relativePath = $mount->getInternalPath($dir); + /** @var \OC\Files\Cache\Scanner $scanner */ $scanner = $storage->getScanner(); $scanner->setUseTransactions(false); $this->attachListener($mount); @@ -252,7 +261,15 @@ class Scanner extends PublicEmitter { try { $propagator = $storage->getPropagator(); $propagator->beginBatch(); - $scanner->scan($relativePath, $recursive, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE); + try { + $scanner->scan($relativePath, $recursive, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE); + } catch (LockedException $e) { + if (is_string($e->getReadablePath()) && str_starts_with($e->getReadablePath(), 'scanner::')) { + throw new LockedException("scanner::$dir", $e, $e->getExistingLock()); + } else { + throw $e; + } + } $cache = $storage->getCache(); if ($cache instanceof Cache) { // only re-calculate for the root folder we scanned, anything below that is taken care of by the scanner |