diff options
author | Joas Schilling <nickvergessen@gmx.de> | 2014-11-19 16:29:30 +0100 |
---|---|---|
committer | Joas Schilling <nickvergessen@gmx.de> | 2014-11-19 16:29:30 +0100 |
commit | 54607a2142037635c88c97dd093ea9b1d45a30fb (patch) | |
tree | e77684bf5adf7d366f94e40b7773e109cfe9f2fd | |
parent | 6a6b645b83384df2512d846315fd51b02af075a0 (diff) | |
parent | f235e8b80345ee68ec6d56f12df2a8e77b6da7e0 (diff) | |
download | nextcloud-server-54607a2142037635c88c97dd093ea9b1d45a30fb.tar.gz nextcloud-server-54607a2142037635c88c97dd093ea9b1d45a30fb.zip |
Merge pull request #12288 from owncloud/backport-mapper-fixes
Backport mapper fixes
-rw-r--r-- | lib/private/files/mapper.php | 75 |
1 files changed, 49 insertions, 26 deletions
diff --git a/lib/private/files/mapper.php b/lib/private/files/mapper.php index 666719da12d..5e78ef03dd0 100644 --- a/lib/private/files/mapper.php +++ b/lib/private/files/mapper.php @@ -66,8 +66,8 @@ class Mapper */ public function copy($path1, $path2) { - $path1 = $this->stripLast($path1); - $path2 = $this->stripLast($path2); + $path1 = $this->resolveRelativePath($path1); + $path2 = $this->resolveRelativePath($path2); $physicPath1 = $this->logicToPhysical($path1, true); $physicPath2 = $this->logicToPhysical($path2, true); @@ -113,18 +113,11 @@ class Mapper return ''; } - private function stripLast($path) { - if (substr($path, -1) == '/') { - $path = substr_replace($path, '', -1); - } - return $path; - } - /** * @param string $logicPath */ private function resolveLogicPath($logicPath) { - $logicPath = $this->stripLast($logicPath); + $logicPath = $this->resolveRelativePath($logicPath); $sql = 'SELECT * FROM `*PREFIX*file_map` WHERE `logic_path_hash` = ?'; $result = \OC_DB::executeAudited($sql, array(md5($logicPath))); $result = $result->fetchRow(); @@ -136,7 +129,7 @@ class Mapper } private function resolvePhysicalPath($physicalPath) { - $physicalPath = $this->stripLast($physicalPath); + $physicalPath = $this->resolveRelativePath($physicalPath); $sql = \OC_DB::prepare('SELECT * FROM `*PREFIX*file_map` WHERE `physic_path_hash` = ?'); $result = \OC_DB::executeAudited($sql, array(md5($physicalPath))); $result = $result->fetchRow(); @@ -144,12 +137,35 @@ class Mapper return $result['logic_path']; } + private function resolveRelativePath($path) { + $explodedPath = explode('/', $path); + $pathArray = array(); + foreach ($explodedPath as $pathElement) { + if (empty($pathElement) || ($pathElement == '.')) { + continue; + } elseif ($pathElement == '..') { + if (count($pathArray) == 0) { + return false; + } + array_pop($pathArray); + } else { + array_push($pathArray, $pathElement); + } + } + if (substr($path, 0, 1) == '/') { + $path = '/'; + } else { + $path = ''; + } + return $path.implode('/', $pathArray); + } + /** * @param string $logicPath * @param boolean $store */ private function create($logicPath, $store) { - $logicPath = $this->stripLast($logicPath); + $logicPath = $this->resolveRelativePath($logicPath); $index = 0; // create the slugified path @@ -177,14 +193,12 @@ class Mapper /** * @param integer $index */ - public function slugifyPath($path, $index=null) { + public function slugifyPath($path, $index = null) { $path = $this->stripRootFolder($path, $this->unchangedPhysicalRoot); $pathElements = explode('/', $path); $sluggedElements = array(); - - $last= end($pathElements); - + foreach ($pathElements as $pathElement) { // remove empty elements if (empty($pathElement)) { @@ -196,20 +210,19 @@ class Mapper // apply index to file name if ($index !== null) { - $last= array_pop($sluggedElements); + $last = array_pop($sluggedElements); // if filename contains periods - add index number before last period - if (preg_match('~\.[^\.]+$~i',$last,$extension)){ - array_push($sluggedElements, substr($last,0,-(strlen($extension[0]))).'-'.$index.$extension[0]); + if (preg_match('~\.[^\.]+$~i', $last, $extension)) { + array_push($sluggedElements, substr($last, 0, -(strlen($extension[0]))) . '-' . $index . $extension[0]); } else { // if filename doesn't contain periods add index ofter the last char - array_push($sluggedElements, $last.'-'.$index); - } - + array_push($sluggedElements, $last . '-' . $index); + } } $sluggedPath = $this->unchangedPhysicalRoot.implode('/', $sluggedElements); - return $this->stripLast($sluggedPath); + return $this->resolveRelativePath($sluggedPath); } /** @@ -218,8 +231,8 @@ class Mapper * @param string $text * @return string */ - private function slugify($text) - { + private function slugify($text) { + $originalText = $text; // replace non letter or digits or dots by - $text = preg_replace('~[^\\pL\d\.]+~u', '-', $text); @@ -241,7 +254,17 @@ class Mapper $text = preg_replace('~\.+$~', '', $text); if (empty($text)) { - return uniqid(); + /** + * Item slug would be empty. Previously we used uniqid() here. + * However this means that the behaviour is not reproducible, so + * when uploading files into a "empty" folder, the folders name is + * different. + * + * If there would be a md5() hash collision, the deduplicate check + * will spot this and append an index later, so this should not be + * a problem. + */ + return md5($originalText); } return $text; |