aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFerdinand Thiessen <opensource@fthiessen.de>2025-03-14 17:59:47 +0100
committerFerdinand Thiessen <opensource@fthiessen.de>2025-04-22 11:09:25 +0200
commitb4255a96529ac1ac61b84170bd5965f3fe07a979 (patch)
tree2e4be02c20b26a5bde14c293c8a9689256e525cd
parent6141ab1da6770c143f538d66c51343d7b13b3a61 (diff)
downloadnextcloud-server-fix/path-length.tar.gz
nextcloud-server-fix/path-length.zip
fix(dav): allow uploading of files with long filenamesfix/path-length
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.php12
-rw-r--r--build/integration/dav_features/dav-v2.feature29
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 777abc1daa2..045b9d7e784 100644
--- a/apps/dav/lib/Connector/Sabre/File.php
+++ b/apps/dav/lib/Connector/Sabre/File.php
@@ -129,8 +129,9 @@ class File extends Node implements IFile {
$view = 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;
@@ -377,9 +378,14 @@ class File extends Node implements IFile {
private function getPartFileBasePath($path) {
$partFileInStorage = Server::get(IConfig::class)->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 a9e62c8ac9e..9eae9a1b5fd 100644
--- a/build/integration/dav_features/dav-v2.feature
+++ b/build/integration/dav_features/dav-v2.feature
@@ -108,6 +108,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"
@@ -132,3 +150,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"