summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoas Schilling <nickvergessen@gmx.de>2014-11-19 16:29:30 +0100
committerJoas Schilling <nickvergessen@gmx.de>2014-11-19 16:29:30 +0100
commit54607a2142037635c88c97dd093ea9b1d45a30fb (patch)
treee77684bf5adf7d366f94e40b7773e109cfe9f2fd
parent6a6b645b83384df2512d846315fd51b02af075a0 (diff)
parentf235e8b80345ee68ec6d56f12df2a8e77b6da7e0 (diff)
downloadnextcloud-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.php75
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;