diff options
author | Ferdinand Thiessen <opensource@fthiessen.de> | 2025-03-14 17:59:47 +0100 |
---|---|---|
committer | backportbot[bot] <backportbot[bot]@users.noreply.github.com> | 2025-04-23 15:19:36 +0000 |
commit | 744a4394feadfb35593e3d89511a4ad45521990f (patch) | |
tree | 999d0e59ca570f08f09c91d05bdcc18ddb0bd940 | |
parent | 95b5fa203f3584164c3d60f0b8d35b8a4689e494 (diff) | |
download | nextcloud-server-backport/51491/stable30.tar.gz nextcloud-server-backport/51491/stable30.zip |
fix(dav): allow uploading of files with long filenamesbackport/51491/stable30
A filename must be less or equal 255 characters, but when adding the
`.part` and `.ocfiletransfer` extensions we might overflow this limit.
So we should also use filename hashes for uploading when the file has a
long filename, similar like when we are uploading to the user storage
directly.
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
-rw-r--r-- | apps/dav/lib/Connector/Sabre/File.php | 12 | ||||
-rw-r--r-- | build/integration/dav_features/dav-v2.feature | 29 |
2 files changed, 38 insertions, 3 deletions
diff --git a/apps/dav/lib/Connector/Sabre/File.php b/apps/dav/lib/Connector/Sabre/File.php index fc6151ce9a2..7d2933c5014 100644 --- a/apps/dav/lib/Connector/Sabre/File.php +++ b/apps/dav/lib/Connector/Sabre/File.php @@ -124,8 +124,9 @@ class File extends Node implements IFile { $view = \OC\Files\Filesystem::getView(); if ($needsPartFile) { + $transferId = \rand(); // mark file as partial while uploading (ignored by the scanner) - $partFilePath = $this->getPartFileBasePath($this->path) . '.ocTransferId' . rand() . '.part'; + $partFilePath = $this->getPartFileBasePath($this->path) . '.ocTransferId' . $transferId . '.part'; if (!$view->isCreatable($partFilePath) && $view->isUpdatable($this->path)) { $needsPartFile = false; @@ -371,9 +372,14 @@ class File extends Node implements IFile { private function getPartFileBasePath($path) { $partFileInStorage = \OC::$server->getConfig()->getSystemValue('part_file_in_storage', true); if ($partFileInStorage) { - return $path; + $filename = basename($path); + // hash does not need to be secure but fast and semi unique + $hashedFilename = hash('xxh128', $filename); + return substr($path, 0, strlen($path) - strlen($filename)) . $hashedFilename; } else { - return md5($path); // will place it in the root of the view with a unique name + // will place the .part file in the users root directory + // therefor we need to make the name (semi) unique - hash does not need to be secure but fast. + return hash('xxh128', $path); } } diff --git a/build/integration/dav_features/dav-v2.feature b/build/integration/dav_features/dav-v2.feature index baaabc07f20..75adba46187 100644 --- a/build/integration/dav_features/dav-v2.feature +++ b/build/integration/dav_features/dav-v2.feature @@ -93,6 +93,24 @@ Feature: dav-v2 When User "user0" uploads file "data/textfile.txt" to "/testquota/asdf.txt" Then the HTTP status code should be "201" + Scenario: Uploading a file with very long filename + Given using new dav path + And As an "admin" + And user "user0" exists + And user "user0" has a quota of "10 MB" + And As an "user0" + When User "user0" uploads file "data/textfile.txt" to "/long-filename-with-250-characters-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.txt" + Then the HTTP status code should be "201" + + Scenario: Uploading a file with a too long filename + Given using new dav path + And As an "admin" + And user "user0" exists + And user "user0" has a quota of "10 MB" + And As an "user0" + When User "user0" uploads file "data/textfile.txt" to "/long-filename-with-251-characters-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.txt" + Then the HTTP status code should be "400" + Scenario: Create a search query on image Given using new dav path And As an "admin" @@ -117,3 +135,14 @@ Feature: dav-v2 Then Favorite search should work And the single response should contain a property "{http://owncloud.org/ns}favorite" with value "1" + Scenario: Create a search query on favorite + Given using new dav path + And As an "admin" + And user "user0" exists + And As an "user0" + When User "user0" uploads file "data/green-square-256.png" to "/fav_image.png" + Then Favorite search should work + And the response should be empty + When user "user0" favorites element "/fav_image.png" + Then Favorite search should work + And the single response should contain a property "{http://owncloud.org/ns}favorite" with value "1" |