From 53a888cc8130a81961dece245b35a226be4d67ab Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 17 Aug 2012 01:22:26 +0200 Subject: [PATCH] more path normalization --- apps/files/index.php | 2 +- lib/files.php | 4 ++ lib/filesystem.php | 13 ++++- lib/filesystemview.php | 118 +++++++++++++++++++++------------------ tests/lib/filesystem.php | 1 + 5 files changed, 80 insertions(+), 58 deletions(-) diff --git a/apps/files/index.php b/apps/files/index.php index 79bed8e357..e1c4ad7f19 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -92,7 +92,7 @@ $maxUploadFilesize = min($maxUploadFilesize ,$freeSpace); $tmpl = new OCP\Template( 'files', 'index', 'user' ); $tmpl->assign( 'fileList', $list->fetchPage(), false ); $tmpl->assign( 'breadcrumb', $breadcrumbNav->fetchPage(), false ); -$tmpl->assign( 'dir', $dir); +$tmpl->assign( 'dir', OC_Filesystem::normalizePath($dir)); $tmpl->assign( 'readonly', !OC_Filesystem::is_writable($dir.'/')); $tmpl->assign( 'files', $files ); $tmpl->assign( 'uploadMaxFilesize', $maxUploadFilesize); diff --git a/lib/files.php b/lib/files.php index d5bebb7e54..b9c2ead944 100644 --- a/lib/files.php +++ b/lib/files.php @@ -33,6 +33,10 @@ class OC_Files { * @param dir $directory path under datadirectory */ public static function getDirectoryContent($directory, $mimetype_filter = ''){ + $directory=OC_Filesystem::normalizePath($directory); + if($directory=='/'){ + $directory=''; + } $files=OC_FileCache::getFolderContent($directory, false, $mimetype_filter); foreach($files as &$file){ $file['directory']=$directory; diff --git a/lib/filesystem.php b/lib/filesystem.php index 6cba6b1b54..ffb8643d49 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -495,7 +495,16 @@ class OC_Filesystem{ OC_Connector_Sabre_Node::removeETagPropertyForPath($path); } - public static function normalizePath($path){ + /** + * normalize a path + * @param string path + * @param bool $stripTrailingSlash + * @return string + */ + public static function normalizePath($path,$stripTrailingSlash=true){ + if($path==''){ + return '/'; + } //no windows style slashes $path=str_replace('\\','/',$path); //add leading slash @@ -503,7 +512,7 @@ class OC_Filesystem{ $path='/'.$path; } //remove trainling slash - if(strlen($path)>1 and substr($path,-1,1)==='/'){ + if($stripTrailingSlash and strlen($path)>1 and substr($path,-1,1)==='/'){ $path=substr($path,0,-1); } //remove duplicate slashes diff --git a/lib/filesystemview.php b/lib/filesystemview.php index 9d85befdc8..571c75f8f3 100644 --- a/lib/filesystemview.php +++ b/lib/filesystemview.php @@ -54,7 +54,7 @@ class OC_FilesystemView { if($path[0]!=='/'){ $path='/'.$path; } - return OC_Filesystem::normalizePath($this->fakeRoot.$path); + return $this->fakeRoot.$path; } /** @@ -227,7 +227,7 @@ class OC_FilesystemView { } public function file_put_contents($path, $data) { if(is_resource($data)) {//not having to deal with streams in file_put_contents makes life easier - $absolutePath = $this->getAbsolutePath($path); + $absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); if (OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) && OC_Filesystem::isValidPath($path)) { $path = $this->getRelativePath($absolutePath); $exists = $this->file_exists($path); @@ -287,11 +287,14 @@ class OC_FilesystemView { return $this->basicOperation( 'deleteAll', $directory, array('delete'), $empty ); } public function rename($path1, $path2) { - $absolutePath1 = $this->getAbsolutePath($path1); - $absolutePath2 = $this->getAbsolutePath($path2); + $postFix1=(substr($path1,-1,1)==='/')?'/':''; + $postFix2=(substr($path2,-1,1)==='/')?'/':''; + $absolutePath1 = OC_Filesystem::normalizePath($this->getAbsolutePath($path1)); + $absolutePath2 = OC_Filesystem::normalizePath($this->getAbsolutePath($path2)); if(OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { $path1 = $this->getRelativePath($absolutePath1); $path2 = $this->getRelativePath($absolutePath2); + if($path1 == null or $path2 == null) { return false; } @@ -305,20 +308,20 @@ class OC_FilesystemView { ) ); if($run) { - $mp1 = $this->getMountPoint($path1); - $mp2 = $this->getMountPoint($path2); + $mp1 = $this->getMountPoint($path1.$postFix1); + $mp2 = $this->getMountPoint($path2.$postFix2); if($mp1 == $mp2) { if($storage = $this->getStorage($path1)) { - $result = $storage->rename($this->getInternalPath($path1), $this->getInternalPath($path2)); + $result = $storage->rename($this->getInternalPath($path1.$postFix1), $this->getInternalPath($path2.$postFix2)); } } else { - $source = $this->fopen($path1, 'r'); - $target = $this->fopen($path2, 'w'); + $source = $this->fopen($path1.$postFix1, 'r'); + $target = $this->fopen($path2.$postFix2, 'w'); $count = OC_Helper::streamCopy($source, $target); $storage1 = $this->getStorage($path1); - $storage1->unlink($this->getInternalPath($path1)); + $storage1->unlink($this->getInternalPath($path1.$postFix1)); $result = $count>0; - } + } OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_rename, @@ -332,11 +335,14 @@ class OC_FilesystemView { } } public function copy($path1, $path2) { - $absolutePath1 = $this->getAbsolutePath($path1); - $absolutePath2 = $this->getAbsolutePath($path2); + $postFix1=(substr($path1,-1,1)==='/')?'/':''; + $postFix2=(substr($path2,-1,1)==='/')?'/':''; + $absolutePath1 = OC_Filesystem::normalizePath($this->getAbsolutePath($path1)); + $absolutePath2 = OC_Filesystem::normalizePath($this->getAbsolutePath($path2)); if(OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { $path1 = $this->getRelativePath($absolutePath1); $path2 = $this->getRelativePath($absolutePath2); + if($path1 == null or $path2 == null) { return false; } @@ -372,15 +378,15 @@ class OC_FilesystemView { ); } if($run) { - $mp1=$this->getMountPoint($path1); - $mp2=$this->getMountPoint($path2); + $mp1=$this->getMountPoint($path1.$postFix1); + $mp2=$this->getMountPoint($path2.$postFix2); if($mp1 == $mp2){ - if($storage = $this->getStorage($path1)) { - $result=$storage->copy($this->getInternalPath($path1), $this->getInternalPath($path2)); + if($storage = $this->getStorage($path1.$postFix1)) { + $result=$storage->copy($this->getInternalPath($path1.$postFix1), $this->getInternalPath($path2.$postFix2)); } } else { - $source = $this->fopen($path1, 'r'); - $target = $this->fopen($path2, 'w'); + $source = $this->fopen($path1.$postFix1, 'r'); + $target = $this->fopen($path2.$postFix2, 'w'); $result = OC_Helper::streamCopy($source, $target); } OC_Hook::emit( @@ -475,7 +481,8 @@ class OC_FilesystemView { return $this->basicOperation('getMimeType', $path); } public function hash($type, $path, $raw = false) { - $absolutePath = $this->getAbsolutePath($path); + $postFix=(substr($path,-1,1)==='/')?'/':''; + $absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); if (OC_FileProxy::runPreProxies('hash', $absolutePath) && OC_Filesystem::isValidPath($path)) { $path = $this->getRelativePath($absolutePath); if ($path == null) { @@ -488,8 +495,8 @@ class OC_FilesystemView { array( OC_Filesystem::signal_param_path => $path) ); } - if ($storage = $this->getStorage($path)) { - $result = $storage->hash($type, $this->getInternalPath($path), $raw); + if ($storage = $this->getStorage($path.$postFix)) { + $result = $storage->hash($type, $this->getInternalPath($path.$postFix), $raw); $result = OC_FileProxy::runPostProxies('hash', $absolutePath, $result); return $result; } @@ -514,35 +521,16 @@ class OC_FilesystemView { * OC_Filestorage for delegation to a storage backend for execution */ private function basicOperation($operation, $path, $hooks=array(), $extraParam=null) { - $absolutePath = $this->getAbsolutePath($path); + $postFix=(substr($path,-1,1)==='/')?'/':''; + $absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); if(OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) { $path = $this->getRelativePath($absolutePath); if($path == null) { return false; } - $internalPath = $this->getInternalPath($path); - $run = true; - if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) { - foreach($hooks as $hook) { - if($hook!='read') { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - $hook, - array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run - ) - ); - } else { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - $hook, - array( OC_Filesystem::signal_param_path => $path) - ); - } - } - } - if($run and $storage = $this->getStorage($path)) { + $internalPath = $this->getInternalPath($path.$postFix); + $run=$this->runHooks($hooks,$path); + if($run and $storage = $this->getStorage($path.$postFix)) { if(!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); } else { @@ -551,15 +539,7 @@ class OC_FilesystemView { $result = OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result); if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) { if($operation!='fopen') {//no post hooks for fopen, the file stream is still open - foreach($hooks as $hook) { - if($hook!='read'){ - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - 'post_'.$hook, - array( OC_Filesystem::signal_param_path => $path) - ); - } - } + $this->runHooks($hooks,$path,true); } } return $result; @@ -568,6 +548,34 @@ class OC_FilesystemView { return null; } + private function runHooks($hooks,$path,$post=false){ + $prefix=($post)?'post_':''; + $run=true; + if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) { + foreach($hooks as $hook) { + if($hook!='read') { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + $prefix.$hook, + array( + OC_Filesystem::signal_param_run => &$run, + OC_Filesystem::signal_param_path => $path + ) + ); + } elseif(!$post) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + $prefix.$hook, + array( + OC_Filesystem::signal_param_path => $path + ) + ); + } + } + } + return $run; + } + /** * check if a file or folder has been updated since $time * @param int $time diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php index e041255ec9..72af083578 100644 --- a/tests/lib/filesystem.php +++ b/tests/lib/filesystem.php @@ -62,6 +62,7 @@ class Test_Filesystem extends UnitTestCase{ public function testNormalize(){ $this->assertEqual('/path',OC_Filesystem::normalizePath('/path/')); + $this->assertEqual('/path/',OC_Filesystem::normalizePath('/path/',false)); $this->assertEqual('/path',OC_Filesystem::normalizePath('path')); $this->assertEqual('/path',OC_Filesystem::normalizePath('\path')); $this->assertEqual('/foo/bar',OC_Filesystem::normalizePath('/foo//bar/'));