From 255cdb2caa7d4fd2f8538126254d4c6b27f5b26b Mon Sep 17 00:00:00 2001 From: Yaroslav98214 Date: Wed, 4 Feb 2026 21:02:12 +0000 Subject: [PATCH] fix: normalize object store paths for writeStream Signed-off-by: Yaroslav98214 --- lib/private/Files/ObjectStore/ObjectStoreStorage.php | 3 ++- .../lib/Files/ObjectStore/ObjectStoreStorageTest.php | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php index ce5fc5b1063ba..338061f0ee741 100644 --- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php +++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php @@ -123,7 +123,7 @@ public function mkdir(string $path, bool $force = false, array $metadata = []): private function normalizePath(string $path): string { $path = trim($path, '/'); //FIXME why do we sometimes get a path like 'files//username'? - $path = str_replace('//', '/', $path); + $path = preg_replace('#/{2,}#', '/', $path); // dirname('/folder') returns '.' but internally (in the cache) we store the root as '' if (!$path || $path === '.') { @@ -456,6 +456,7 @@ public function file_put_contents(string $path, mixed $data): int { } public function writeStream(string $path, $stream, ?int $size = null): int { + $path = $this->normalizePath($path); if ($size === null) { $stats = fstat($stream); if (is_array($stats) && isset($stats['size'])) { diff --git a/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php b/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php index f980b49172f7a..df9f219bf2f14 100644 --- a/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php +++ b/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php @@ -67,6 +67,18 @@ public function testStat(): void { } } + public function testWriteStreamNormalizesPath(): void { + $this->instance->mkdir('files'); + $this->instance->mkdir('files/user'); + + $this->instance->file_put_contents('files//user/test.txt', 'foo'); + + $cache = $this->instance->getCache(); + $this->assertTrue($cache->inCache('files/user/test.txt')); + $this->assertFalse($cache->inCache('files//user/test.txt')); + $this->assertEquals('foo', $this->instance->file_get_contents('files/user/test.txt')); + } + public function testCheckUpdate(): void { $this->markTestSkipped('Detecting external changes is not supported on object storages'); }