diff options
author | Benjamin Gaussorgues <benjamin.gaussorgues@nextcloud.com> | 2023-11-16 16:34:12 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-16 16:34:12 +0100 |
commit | 902ba76d3006f915d81f7357e1ac64f3af2d2407 (patch) | |
tree | 0110a64cc70e80384da5543712f787f66a0c2375 | |
parent | 1af4301997c4d4979a9a43acb5450a436f672eb2 (diff) | |
parent | 482deca3543ecfed3041bdf8516c89094309794e (diff) | |
download | nextcloud-server-902ba76d3006f915d81f7357e1ac64f3af2d2407.tar.gz nextcloud-server-902ba76d3006f915d81f7357e1ac64f3af2d2407.zip |
Merge pull request #41502 from nextcloud/backport/40935/stable27
[stable27] add some support for rename on case insensitive local filesystems
-rw-r--r-- | lib/private/Files/Storage/Local.php | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/lib/private/Files/Storage/Local.php b/lib/private/Files/Storage/Local.php index 3b292506578..813e5aa09d7 100644 --- a/lib/private/Files/Storage/Local.php +++ b/lib/private/Files/Storage/Local.php @@ -73,6 +73,8 @@ class Local extends \OC\Files\Storage\Common { protected bool $unlinkOnTruncate; + protected bool $caseInsensitive = false; + public function __construct($arguments) { if (!isset($arguments['datadir']) || !is_string($arguments['datadir'])) { throw new \InvalidArgumentException('No data directory set for local storage'); @@ -92,6 +94,7 @@ class Local extends \OC\Files\Storage\Common { $this->config = \OC::$server->get(IConfig::class); $this->mimeTypeDetector = \OC::$server->get(IMimeTypeDetector::class); $this->defUMask = $this->config->getSystemValue('localstorage.umask', 0022); + $this->caseInsensitive = $this->config->getSystemValueBool('localstorage.case_insensitive', false); // support Write-Once-Read-Many file systems $this->unlinkOnTruncate = $this->config->getSystemValueBool('localstorage.unlink_on_truncate', false); @@ -155,6 +158,9 @@ class Local extends \OC\Files\Storage\Common { } public function is_dir($path) { + if ($this->caseInsensitive && !$this->file_exists($path)) { + return false; + } if (substr($path, -1) == '/') { $path = substr($path, 0, -1); } @@ -162,6 +168,9 @@ class Local extends \OC\Files\Storage\Common { } public function is_file($path) { + if ($this->caseInsensitive && !$this->file_exists($path)) { + return false; + } return is_file($this->getSourcePath($path)); } @@ -264,7 +273,13 @@ class Local extends \OC\Files\Storage\Common { } public function file_exists($path) { - return file_exists($this->getSourcePath($path)); + if ($this->caseInsensitive) { + $fullPath = $this->getSourcePath($path); + $content = scandir(dirname($fullPath), SCANDIR_SORT_NONE); + return is_array($content) && array_search(basename($fullPath), $content) !== false; + } else { + return file_exists($this->getSourcePath($path)); + } } public function filemtime($path) { @@ -375,7 +390,16 @@ class Local extends \OC\Files\Storage\Common { $this->checkTreeForForbiddenItems($this->getSourcePath($source)); } - return rename($this->getSourcePath($source), $this->getSourcePath($target)); + if (rename($this->getSourcePath($source), $this->getSourcePath($target))) { + if ($this->caseInsensitive) { + if (mb_strtolower($target) === mb_strtolower($source) && !$this->file_exists($target)) { + return false; + } + } + return true; + } + + return false; } public function copy($source, $target) { @@ -388,6 +412,11 @@ class Local extends \OC\Files\Storage\Common { } $result = copy($this->getSourcePath($source), $this->getSourcePath($target)); umask($oldMask); + if ($this->caseInsensitive) { + if (mb_strtolower($target) === mb_strtolower($source) && !$this->file_exists($target)) { + return false; + } + } return $result; } } |