From 0293d8e04f614c330be8aac7e968eec8469fb0e5 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 8 Oct 2013 11:26:49 +0200 Subject: [PATCH 1/3] If a existing file in Shared/ with update permissions gets updated we need to write the .part file to a different place because we can't create new files in the Shared folder --- lib/private/connector/sabre/file.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php index 12d7585884..43e25de40c 100644 --- a/lib/private/connector/sabre/file.php +++ b/lib/private/connector/sabre/file.php @@ -45,7 +45,9 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D * @return string|null */ public function put($data) { + $fs = $this->getFS(); + if ($fs->file_exists($this->path) && !$fs->isUpdatable($this->path)) { throw new \Sabre_DAV_Exception_Forbidden(); @@ -58,12 +60,14 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D // chunked handling if (isset($_SERVER['HTTP_OC_CHUNKED'])) { + list($path, $name) = \Sabre_DAV_URLUtil::splitPath($this->path); $info = OC_FileChunking::decodeName($name); if (empty($info)) { throw new Sabre_DAV_Exception_NotImplemented(); } + $chunk_handler = new OC_FileChunking($info); $chunk_handler->store($info['index'], $data); if ($chunk_handler->isComplete()) { @@ -78,6 +82,13 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D // mark file as partial while uploading (ignored by the scanner) $partpath = $this->path . '.part'; + // if file is located in /Shared we write the part file to the users + // root folder because we can't create new files in /shared + // we extend the name with a random number to avoid overwriting a existing file + if (dirname($partpath) === 'Shared') { + $partpath = pathinfo($partpath, PATHINFO_FILENAME) . rand(); + } + try { $putOkay = $fs->file_put_contents($partpath, $data); if ($putOkay === false) { From dd202d9ad3a542cb4c86baad92cadb2cb975afcf Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 8 Oct 2013 11:27:08 +0200 Subject: [PATCH 2/3] updating a existing large file creates new file chunks. Therefore createFile() needs to check not only if we can write to the parent folder but also if we can update the existing file" --- lib/private/connector/sabre/directory.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/private/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php index af0dfd70f0..d033478036 100644 --- a/lib/private/connector/sabre/directory.php +++ b/lib/private/connector/sabre/directory.php @@ -50,8 +50,22 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa */ public function createFile($name, $data = null) { - if (!\OC\Files\Filesystem::isCreatable($this->path)) { - throw new \Sabre_DAV_Exception_Forbidden(); + // for chunked upload also updating a existing file is a "createFile" + // because we create all the chunks before reasamble them to the existing file. + if (isset($_SERVER['HTTP_OC_CHUNKED'])) { + + // exit if we can't create a new file and we don't updatable existing file + $info = OC_FileChunking::decodeName($name); + if (!\OC\Files\Filesystem::isCreatable($this->path) && + !\OC\Files\Filesystem::isUpdatable($this->path . '/' . $info['name'])) { + throw new \Sabre_DAV_Exception_Forbidden(); + } + + } else { + // For non-chunked upload it is enough to check if we can create a new file + if (!\OC\Files\Filesystem::isCreatable($this->path)) { + throw new \Sabre_DAV_Exception_Forbidden(); + } } $path = $this->path . '/' . $name; From 6c45fab0375bd8e6c02ba3081da7442b6d783c86 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Tue, 8 Oct 2013 12:00:32 +0200 Subject: [PATCH 3/3] part file needs to have .part extension --- lib/private/connector/sabre/file.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php index 43e25de40c..037dba7f37 100644 --- a/lib/private/connector/sabre/file.php +++ b/lib/private/connector/sabre/file.php @@ -86,7 +86,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D // root folder because we can't create new files in /shared // we extend the name with a random number to avoid overwriting a existing file if (dirname($partpath) === 'Shared') { - $partpath = pathinfo($partpath, PATHINFO_FILENAME) . rand(); + $partpath = pathinfo($partpath, PATHINFO_FILENAME) . rand() . '.part'; } try {