Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion apps/dav/lib/Connector/Sabre/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,14 @@ public function put($data) {
$renameOkay = $storage->moveFromStorage($partStorage, $internalPartPath, $internalPath);
$fileExists = $storage->file_exists($internalPath);
if ($renameOkay === false || $fileExists === false) {
Server::get(LoggerInterface::class)->error('renaming part file to final file failed $renameOkay: ' . ($renameOkay ? 'true' : 'false') . ', $fileExists: ' . ($fileExists ? 'true' : 'false') . ')', ['app' => 'webdav']);
Server::get(LoggerInterface::class)
->error('renaming part file to final file failed $renameOkay: ' . ($renameOkay ? 'true' : 'false') . ', $fileExists: ' . ($fileExists ? 'true' : 'false') . ')', [
'app' => 'webdav',
'source_storage' => $partStorage->getId(),
'target_storage' => $storage->getId(),
'source_internal_path' => $internalPartPath,
'target_internal_path' => $internalPath,
]);
throw new Exception($this->l10n->t('Could not rename part file to final file'));
}
} catch (ForbiddenException $ex) {
Expand Down
37 changes: 31 additions & 6 deletions lib/private/Files/Storage/Local.php
Original file line number Diff line number Diff line change
Expand Up @@ -355,18 +355,20 @@ public function rename(string $source, string $target): bool {
$srcParent = dirname($source);
$dstParent = dirname($target);

$logger = Server::get(LoggerInterface::class);

if (!$this->isUpdatable($srcParent)) {
Server::get(LoggerInterface::class)->error('unable to rename, source directory is not writable : ' . $srcParent, ['app' => 'core']);
$logger->error('unable to rename, source directory is not writable : ' . $srcParent, ['app' => 'core']);
return false;
}

if (!$this->isUpdatable($dstParent)) {
Server::get(LoggerInterface::class)->error('unable to rename, destination directory is not writable : ' . $dstParent, ['app' => 'core']);
$logger->error('unable to rename, destination directory is not writable : ' . $dstParent, ['app' => 'core']);
return false;
}

if (!$this->file_exists($source)) {
Server::get(LoggerInterface::class)->error('unable to rename, file does not exists : ' . $source, ['app' => 'core']);
$logger->error('unable to rename, file does not exists : ' . $source, ['app' => 'core']);
return false;
}

Expand All @@ -378,20 +380,43 @@ public function rename(string $source, string $target): bool {
}
}

$absoluteSource = $this->getSourcePath($source);
$absoluteTarget = $this->getSourcePath($target);

if ($this->is_dir($source)) {
$this->checkTreeForForbiddenItems($this->getSourcePath($source));
$this->checkTreeForForbiddenItems($absoluteSource);
}

if (@rename($this->getSourcePath($source), $this->getSourcePath($target))) {
if (@rename($absoluteSource, $absoluteTarget)) {
if ($this->caseInsensitive) {
if (mb_strtolower($target) === mb_strtolower($source) && !$this->file_exists($target)) {
return false;
}
}
return true;
} else {
$logger->error('failed to rename ' . $absoluteSource . ' to ' . $absoluteTarget . ', trying copy+delete fallback instead', [
'app' => 'core',
'last_error' => error_get_last(),
]);
}

return $this->copy($source, $target) && $this->unlink($source);
if (!$this->copy($source, $target)) {
$logger->error('failed to copy ' . $absoluteSource . ' to ' . $absoluteTarget . ' as part of rename fallback', [
'app' => 'core',
'last_error' => error_get_last(),
]);
return false;
}

if (!$this->unlink($source)) {
$logger->error('failed to delete ' . $absoluteSource . ' as part of rename fallback', [
'app' => 'core',
'last_error' => error_get_last(),
]);
return false;
}
return true;
}

#[\Override]
Expand Down
Loading