diff options
Diffstat (limited to 'library/Smarty/libs/sysplugins/smarty_internal_resource_file.php')
-rw-r--r-- | library/Smarty/libs/sysplugins/smarty_internal_resource_file.php | 149 |
1 files changed, 138 insertions, 11 deletions
diff --git a/library/Smarty/libs/sysplugins/smarty_internal_resource_file.php b/library/Smarty/libs/sysplugins/smarty_internal_resource_file.php index 0abdc4495..b34033dd8 100644 --- a/library/Smarty/libs/sysplugins/smarty_internal_resource_file.php +++ b/library/Smarty/libs/sysplugins/smarty_internal_resource_file.php @@ -18,6 +18,134 @@ class Smarty_Internal_Resource_File extends Smarty_Resource { /** + * build template filepath by traversing the template_dir array + * + * @param Smarty_Template_Source $source source object + * @param Smarty_Internal_Template $_template template object + * + * @return string fully qualified filepath + * @throws SmartyException + */ + protected function buildFilepath(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null) + { + $file = $source->name; + preg_match('#^(?P<absolute>[\\\/]|[a-zA-Z]:[\\\/])|(\[(?P<index>[^\]]+)\])|(?P<rel>\.[\\\/])#', $file, $fileMatch); + // save basename + if (!empty($fileMatch['absolute'])) { + $file = $this->normalizePath($file); + return is_file($file) ? $file : false; + } + // go relative to a given template? + if (!empty($fileMatch['rel']) && $_template && $_template->parent instanceof Smarty_Internal_Template) { + if ($_template->parent->source->type != 'file' && $_template->parent->source->type != 'extends' && !$_template->parent->allow_relative_path) { + throw new SmartyException("Template '{$file}' cannot be relative to template of resource type '{$_template->parent->source->type}'"); + } + $path = dirname($_template->parent->source->filepath) . DS . $file; + // normalize path + $path = $this->normalizePath($path); + // files relative to a template only get one shot + return is_file($path) ? $path : false; + } + + if ($source->isConfig) { + $_directories = $source->smarty->getConfigDir(); + } else { + $_directories = $source->smarty->getTemplateDir(); + } + // template_dir index? + if (!empty($fileMatch['index'])) { + $index = $fileMatch['index']; + $_directory = null; + // try string indexes + if (isset($_directories[$index])) { + $_directory = $_directories[$index]; + } elseif (is_numeric($index)) { + // try numeric index + $index = (int) $index; + if (isset($_directories[$index])) { + $_directory = $_directories[$index]; + } else { + // try at location index + $keys = array_keys($_directories); + $_directory = $_directories[$keys[$index]]; + } + } + if ($_directory) { + preg_match('#\](.+)$#', $file, $fileMatch); + $path = $_directory . $fileMatch[1]; + $path = $this->normalizePath($path); + if (is_file($path)) { + return $path; + } + } else { + // index not found + return false; + } + } + + // relative file name? + foreach ($_directories as $_directory) { + $_filepath = $_directory . $file; + $path = $this->normalizePath($_filepath); + if (is_file($path)) { + return $path; + } + if ($source->smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_directory)) { + // try PHP include_path + if (function_exists('stream_resolve_include_path')) { + $_filepath = stream_resolve_include_path($_filepath); + } else { + $_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath); + } + if ($_filepath !== false) { + $path = $this->normalizePath($_filepath); + if (is_file($path)) { + return $path; + } + } + } + } + // Could be relative to cwd + $path = $this->normalizePath(getcwd() . DS . $file); + return is_file($path) ? $path : false; + } + + /** + * Normalize path + * - remove /./ and /../ + * - make it absolute + * + * @param string $path file path + * + * @return string + */ + public function normalizePath($path) + { + if ($path[0] == '.') { + $path = getcwd() . DS . $path; + } + $path = preg_replace('#[\\\/]+([.][\\\/]+)*#', DS, $path); + while (strrpos($path, '.' . DS) !== false) { + $path = preg_replace('#([\\\/]([^\\\/]+[\\\/]){2}([.][.][\\\/]){2})|([\\\/][^\\\/]+[\\\/][.][.][\\\/])#', DS, $path); + } + return $path; + } + + /** + * test is file exists and save timestamp + * + * @param Smarty_Template_Source $source source object + * @param string $file file name + * + * @return bool true if file exists + */ + protected function fileExists(Smarty_Template_Source $source, $file) + { + $source->timestamp = is_file($file) ? @filemtime($file) : false; + return $source->exists = !!$source->timestamp; + } + + /** * populate Source Object with meta data from Resource * * @param Smarty_Template_Source $source source object @@ -31,12 +159,14 @@ class Smarty_Internal_Resource_File extends Smarty_Resource if (is_object($source->smarty->security_policy)) { $source->smarty->security_policy->isTrustedResourceDir($source->filepath); } - - $source->uid = sha1(realpath($source->filepath)); + $source->exists = true; + $source->uid = sha1($source->filepath); if ($source->smarty->compile_check && !isset($source->timestamp)) { $source->timestamp = @filemtime($source->filepath); - $source->exists = !!$source->timestamp; } + } else { + $source->timestamp = false; + $source->exists = false; } } @@ -47,8 +177,10 @@ class Smarty_Internal_Resource_File extends Smarty_Resource */ public function populateTimestamp(Smarty_Template_Source $source) { - $source->timestamp = @filemtime($source->filepath); - $source->exists = !!$source->timestamp; + $source->timestamp = $source->exists = is_file($source->filepath); + if ($source->exists) { + $source->timestamp = @filemtime($source->filepath); + } } /** @@ -79,11 +211,6 @@ class Smarty_Internal_Resource_File extends Smarty_Resource */ public function getBasename(Smarty_Template_Source $source) { - $_file = $source->name; - if (($_pos = strpos($_file, ']')) !== false) { - $_file = substr($_file, $_pos + 1); - } - - return basename($_file); + return basename($source->filepath); } } |