From ec3639dc7a28348b136d2008e692cffe8c3753ad Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 4 Sep 2013 13:06:04 +0200 Subject: Always check variable type before using readdir to avoid surprises --- lib/files/storage/common.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'lib/files/storage') diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 01560f34fde..a5b79f0e967 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -142,13 +142,15 @@ abstract class Common implements \OC\Files\Storage\Storage { return false; } else { $directoryHandle = $this->opendir($directory); - while (($contents = readdir($directoryHandle)) !== false) { - if (!\OC\Files\Filesystem::isIgnoredDir($contents)) { - $path = $directory . '/' . $contents; - if ($this->is_dir($path)) { - $this->deleteAll($path); - } else { - $this->unlink($path); + if(is_resource($directoryHandle)) { + while (($contents = readdir($directoryHandle)) !== false) { + if (!\OC\Files\Filesystem::isIgnoredDir($contents)) { + $path = $directory . '/' . $contents; + if ($this->is_dir($path)) { + $this->deleteAll($path); + } else { + $this->unlink($path); + } } } } @@ -224,7 +226,8 @@ abstract class Common implements \OC\Files\Storage\Storage { } private function addLocalFolder($path, $target) { - if ($dh = $this->opendir($path)) { + $dh = $this->opendir($path); + if(is_resource($dh)) { while (($file = readdir($dh)) !== false) { if ($file !== '.' and $file !== '..') { if ($this->is_dir($path . '/' . $file)) { @@ -242,7 +245,7 @@ abstract class Common implements \OC\Files\Storage\Storage { protected function searchInDir($query, $dir = '') { $files = array(); $dh = $this->opendir($dir); - if ($dh) { + if (is_resource($dh)) { while (($item = readdir($dh)) !== false) { if ($item == '.' || $item == '..') continue; if (strstr(strtolower($item), strtolower($query)) !== false) { -- cgit v1.2.3 From c01675de5d6650c7b1cd0571d8c313f21d13c33c Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 5 Sep 2013 11:58:57 +0200 Subject: more is_resource checks before readdir --- apps/files_encryption/lib/util.php | 121 ++++++++++++++++--------------- apps/files_external/lib/config.php | 2 +- apps/files_sharing/lib/sharedstorage.php | 3 +- lib/files/storage/mappedlocal.php | 18 +++-- lib/helper.php | 32 ++++---- lib/migration/content.php | 3 +- 6 files changed, 94 insertions(+), 85 deletions(-) (limited to 'lib/files/storage') diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index b8d68623493..8a7b6f40cba 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -329,72 +329,73 @@ class Util { $this->view->is_dir($directory) && $handle = $this->view->opendir($directory) ) { - - while (false !== ($file = readdir($handle))) { - - if ( - $file !== "." - && $file !== ".." - ) { - - $filePath = $directory . '/' . $this->view->getRelativePath('/' . $file); - $relPath = \OCA\Encryption\Helper::stripUserFilesPath($filePath); - - // If the path is a directory, search - // its contents - if ($this->view->is_dir($filePath)) { - - $this->findEncFiles($filePath, $found); - - // If the path is a file, determine - // its encryption status - } elseif ($this->view->is_file($filePath)) { - - // Disable proxies again, some- - // where they got re-enabled :/ - \OC_FileProxy::$enabled = false; - - $isEncryptedPath = $this->isEncryptedPath($filePath); - // If the file is encrypted - // NOTE: If the userId is - // empty or not set, file will - // detected as plain - // NOTE: This is inefficient; - // scanning every file like this - // will eat server resources :( - if ( - Keymanager::getFileKey($this->view, $this->userId, $relPath) - && $isEncryptedPath - ) { - - $found['encrypted'][] = array( - 'name' => $file, - 'path' => $filePath - ); - - // If the file uses old - // encryption system - } elseif (Crypt::isLegacyEncryptedContent($isEncryptedPath, $relPath)) { - - $found['legacy'][] = array( - 'name' => $file, - 'path' => $filePath - ); - - // If the file is not encrypted - } else { - - $found['plain'][] = array( - 'name' => $file, - 'path' => $relPath - ); + if(is_resource($handle)) { + while (false !== ($file = readdir($handle))) { + + if ( + $file !== "." + && $file !== ".." + ) { + + $filePath = $directory . '/' . $this->view->getRelativePath('/' . $file); + $relPath = \OCA\Encryption\Helper::stripUserFilesPath($filePath); + + // If the path is a directory, search + // its contents + if ($this->view->is_dir($filePath)) { + + $this->findEncFiles($filePath, $found); + + // If the path is a file, determine + // its encryption status + } elseif ($this->view->is_file($filePath)) { + + // Disable proxies again, some- + // where they got re-enabled :/ + \OC_FileProxy::$enabled = false; + + $isEncryptedPath = $this->isEncryptedPath($filePath); + // If the file is encrypted + // NOTE: If the userId is + // empty or not set, file will + // detected as plain + // NOTE: This is inefficient; + // scanning every file like this + // will eat server resources :( + if ( + Keymanager::getFileKey($this->view, $this->userId, $relPath) + && $isEncryptedPath + ) { + + $found['encrypted'][] = array( + 'name' => $file, + 'path' => $filePath + ); + + // If the file uses old + // encryption system + } elseif (Crypt::isLegacyEncryptedContent($isEncryptedPath, $relPath)) { + + $found['legacy'][] = array( + 'name' => $file, + 'path' => $filePath + ); + + // If the file is not encrypted + } else { + + $found['plain'][] = array( + 'name' => $file, + 'path' => $relPath + ); + + } } } } - } \OC_FileProxy::$enabled = true; diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 1935740cd2e..659959e662e 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -378,7 +378,7 @@ class OC_Mount_Config { } $result = array(); $handle = opendir($path); - if ( ! $handle) { + if(!is_resource($handle)) { return array(); } while (false !== ($file = readdir($handle))) { diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index d91acbbb2bd..257da89c84e 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -221,7 +221,8 @@ class Shared extends \OC\Files\Storage\Common { public function filemtime($path) { if ($path == '' || $path == '/') { $mtime = 0; - if ($dh = $this->opendir($path)) { + $dh = $this->opendir($path); + if(is_resource($dh)) { while (($filename = readdir($dh)) !== false) { $tempmtime = $this->filemtime($filename); if ($tempmtime > $mtime) { diff --git a/lib/files/storage/mappedlocal.php b/lib/files/storage/mappedlocal.php index fbf1b4ebf96..ba5ac4191c5 100644 --- a/lib/files/storage/mappedlocal.php +++ b/lib/files/storage/mappedlocal.php @@ -65,16 +65,18 @@ class MappedLocal extends \OC\Files\Storage\Common{ $logicalPath = $this->mapper->physicalToLogic($physicalPath); $dh = opendir($physicalPath); - while (($file = readdir($dh)) !== false) { - if ($file === '.' or $file === '..') { - continue; - } + if(is_resource($dh)) { + while (($file = readdir($dh)) !== false) { + if ($file === '.' or $file === '..') { + continue; + } - $logicalFilePath = $this->mapper->physicalToLogic($physicalPath.'/'.$file); + $logicalFilePath = $this->mapper->physicalToLogic($physicalPath.'/'.$file); - $file= $this->mapper->stripRootFolder($logicalFilePath, $logicalPath); - $file = $this->stripLeading($file); - $files[]= $file; + $file= $this->mapper->stripRootFolder($logicalFilePath, $logicalPath); + $file = $this->stripLeading($file); + $files[]= $file; + } } \OC\Files\Stream\Dir::register('local-win32'.$path, $files); diff --git a/lib/helper.php b/lib/helper.php index 5fb8fed3459..0af7f6f0394 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -341,17 +341,19 @@ class OC_Helper { if (!is_dir($path)) return chmod($path, $filemode); $dh = opendir($path); - while (($file = readdir($dh)) !== false) { - if ($file != '.' && $file != '..') { - $fullpath = $path . '/' . $file; - if (is_link($fullpath)) - return false; - elseif (!is_dir($fullpath) && !@chmod($fullpath, $filemode)) - return false; elseif (!self::chmodr($fullpath, $filemode)) - return false; + if(is_resource($dh)) { + while (($file = readdir($dh)) !== false) { + if ($file != '.' && $file != '..') { + $fullpath = $path . '/' . $file; + if (is_link($fullpath)) + return false; + elseif (!is_dir($fullpath) && !@chmod($fullpath, $filemode)) + return false; elseif (!self::chmodr($fullpath, $filemode)) + return false; + } } + closedir($dh); } - closedir($dh); if (@chmod($path, $filemode)) return true; else @@ -649,9 +651,11 @@ class OC_Helper { // if oc-noclean is empty delete it $isTmpDirNoCleanEmpty = true; $tmpDirNoClean = opendir($tmpDirNoCleanName); - while (false !== ($file = readdir($tmpDirNoClean))) { - if (!\OC\Files\Filesystem::isIgnoredDir($file)) { - $isTmpDirNoCleanEmpty = false; + if(is_resource($tmpDirNoClean)) { + while (false !== ($file = readdir($tmpDirNoClean))) { + if (!\OC\Files\Filesystem::isIgnoredDir($file)) { + $isTmpDirNoCleanEmpty = false; + } } } if ($isTmpDirNoCleanEmpty) { @@ -694,7 +698,7 @@ class OC_Helper { $newpath = $path . '/' . $filename; if ($view->file_exists($newpath)) { if (preg_match_all('/\((\d+)\)/', $name, $matches, PREG_OFFSET_CAPTURE)) { - //Replace the last "(number)" with "(number+1)" + //Replace the last "(number)" with "(number+1)" $last_match = count($matches[0]) - 1; $counter = $matches[1][$last_match][0] + 1; $offset = $matches[0][$last_match][1]; @@ -705,7 +709,7 @@ class OC_Helper { } do { if ($offset) { - //Replace the last "(number)" with "(number+1)" + //Replace the last "(number)" with "(number+1)" $newname = substr_replace($name, '(' . $counter . ')', $offset, $match_length); } else { $newname = $name . ' (' . $counter . ')'; diff --git a/lib/migration/content.php b/lib/migration/content.php index 2d8268a1d74..4413d722731 100644 --- a/lib/migration/content.php +++ b/lib/migration/content.php @@ -191,7 +191,8 @@ class OC_Migration_Content{ if( !file_exists( $dir ) ) { return false; } - if ($dirhandle = opendir($dir)) { + $dirhandle = opendir($dir); + if(is_resource($dirhandle)) { while (false !== ( $file = readdir($dirhandle))) { if (( $file != '.' ) && ( $file != '..' )) { -- cgit v1.2.3 From 2e5ce091f037f0f1b2d5f97ad8866a82c9118f58 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 10 Sep 2013 20:13:47 +0200 Subject: add storage backend interface to public namespace --- lib/files/storage/storage.php | 2 +- lib/public/files/node.php | 2 +- lib/public/files/storage.php | 343 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 345 insertions(+), 2 deletions(-) create mode 100644 lib/public/files/storage.php (limited to 'lib/files/storage') diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index c96caebf4af..b673bb9a32d 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -13,7 +13,7 @@ namespace OC\Files\Storage; * * All paths passed to the storage are relative to the storage and should NOT have a leading slash. */ -interface Storage { +interface Storage extends \OCP\Files\Storage { /** * $parameters is a free form array with the configuration options needed to construct the storage * diff --git a/lib/public/files/node.php b/lib/public/files/node.php index 42dd910871d..b3ddf6de621 100644 --- a/lib/public/files/node.php +++ b/lib/public/files/node.php @@ -43,7 +43,7 @@ interface Node { /** * Get the storage backend the file or folder is stored on * - * @return \OC\Files\Storage\Storage + * @return \OCP\Files\Storage * @throws \OCP\Files\NotFoundException */ public function getStorage(); diff --git a/lib/public/files/storage.php b/lib/public/files/storage.php new file mode 100644 index 00000000000..e794662a434 --- /dev/null +++ b/lib/public/files/storage.php @@ -0,0 +1,343 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCP\Files; + +/** + * Provide a common interface to all different storage options + * + * All paths passed to the storage are relative to the storage and should NOT have a leading slash. + */ +interface Storage { + /** + * $parameters is a free form array with the configuration options needed to construct the storage + * + * @param array $parameters + */ + public function __construct($parameters); + + /** + * Get the identifier for the storage, + * the returned id should be the same for every storage object that is created with the same parameters + * and two storage objects with the same id should refer to two storages that display the same files. + * + * @return string + */ + public function getId(); + + /** + * see http://php.net/manual/en/function.mkdir.php + * + * @param string $path + * @return bool + */ + public function mkdir($path); + + /** + * see http://php.net/manual/en/function.rmdir.php + * + * @param string $path + * @return bool + */ + public function rmdir($path); + + /** + * see http://php.net/manual/en/function.opendir.php + * + * @param string $path + * @return resource + */ + public function opendir($path); + + /** + * see http://php.net/manual/en/function.is_dir.php + * + * @param string $path + * @return bool + */ + public function is_dir($path); + + /** + * see http://php.net/manual/en/function.is_file.php + * + * @param string $path + * @return bool + */ + public function is_file($path); + + /** + * see http://php.net/manual/en/function.stat.php + * only the following keys are required in the result: size and mtime + * + * @param string $path + * @return array + */ + public function stat($path); + + /** + * see http://php.net/manual/en/function.filetype.php + * + * @param string $path + * @return bool + */ + public function filetype($path); + + /** + * see http://php.net/manual/en/function.filesize.php + * The result for filesize when called on a folder is required to be 0 + * + * @param string $path + * @return int + */ + public function filesize($path); + + /** + * check if a file can be created in $path + * + * @param string $path + * @return bool + */ + public function isCreatable($path); + + /** + * check if a file can be read + * + * @param string $path + * @return bool + */ + public function isReadable($path); + + /** + * check if a file can be written to + * + * @param string $path + * @return bool + */ + public function isUpdatable($path); + + /** + * check if a file can be deleted + * + * @param string $path + * @return bool + */ + public function isDeletable($path); + + /** + * check if a file can be shared + * + * @param string $path + * @return bool + */ + public function isSharable($path); + + /** + * get the full permissions of a path. + * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php + * + * @param string $path + * @return int + */ + public function getPermissions($path); + + /** + * see http://php.net/manual/en/function.file_exists.php + * + * @param string $path + * @return bool + */ + public function file_exists($path); + + /** + * see http://php.net/manual/en/function.filemtime.php + * + * @param string $path + * @return int + */ + public function filemtime($path); + + /** + * see http://php.net/manual/en/function.file_get_contents.php + * + * @param string $path + * @return string + */ + public function file_get_contents($path); + + /** + * see http://php.net/manual/en/function.file_put_contents.php + * + * @param string $path + * @param string $data + * @return bool + */ + public function file_put_contents($path, $data); + + /** + * see http://php.net/manual/en/function.unlink.php + * + * @param string $path + * @return bool + */ + public function unlink($path); + + /** + * see http://php.net/manual/en/function.rename.php + * + * @param string $path1 + * @param string $path2 + * @return bool + */ + public function rename($path1, $path2); + + /** + * see http://php.net/manual/en/function.copy.php + * + * @param string $path1 + * @param string $path2 + * @return bool + */ + public function copy($path1, $path2); + + /** + * see http://php.net/manual/en/function.fopen.php + * + * @param string $path + * @param string $mode + * @return resource + */ + public function fopen($path, $mode); + + /** + * get the mimetype for a file or folder + * The mimetype for a folder is required to be "httpd/unix-directory" + * + * @param string $path + * @return string + */ + public function getMimeType($path); + + /** + * see http://php.net/manual/en/function.hash-file.php + * + * @param string $type + * @param string $path + * @param bool $raw + * @return string + */ + public function hash($type, $path, $raw = false); + + /** + * see http://php.net/manual/en/function.free_space.php + * + * @param string $path + * @return int + */ + public function free_space($path); + + /** + * search for occurrences of $query in file names + * + * @param string $query + * @return array + */ + public function search($query); + + /** + * see http://php.net/manual/en/function.touch.php + * If the backend does not support the operation, false should be returned + * + * @param string $path + * @param int $mtime + * @return bool + */ + public function touch($path, $mtime = null); + + /** + * get the path to a local version of the file. + * The local version of the file can be temporary and doesn't have to be persistent across requests + * + * @param string $path + * @return string + */ + public function getLocalFile($path); + + /** + * get the path to a local version of the folder. + * The local version of the folder can be temporary and doesn't have to be persistent across requests + * + * @param string $path + * @return string + */ + public function getLocalFolder($path); + /** + * check if a file or folder has been updated since $time + * + * @param string $path + * @param int $time + * @return bool + * + * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed. + * returning true for other changes in the folder is optional + */ + public function hasUpdated($path, $time); + + /** + * get a cache instance for the storage + * + * @param string $path + * @return \OC\Files\Cache\Cache + */ + public function getCache($path = ''); + + /** + * get a scanner instance for the storage + * + * @param string $path + * @return \OC\Files\Cache\Scanner + */ + public function getScanner($path = ''); + + + /** + * get the user id of the owner of a file or folder + * + * @param string $path + * @return string + */ + public function getOwner($path); + + /** + * get a permissions cache instance for the cache + * + * @param string $path + * @return \OC\Files\Cache\Permissions + */ + public function getPermissionsCache($path = ''); + + /** + * get a watcher instance for the cache + * + * @param string $path + * @return \OC\Files\Cache\Watcher + */ + public function getWatcher($path = ''); + + /** + * @return \OC\Files\Cache\Storage + */ + public function getStorageCache(); + + /** + * get the ETag for a file or folder + * + * @param string $path + * @return string + */ + public function getETag($path); +} -- cgit v1.2.3