Compare commits

..

7 Commits

Author SHA1 Message Date
Simon Wisselink 5de6092a56 added changelog 2024-05-24 00:15:02 +02:00
Scott Baker 32c8339492 Some fixes per Wisskid in the PR 2024-05-15 08:45:01 -07:00
Scott Baker 2042979701 Update example docs to point at libs/ 2024-05-15 08:14:21 -07:00
Scott Baker d0270fb8ea Move to /libs/ 2024-05-15 08:11:01 -07:00
Scott Baker 39db8ce64f Correct a path in the example 2024-05-14 12:28:56 -07:00
Scott Baker 11cc46c942 Add standalone instantiation documentation 2024-05-14 12:23:52 -07:00
Scott Baker d974bde2c4 Add a PSR-4 loading script to allow Smarty to be used without Composer
Fix a directory path
2024-05-14 12:09:25 -07:00
19 changed files with 95 additions and 178 deletions
+2 -13
View File
@@ -6,17 +6,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [5.3.0] - 2024-05-30
- Fix warning when calling hasVariable for an undefined variable [#977](https://github.com/smarty-php/smarty/issues/977)
- Added `$smarty->prependTemplateDir()` method [#1022](https://github.com/smarty-php/smarty/issues/1022)
## [5.2.0] - 2024-05-28
- Fixed a code injection vulnerability in extends-tag. This addresses CVE-2024-35226.
- Added `$smarty->setCacheModifiedCheck()` setter for cache_modified_check
- Added a PSR-4 loading script to allow Smarty to be used without Composer [#1017](https://github.com/smarty-php/smarty/pull/1017)
## [5.1.0] - 2024-04-22
- Prevent deprecation notices during compilation in PHP8.3 [#996](https://github.com/smarty-php/smarty/issues/996)
- Fix that getTemplateVars would return an array of objects instead of the assigned variables values [#994](https://github.com/smarty-php/smarty/issues/994)
@@ -27,16 +16,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Internal compiler classes always return a string (the internal has_code flag has been removed for simplicity) [#918](https://github.com/smarty-php/smarty/pull/918)
- Fix invalid classnames in Runtime code for foreach [#1000](https://github.com/smarty-php/smarty/issues/1000)
## [5.0.2] - 2024-03-28
- Fix Smarty::assign() not returning $this when called with an array as first parameter [#972](https://github.com/smarty-php/smarty/pull/972)
## [5.0.1] - 2024-03-27
- Fix error in Smarty\Smarty::compileAllTemplates() by including missing FilesystemIterator class [#966](https://github.com/smarty-php/smarty/issues/966)
## [5.0.0] - 2024-03-25
- Fixed that scoped variables would overwrite parent scope [#952](https://github.com/smarty-php/smarty/issues/952)
- Removed publicly accessible `$tpl->_var_stack` variable
### Fixed
- Too many shorthand attributes error when using a modifier as a function with more than 3 parameters in an expression [#949](https://github.com/smarty-php/smarty/issues/949)
+1
View File
@@ -0,0 +1 @@
- Added a PSR-4 loading script to allow Smarty to be used without Composer [#1017](https://github.com/smarty-php/smarty/pull/1017)
+10 -13
View File
@@ -12,27 +12,24 @@ Use `getTemplateDir()` to retrieve the configured paths.
<?php
// set a single directory where the config files are stored
$smarty->setTemplateDir('./templates');
$smarty->setTemplateDir('./config');
// set multiple directories where templates are stored
$smarty->setTemplateDir(['./templates', './templates_2', './templates_3']);
// set multiple directories where config files are stored
$smarty->setTemplateDir(['./config', './config_2', './config_3']);
// add directory where templates files are stored to the current list of dirs
$smarty->addTemplateDir('./templates_1');
// add directory where config files are stored to the current list of dirs
$smarty->addTemplateDir('./config_1');
// add multiple directories to the current list of dirs
$smarty->addTemplateDir([
'./templates_2',
'./templates_3',
'./config_2',
'./config_3',
]);
// chaining of method calls
$smarty->setTemplateDir('./templates')
->addTemplateDir('./templates_1')
->addTemplateDir('./templates_2');
// insert a template dir before exising template dirs
$smarty->prependTemplateDir('./more_important_templates')
$smarty->setTemplateDir('./config')
->addTemplateDir('./config_1')
->addTemplateDir('./config_2');
// get all directories where config files are stored
$template_dirs = $smarty->getTemplateDir();
+62 -2
View File
@@ -32,7 +32,7 @@ class ExtendsTag extends Inheritance {
*
* @var array
*/
protected $optional_attributes = [];
protected $optional_attributes = ['extends_resource'];
/**
* Attribute definition: Overwrites base class.
@@ -64,7 +64,29 @@ class ExtendsTag extends Inheritance {
}
// add code to initialize inheritance
$this->registerInit($compiler, true);
$this->compileEndChild($compiler, $_attr['file']);
$file = trim($_attr['file'], '\'"');
if (strlen($file) > 8 && substr($file, 0, 8) === 'extends:') {
// generate code for each template
$files = array_reverse(explode('|', substr($file, 8)));
$i = 0;
foreach ($files as $file) {
if ($file[0] === '"') {
$file = trim($file, '".');
} else {
$file = "'{$file}'";
}
$i++;
if ($i === count($files) && isset($_attr['extends_resource'])) {
$this->compileEndChild($compiler);
}
$this->compileInclude($compiler, $file);
}
if (!isset($_attr['extends_resource'])) {
$this->compileEndChild($compiler);
}
} else {
$this->compileEndChild($compiler, $_attr['file']);
}
return '';
}
@@ -84,4 +106,42 @@ class ExtendsTag extends Inheritance {
(isset($template) ? ", {$template}, \$_smarty_current_dir" : '') . ");\n?>"
);
}
/**
* Add code for including subtemplate to end of template
*
* @param \Smarty\Compiler\Template $compiler
* @param string $template subtemplate name
*
* @throws \Smarty\CompilerException
* @throws \Smarty\Exception
*/
private function compileInclude(\Smarty\Compiler\Template $compiler, $template) {
$compiler->getParser()->template_postfix[] = new \Smarty\ParseTree\Tag(
$compiler->getParser(),
$compiler->compileTag(
'include',
[
$template,
['scope' => 'parent'],
]
)
);
}
/**
* Create source code for {extends} from source components array
*
* @param \Smarty\Template $template
*
* @return string
*/
public static function extendsSourceArrayCode(\Smarty\Template $template) {
$resources = [];
foreach ($template->getSource()->components as $source) {
$resources[] = $source->resource;
}
return $template->getLeftDelimiter() . 'extends file=\'extends:' . join('|', $resources) .
'\' extends_resource=true' . $template->getRightDelimiter();
}
}
+11 -27
View File
@@ -403,37 +403,21 @@ class Template extends BaseCompiler {
}
// get template source
if (!empty($this->template->getSource()->components)) {
$_compiled_code = '<?php $_smarty_tpl->getInheritance()->init($_smarty_tpl, true); ?>';
$i = 0;
$reversed_components = array_reverse($this->template->getSource()->components);
foreach ($reversed_components as $source) {
$i++;
if ($i === count($reversed_components)) {
$_compiled_code .= '<?php $_smarty_tpl->getInheritance()->endChild($_smarty_tpl); ?>';
}
$_compiled_code .= $this->compileTag(
'include',
[
var_export($source->resource, true),
['scope' => 'parent'],
]
);
}
$_compiled_code = $this->smarty->runPostFilters($_compiled_code, $this->template);
// we have array of inheritance templates by extends: resource
// generate corresponding source code sequence
$_content =
ExtendsTag::extendsSourceArrayCode($this->template);
} else {
// get template source
$_content = $this->template->getSource()->getContent();
$_compiled_code = $this->smarty->runPostFilters(
$this->doCompile(
$this->smarty->runPreFilters($_content, $this->template),
true
),
$this->template
);
}
$_compiled_code = $this->smarty->runPostFilters(
$this->doCompile(
$this->smarty->runPreFilters($_content, $this->template),
true
),
$this->template
);
} catch (\Exception $e) {
if ($this->smarty->debugging) {
$this->smarty->getDebug()->end_compile($this->template);
+1 -1
View File
@@ -290,7 +290,7 @@ class Data
* @return bool
*/
public function hasVariable($varName): bool {
return !($this->getVariable($varName, true, false) instanceof UndefinedVariable);
return !($this->getVariable($varName) instanceof UndefinedVariable);
}
/**
+1 -25
View File
@@ -54,7 +54,7 @@ class Smarty extends \Smarty\TemplateBase {
/**
* smarty version
*/
const SMARTY_VERSION = '5.3.0';
const SMARTY_VERSION = '5.1.0';
/**
* define caching modes
@@ -684,21 +684,6 @@ class Smarty extends \Smarty\TemplateBase {
return $this;
}
/**
* Adds a template directory before any existing directoires
*
* @param string $new_template_dir directory of template sources
* @param bool $is_config true for config_dir
*
* @return static current Smarty instance for chaining
*/
public function prependTemplateDir($new_template_dir, $is_config = false) {
$current_template_dirs = $is_config ? $this->config_dir : $this->template_dir;
array_unshift($current_template_dirs, $new_template_dir);
$this->setTemplateDir($current_template_dirs, $is_config);
return $this;
}
/**
* Add config directory(s)
*
@@ -2226,14 +2211,5 @@ class Smarty extends \Smarty\TemplateBase {
return $template;
}
/**
* Sets if Smarty should check If-Modified-Since headers to determine cache validity.
* @param bool $cache_modified_check
* @return void
*/
public function setCacheModifiedCheck($cache_modified_check): void {
$this->cache_modified_check = (bool) $cache_modified_check;
}
}
@@ -91,13 +91,4 @@ class FileResourceIndexedTest extends PHPUnit_Smarty
$this->assertNotEquals($tpl->getCached()->filepath, $tpl2->getCached()->filepath);
}
public function testPrependTemplatePath()
{
$this->smarty->setTemplateDir(__DIR__ . '/templates');
$this->smarty->prependTemplateDir(__DIR__ . '/templates_4');
$tpl = $this->smarty->createTemplate('dirname.tpl');
$this->assertEquals('templates_4', $this->smarty->fetch($tpl));
}
}
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -1,32 +0,0 @@
<?php
/**
* Tests the ::hasVariable method
*/
class HasVariableTest extends PHPUnit_Smarty
{
public function setUp(): void
{
$this->setUpSmarty(__DIR__);
}
public function testInit()
{
$this->cleanDirs();
}
public function testSimpleTrue()
{
$this->smarty->assign('foo', 'bar');
$this->assertTrue($this->smarty->hasVariable('foo'));
}
public function testSimpleFalse()
{
$this->smarty->assign('foo', 'bar');
$this->assertFalse($this->smarty->hasVariable('foox'));
}
}
@@ -1193,38 +1193,8 @@ class CompileBlockExtendsTest extends PHPUnit_Smarty
);
}
public function testBlockWithAssign() {
$this->assertEquals('Captured content is: Content with lots of html here', $this->smarty->fetch('038_child.tpl'));
}
/**
* Test escaping of file parameter
*/
public function testEscaping()
{
$this->expectException(\Smarty\Exception::class);
$this->expectExceptionMessageMatches('/Unable to load.*/');
$this->assertEquals('hello world', $this->smarty->fetch('escaping.tpl'));
}
/**
* Test escaping of file parameter 2
*/
public function testEscaping2()
{
$this->expectException(\Smarty\Exception::class);
$this->expectExceptionMessageMatches('/Unable to load.*/');
$this->assertEquals('hello world', $this->smarty->fetch('escaping2.tpl'));
}
/**
* Test escaping of file parameter 3
*/
public function testEscaping3()
{
$this->expectException(\Smarty\Exception::class);
$this->expectExceptionMessageMatches('/Unable to load.*/');
$this->assertEquals('hello world', $this->smarty->fetch('escaping3.tpl'));
}
public function testBlockWithAssign() {
$this->assertEquals('Captured content is: Content with lots of html here', $this->smarty->fetch('038_child.tpl'));
}
}
@@ -1 +0,0 @@
{extends "extends:helloworld.tpl', var_dump(shell_exec('ls')), 1, 2, 3);}}?>"}
@@ -1 +0,0 @@
{extends 'extends:"helloworld.tpl\', var_dump(shell_exec(\'ls\')), 1, 2, 3);}}?>'}
@@ -1 +0,0 @@
{extends file='extends:"helloworld.tpl'|cat:"', var_dump(shell_exec('ls')), 1, 2, 3);}}?>"}
@@ -82,18 +82,6 @@ class CompileIncludeTest extends PHPUnit_Smarty
$this->assertEquals('I1I2I3', $content, $text);
}
/**
* test template name escaping
*/
public function testIncludeFilenameEscaping()
{
$this->expectException(\Smarty\Exception::class);
$this->expectExceptionMessageMatches('/Unable to load.*/');
$tpl = $this->smarty->createTemplate('test_include_security.tpl');
$content = $this->smarty->fetch($tpl);
$this->assertEquals("hello world", $content);
}
/**
* test standard output
*
@@ -1 +0,0 @@
{include file="helloworld.tpl', var_dump(shell_exec('ls')), 1, 2, 3);}}?>"}
@@ -32,11 +32,4 @@ class ExtendsIssue419Test extends PHPUnit_Smarty
$this->assertEquals('child', $this->smarty->fetch('extends:001_parent.tpl|001_child.tpl'));
}
public function testextendsSecurity()
{
$this->expectException(\Smarty\Exception::class);
$this->expectExceptionMessageMatches('/Unable to load.*/');
$this->assertEquals('child', $this->smarty->fetch('string:{include "001_parent.tpl\', var_dump(shell_exec(\'ls\')), 1, 2, 3);}}?>"}'));
}
}