]> source.dussan.org Git - nextcloud-server.git/commitdiff
fix(files_external): on case insensitive system, block case change 41222/head
authorBenjamin Gaussorgues <benjamin.gaussorgues@nextcloud.com>
Mon, 23 Oct 2023 08:15:46 +0000 (10:15 +0200)
committerbackportbot-nextcloud[bot] <backportbot-nextcloud[bot]@users.noreply.github.com>
Tue, 31 Oct 2023 15:26:46 +0000 (15:26 +0000)
When a file/directory is renamed to the same name with only case change,
the rename fail. We block this kind of rename.
The user will have to rename to another name first.

Signed-off-by: Benjamin Gaussorgues <benjamin.gaussorgues@nextcloud.com>
apps/files_external/lib/Lib/Backend/SMB.php
apps/files_external/lib/Lib/Storage/SMB.php

index bf73c5b40f844bd445f9bc22f0ac4dddce60fa0c..6c87967608876dbb52eb2f61ec11e05aba072e67 100644 (file)
@@ -59,6 +59,11 @@ class SMB extends Backend {
                                (new DefinitionParameter('show_hidden', $l->t('Show hidden files')))
                                        ->setType(DefinitionParameter::VALUE_BOOLEAN)
                                        ->setFlag(DefinitionParameter::FLAG_OPTIONAL),
+                               (new DefinitionParameter('case_sensitive', $l->t('Case sensitive file system')))
+                                       ->setType(DefinitionParameter::VALUE_BOOLEAN)
+                                       ->setFlag(DefinitionParameter::FLAG_OPTIONAL)
+                                       ->setDefaultValue(true)
+                                       ->setTooltip($l->t('Disabling it will allow to use a case insentive file system, but comes with a performance penalty')),
                                (new DefinitionParameter('check_acl', $l->t('Verify ACL access when listing files')))
                                        ->setType(DefinitionParameter::VALUE_BOOLEAN)
                                        ->setFlag(DefinitionParameter::FLAG_OPTIONAL)
index 1d4cf5a7a2ebdb2fbca3250baf9b51f6b8f56d6c..7ceb5882b881d896badbec13d455ee58e884849f 100644 (file)
@@ -93,6 +93,8 @@ class SMB extends Common implements INotifyStorage {
        /** @var bool */
        protected $showHidden;
 
+       private bool $caseSensitive;
+
        /** @var bool */
        protected $checkAcl;
 
@@ -132,6 +134,7 @@ class SMB extends Common implements INotifyStorage {
                $this->root = rtrim($this->root, '/') . '/';
 
                $this->showHidden = isset($params['show_hidden']) && $params['show_hidden'];
+               $this->caseSensitive = (bool) ($params['case_sensitive'] ?? true);
                $this->checkAcl = isset($params['check_acl']) && $params['check_acl'];
 
                $this->statCache = new CappedMemoryCache();
@@ -314,6 +317,12 @@ class SMB extends Common implements INotifyStorage {
                if ($this->isRootDir($source) || $this->isRootDir($target)) {
                        return false;
                }
+               if ($this->caseSensitive === false
+                       && mb_strtolower($target) === mb_strtolower($source)
+               ) {
+                       // Forbid changing case only on case-insensitive file system
+                       return false;
+               }
 
                $absoluteSource = $this->buildPath($source);
                $absoluteTarget = $this->buildPath($target);
@@ -663,6 +672,16 @@ class SMB extends Common implements INotifyStorage {
 
        public function file_exists($path) {
                try {
+                       if ($this->caseSensitive === false) {
+                               $filename = basename($path);
+                               $siblings = $this->getDirectoryContent(dirname($this->buildPath($path)));
+                               foreach ($siblings as $sibling) {
+                                       if ($sibling['name'] === $filename) {
+                                               return true;
+                                       }
+                               }
+                               return false;
+                       }
                        $this->getFileInfo($path);
                        return true;
                } catch (NotFoundException $e) {