From 4a9748e7f59c6bd316ddd650fcf7bb93d6f0e59a Mon Sep 17 00:00:00 2001 From: phpnut Date: Sat, 23 Jun 2007 04:48:29 +0000 Subject: [PATCH] Refactoring FileEngine cache class Refactoring Folder class git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@5339 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/libs/cache/file.php | 53 +++++++++++++++++++++++++++++----------- cake/libs/folder.php | 52 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 88 insertions(+), 17 deletions(-) diff --git a/cake/libs/cache/file.php b/cake/libs/cache/file.php index ffa2d387f..1c4403886 100644 --- a/cake/libs/cache/file.php +++ b/cake/libs/cache/file.php @@ -29,6 +29,9 @@ * Included libraries. * */ +if (!class_exists('File')) { + uses ('file'); +} if (!class_exists('Folder')) { uses ('folder'); } @@ -40,6 +43,14 @@ if (!class_exists('Folder')) { * @subpackage cake.cake.libs.cache */ class FileEngine extends CacheEngine { + +/** + * Does the cache engine handle prefixes on it's own? + * + * @var boolean + * @access private + */ + var $_usesPrefixes = true; /** * Cache directory * @@ -117,17 +128,31 @@ class FileEngine extends CacheEngine { return false; } $expires = time() + $duration; - return $this->_writeCache($this->_getFilename($key), $serialized, $expires); + + $fileName = $this->_getFilename($key); + if ($fileName === false) { + return false; + } + return $this->_writeCache($fileName, $serialized, $expires); } /** * Get absolute filename for a key * * @param string $key The key - * @return string Absolute cache filename for the given key + * @return mixed Absolute cache filename for the given key or false if erroneous * @access private */ function _getFilename($key) { - return $this->_dir . $this->_prefix . $this->base64url_encode($key); + $fullpath = $this->_dir . $key; + $directoryName = dirname($fullpath); + $fileName = $this->_prefix.basename($fullpath); + $fullpath = Folder::realpath($directoryName . DS . $fileName); + + $folder = new Folder($this->_dir); + if (!$folder->inPath($fullpath, true)) { + return false; + } + return $fullpath; } /** * write serialized data to a file @@ -139,6 +164,13 @@ class FileEngine extends CacheEngine { * @access private */ function _writeCache(&$filename, &$value, &$expires) { + $directoryName = dirname($filename); + if (!is_writable($directoryName)) { + $folder = new Folder($directoryName); + if (!$folder->create($directoryName)) { + return false; + } + } $contents = $expires."\n".$value."\n"; return ife(file_put_contents($filename, $contents, ife($this->_lock, LOCK_EX, 0)), true, false); } @@ -152,7 +184,7 @@ class FileEngine extends CacheEngine { function read($key) { $filename = $this->_getFilename($key); - if (!is_file($filename) || !is_readable($filename)) { + if ($filename === false || !is_file($filename) || !is_readable($filename)) { return false; } $fp = fopen($filename, 'r'); @@ -209,6 +241,9 @@ class FileEngine extends CacheEngine { */ function delete($key) { $filename = $this->_getFilename($key); + if ($filename === false) { + return false; + } return unlink($filename); } /** @@ -265,15 +300,5 @@ class FileEngine extends CacheEngine { 'prefix' => $this->_prefix, 'lock' => $lock); } -/** - * Get a filename-safe version of a string - * - * @param string $str String to encode - * @return string Encoded version of the string - * @access public - */ - function base64url_encode($str) { - return strtr(base64_encode($str), '+/', '-_'); - } } ?> \ No newline at end of file diff --git a/cake/libs/folder.php b/cake/libs/folder.php index 5788c0a6d..b278ade96 100644 --- a/cake/libs/folder.php +++ b/cake/libs/folder.php @@ -114,7 +114,7 @@ class Folder extends Object{ * @access public */ function cd($path) { - $path = realpath($path); + $path = $this->realpath($path); if (!$this->isAbsolute($path)) { $path = $this->addPathElement($this->path, $path); } @@ -334,9 +334,19 @@ class Folder extends Object{ * @return boolean * @access public */ - function inPath($path = '') { + function inPath($path = '', $reverse = false) { + if (!$this->isAbsolute($path)) { + $path = $this->addPathElement($this->path, $path); + } + $path = $this->realpath($path); $dir = substr($this->slashTerm($path), 0, -1); - $return = preg_match('/^' . preg_quote($this->slashTerm($dir), '/') . '(.*)/', $this->slashTerm($this->pwd())); + + if (!$reverse) { + $return = preg_match('/^' . preg_quote($this->slashTerm($dir), '/') . '(.*)/', $this->slashTerm($this->pwd())); + } else { + $return = preg_match('/^' . preg_quote($this->slashTerm($this->pwd()), '/') . '(.*)/', $this->slashTerm($dir)); + } + if ($return == 1) { return true; } else { @@ -671,6 +681,42 @@ class Folder extends Object{ function rm($path) { return $this->delete($path); } +/** + * Get the real path (taking ".." and such into account) + * + * @param string $path Path to resolve + * @return string The resolved path + */ + function realpath($path) { + $path = trim($path); + if (strpos($path, '..') === false) { + return $path; + } + $parts = explode(DS, $path); + $newparts = array(); + $newpath = ife($path{0} == DS, DS, ''); + + while (($part = array_shift($parts)) !== NULL) { + if ($part == '.' || $part == '') { + continue; + } + if ($part == '..') { + if (count($newparts) > 0) { + array_pop($newparts); + continue; + } else { + return false; + } + } + $newparts[] = $part; + } + $newpath .= implode(DS, $newparts); + + if (strlen($path > 1) && $path{strlen($path)-1} == DS) { + $newpath .= DS; + } + return $newpath; + } /** * * @deprecated