Compare commits

...

69 Commits

Author SHA1 Message Date
Simon Wisselink 99085d8dc6 Merge branch 'release/3.1.44' into support/3.1 2022-01-18 00:12:04 +01:00
Simon Wisselink eed1e07128 version bump 2022-01-18 00:12:03 +01:00
Simon Wisselink 208f881d06 Bugfix/702 (#709)
* fix(math): fix equation regexp

Fixes #702.
2022-01-18 00:10:25 +01:00
Simon Wisselink 273f7e00fe Merge branch 'release/3.1.43' into support/3.1 2022-01-10 10:52:40 +01:00
Simon Wisselink ce1ff003d7 version bump 2022-01-10 10:52:39 +01:00
Simon Wisselink 28519ca00f Merge pull request from GHSA-4h9c-v5vg-5m6m 2022-01-10 10:48:27 +01:00
Simon Wisselink b674cba13d Merge branch 'release/3.1.42' into support/3.1 2022-01-10 00:08:36 +01:00
Simon Wisselink a52a5b72ba version bump 2022-01-10 00:08:34 +01:00
Simon Wisselink 7ad97ad030 Merge pull request from GHSA-29gp-2c3m-3j6m
* Temporary fix. Waiting for CVE

* Add CVE
2022-01-10 00:07:57 +01:00
Simon Wisselink d8fa8c982f Fixed unit tests 2022-01-09 23:29:58 +01:00
Simon Wisselink de7e15d423 Merge branch 'release/3.1.41' into support/3.1 2022-01-09 23:21:20 +01:00
Simon Wisselink 1b6919da85 version bump 2022-01-09 23:21:19 +01:00
Simon Wisselink 457284283a Rewrote the mailto function to not use eval when encoding with javascript
(cherry picked from commit c7576eb1a1)
2022-01-09 23:18:17 +01:00
Simon Wisselink 9ffca4a093 Make make-release.sh safer by checking for version number. 2021-10-22 16:00:25 +02:00
Simon Wisselink 0c8a549603 Make make-release.sh safer by checking for version number. 2021-10-22 15:58:10 +02:00
Simon Wisselink 9d4f8309ed Merge branch 'release/3.1.40' 2021-10-13 12:04:31 +02:00
Simon Wisselink 7c4354e7b8 version bump 2021-10-13 12:04:29 +02:00
Simon Wisselink 770bc4aae2 Merge branch 'm-haritonov-escape' 2021-08-19 16:15:57 +02:00
Simon Wisselink 0ff7ba5ab6 Add changelog 2021-08-19 16:13:30 +02:00
Simon Wisselink 3b0fd82849 Merge branch 'escape' of https://github.com/m-haritonov/smarty into m-haritonov-escape 2021-08-19 15:26:27 +02:00
Ikko Ashimine 1a68b79b6c Update README.md (#668)
github -> GitHub
2021-08-18 23:23:36 +02:00
Michael Voříšek e3eabe0b96 Delete uninted file expectException (#664) 2021-05-25 21:18:07 +02:00
Simon Wisselink 4698dd9fb0 Changelog 2021-03-21 21:24:32 +01:00
David Goodwin 039043e5a2 Update modifier.escape.php (#649)
trigger a notice if an incorrect modifier was used (E.g.|escape:quotes vs |escape:quote).
2021-03-21 21:21:55 +01:00
Mihail Haritonov 9cde36e3bc plugins: escape: javascript escaping secure fix 2021-02-28 16:44:56 +03:00
Simon Wisselink 290aee6db3 Update CHANGELOG.md
Add CVE's
2021-02-21 22:23:45 +01:00
Simon Wisselink e2485fa45e Create SECURITY.md 2021-02-21 22:03:44 +01:00
Simon Wisselink e27da524f7 Merge branch 'release/3.1.39' 2021-02-17 22:57:51 +01:00
Simon Wisselink a21f59663c version bump 2021-02-17 22:57:50 +01:00
Simon Wisselink 3148d406a0 changelog 2021-02-17 22:57:33 +01:00
Simon Wisselink 4f634c0097 Merge branch 'bugfix/tplfunction_sandbox_escape' 2021-02-17 22:52:34 +01:00
Simon Wisselink c9272058d9 Merge branch 'bugfix/template_object_sandbox_escape' 2021-02-17 22:51:38 +01:00
Simon Wisselink e66e293a8a Do not push release automatically in make release script, to enable a chance to catch any errors. 2021-02-17 22:50:52 +01:00
Simon Wisselink 74cab5a56b updated changelog header to security 2021-02-17 22:30:35 +01:00
Simon Wisselink 8fc66e27a7 Cannot use in Smarty3 yet, revert to @expectedException 2021-02-01 10:33:00 +01:00
Simon Wisselink 2543174460 Cannot use in Smarty3 yet, revert to @expectedException 2021-02-01 10:31:20 +01:00
Simon Wisselink 288a54f6b0 Add unit test 2021-01-24 23:52:45 +01:00
Simon Wisselink 165f1bd4d2 Fixed Code injection vulnerability by using illegal function names 2021-01-24 23:44:07 +01:00
Simon Wisselink 6463519a6c Prevent access to .template_object when in security mode to prevent PHP code injection vulnerability 2021-01-24 23:13:26 +01:00
Simon Wisselink fedc127057 Mark tests that use sleep calls as slow, so we can ignore them when running unit tests in development 2021-01-16 23:01:15 +01:00
Ikko Ashimine 3af2df20a4 Fix typo in StreamVariableTest.php (#616)
existant -> existent
2021-01-08 17:28:33 +01:00
Simon Wisselink 63b3c0aed0 Merge branch 'release/3.1.38' 2021-01-08 15:05:42 +01:00
Simon Wisselink 2af2a07906 version bump 2021-01-08 15:05:40 +01:00
Simon Wisselink cb4254355e Removed unused error_reporting.ini file, updated version number in Smarty::SMARTY_VERSION, fixed inline phpdoc that caused an IDE error 2021-01-08 15:05:10 +01:00
Simon Wisselink f65e7ddd22 fixed changelog 2021-01-07 00:34:08 +01:00
Simon Wisselink 92e05d4f8d Brought lexer source functionally up-to-date with compiled version (#625)
Fixes #621
2021-01-07 00:26:28 +01:00
Simon Wisselink e2b28167f8 Clarify correct LGPL version.
Fixes #612
2021-01-05 22:23:13 +01:00
Libor M 820782cd80 const fix for usage with comparison operators (#618)
Fixes #609 #613
2021-01-05 22:07:44 +01:00
Simon Wisselink c295786e43 Fixes for php8.0.0beta3 (#608)
* Set $errcontext argument optional to support PHP 8

- Argument is optional and deprecated in PHP 7.2

* Getting ready for PHP8, handling changed error levels/handlers mostly

* php5 compat syntax

* Updated UndefinedTemplateVarTest for PHP8 (and disabled a check for PHP<5.6) and re-enabled php:nightly in travis config

* Attempt to fix travis runs for (almost) all php versions supported

* Fix unit tests for php8, force composer to think we are still php7 to pick a supported phpunit and being less specific about an error msg because PHP8 is in active development and the exact wording is changing.

* Fixed a unit test that accidentally passed on phpunit < 7 because of sloppy string comparison.

* changelog

* run travis in xenial where possible for latest php versions. Fix unit tests from freakingo over inconsistent error messages in php8-beta.

* Incorporated AnrDaemons suggestions, making composer figure out the required phpunit version instead of specifying it explicitly and removing a unneeded error supression (@).

Co-authored-by: Jorge Sá Pereira <me@jorgesapereira.com>
2020-09-12 21:37:31 +02:00
♚ PH⑦ de Soria™♛ 859a09e1bb Bumped phpdoc @version tag to 3.1.36 (#598)
Although this could be removed, since the header comment is still there, it's good to keep the @version tag updated in order to avoid confusion for those who read it :)
2020-09-11 13:34:15 +02:00
Simon Wisselink a5934a755d Fixed a unit test that accidentally passed on phpunit < 7 because of sloppy string comparison. 2020-09-11 13:22:45 +02:00
Simon Wisselink 5a72624380 Test travis config for PHP5 versions (#592)
* Run tests for PHP5.x
* Start from 5.3 since composer requires it and without it we cannot install phpunit
* Specify dist for 5.3
* Disabled nightly testing because phpunit doesn't support php8 yet.
2020-05-05 15:08:31 +02:00
Simon Wisselink 1418c8c422 Merge branch 'AnrDaemon-fix-php5.3-compat' 2020-05-05 09:21:07 +02:00
Simon Wisselink f46c13b32a Updated changelog 2020-05-05 09:20:56 +02:00
AnrDaemon eae19f23b9 PHP 5.3 compatibility fixes 2020-05-05 01:37:36 +03:00
Sławomir Kaleta e1c050a32c Fix comment - Method can return string (#583) 2020-04-14 17:26:20 +02:00
Simon Wisselink fd148f7ade Merge branch 'release/3.1.36' 2020-04-14 16:44:26 +02:00
Simon Wisselink 07772aac90 version bump 2020-04-14 16:44:24 +02:00
Simon Wisselink 08227651fc Fixed #584 2020-04-14 16:44:09 +02:00
Simon Wisselink e0ea6899c8 fixed version of Smarty::SMARTY_VERSION and updates make-release script to do so automatically from now on 2020-04-14 16:40:44 +02:00
Simon Wisselink 97f700971f Merge branch 'release/3.1.35' 2020-04-14 00:02:48 +02:00
Simon Wisselink a0abc47588 version bump 2020-04-14 00:02:39 +02:00
Simon Wisselink 728a584ad5 Moved changelog to a keepachangelog.com format and added a release script 2020-04-14 00:02:18 +02:00
Simon Wisselink 290f7cfc3d Moved the isset tests into the test suite 2020-04-13 23:44:39 +02:00
Simon Wisselink 48d24b7ad1 Fix repo layout for package maintainers (#571)
* Do not ignore lexer subfolder for export as this contains source files and add smarty-lexer as a composer dev-dependency.
* Remove unit tests etc from archive export

Please note that the generated lexer / parser classes are not exactly equivalent, as they have been editing to conform to coding standards afterwards. I did a quick review and there don't seem to be any differences in semantics though.
2020-04-13 22:32:23 +02:00
Simon Wisselink 19ef8342aa Strip now removes whitespaces after comment (#582)
* Mark text sections as to be stripped, but do not strip them right away. Combine equivalent sections in chunks at the template level and strip combined chunks where possible.
- simplified Smarty_Internal_TemplateCompilerBase::processText along the way
Fixes #447
2020-04-13 22:27:42 +02:00
Simon Wisselink 4f89f6d84f Throw SmartyException when setting caching attributes for cacheable plugin as compiling this would fail (#573)
Fixes #457
2020-04-13 22:26:24 +02:00
Simon Wisselink 4396351d75 Switched to a more advanced regex to test wheter parameter is a variable (#567)
* This appears to fix #453, #498, #499 and possibly more issues.
2020-04-13 22:24:29 +02:00
Simon Wisselink 17d4d43624 Feature/merge smarty-phpunit into tests subfolder (#580)
* Removed unneeded files and replace dummy.txt with .gitignore files
* Synced unit tests with master codebase, noted TODO's, fixed phpunit scripts and travis config
* fix php7.4 deprecation and remove php7.4 from travis allow_failures since php7.4 is current stable

Co-authored-by: Uwe Tews <uwe.tews@googlemail.com>
Co-authored-by: Uwe Tews <uwe.tews@gmail.com>
Co-authored-by: AnrDaemon <anrdaemon@yandex.ru>
2020-04-13 15:30:52 +02:00
899 changed files with 27476 additions and 221 deletions
+10 -7
View File
@@ -6,11 +6,14 @@
*.lex text eol=lf
# exclude from git export
/travis.ini export-ignore
/myconfig.ini export-ignore
/.travis.yml export-ignore
/.gitignore export-ignore
/.gitattributes export-ignore
/lexer/ export-ignore
/tests export-ignore
/utilities/ export-ignore
/error_reporting.ini export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore
/make-release.sh export-ignore
/phpunit.sh export-ignore
/phpunit.xml export-ignore
/TODO.md export-ignore
/travis.ini export-ignore
-1
View File
@@ -11,4 +11,3 @@ utilies/*.php
phpunit*
vendor/*
composer.lock
templates_c/*
+18 -16
View File
@@ -1,37 +1,39 @@
language: php
os: linux
dist: xenial
sudo: false
install:
- travis_retry composer install
dist: trusty
matrix:
jobs:
include:
- php: 5.3 # Composer and PHPUnit require PHP 5.3.2+ to run, so we cannot test below 5.3
dist: precise # PHP 5.3 is supported only on Precise.
- php: 5.4
dist: trusty # PHP 5.4 is supported only on Trusty.
- php: 5.5
dist: trusty # PHP 5.5 is supported only on Trusty.
- php: 5.6
- php: 7.0
- php: 7.1
- php: 7.2
- php: 7.3
- php: 7.4snapshot
- php: 7.4
- php: nightly
install: travis_retry composer config platform.php 7.4.0 && composer install
fast_finish: true
allow_failures:
- php: 7.4snapshot
- php: nightly
- php: nightly # PHP 8 is still in beta
services:
- memcached
- mysql
before_script:
- mysql -e "create database IF NOT EXISTS test;" -uroot
- mysql -e "create database IF NOT EXISTS test;" -uroot
before_install:
- phpenv config-rm xdebug.ini || return 0
install:
- travis_retry composer install
- git clone --depth=50 --branch=master git://github.com/smarty-php/smarty-phpunit.git
- phpenv config-rm xdebug.ini || return 0
script:
- cd smarty-phpunit
- ../vendor/bin/phpunit ./
- ./phpunit.sh
+124 -53
View File
@@ -1,6 +1,76 @@
- fix foreachelse on arrayiterators https://github.com/smarty-php/smarty/issues/506
# Changelog
All notable changes to this project will be documented in this file.
===== 3.1.34 release ===== 05.11.2019
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [3.1.44] - 2022-01-18
### Fixed
- Fixed illegal characters bug in math function security check [#702](https://github.com/smarty-php/smarty/issues/702)
## [3.1.43] - 2022-01-10
### Security
- Prevent evasion of the `static_classes` security policy. This addresses CVE-2021-21408
## [3.1.42] - 2022-01-10
### Security
- Prevent arbitrary PHP code execution through maliciously crafted expression for the math function. This addresses CVE-2021-29454
## [3.1.41] - 2022-01-09
### Security
- Rewrote the mailto function to not use `eval` when encoding with javascript
## [3.1.40] - 2021-10-13
### Changed
- modifier escape now triggers a E_USER_NOTICE when an unsupported escape type is used https://github.com/smarty-php/smarty/pull/649
### Security
- More advanced javascript escaping to handle https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements thanks to m-haritonov
## [3.1.39] - 2021-02-17
### Security
- Prevent access to `$smarty.template_object` in sandbox mode. This addresses CVE-2021-26119.
- Fixed code injection vulnerability by using illegal function names in `{function name='blah'}{/function}`. This addresses CVE-2021-26120.
## [3.1.38] - 2021-01-08
### Fixed
- Smarty::SMARTY_VERSION wasn't updated https://github.com/smarty-php/smarty/issues/628
## [3.1.37] - 2021-01-07
### Changed
- Changed error handlers and handling of undefined constants for php8-compatibility (set $errcontext argument optional) https://github.com/smarty-php/smarty/issues/605
- Changed expected error levels in unit tests for php8-compatibility
- Travis unit tests now run for all php versions >= 5.3, including php8
- Travis runs on Xenial where possible
### Fixed
- PHP5.3 compatibility fixes
- Brought lexer source functionally up-to-date with compiled version
## [3.1.36] - 2020-04-14
### Fixed
- Smarty::SMARTY_VERSION wasn't updated in v3.1.35 https://github.com/smarty-php/smarty/issues/584
## [3.1.35] - 2020-04-14
- remove whitespaces after comments https://github.com/smarty-php/smarty/issues/447
- fix foreachelse on arrayiterators https://github.com/smarty-php/smarty/issues/506
- fix files contained in git export archive for package maintainers https://github.com/smarty-php/smarty/issues/325
- throw SmartyException when setting caching attributes for cacheable plugin https://github.com/smarty-php/smarty/issues/457
- fix errors that occured where isset was replaced with null check such as https://github.com/smarty-php/smarty/issues/453
- unit tests are now in the repository
## 3.1.34 release - 05.11.2019
13.01.2020
- fix typo in exception message (JercSi)
- fix typehint warning with callable (bets4breakfast)
@@ -9,7 +79,8 @@
- fix wrong set/get methods for memcached (IT-Experte)
- fix pborm assigning value to object variables in smarty_internal_compile_assign (Hunman)
- exclude error_reporting.ini from git export (glensc)
===== 3.1.34-dev-6 =====
## 3.1.34-dev-6 -
30.10.2018
- bugfix a nested subblock in an inheritance child template was not replace by
outer level block with same name in same child template https://github.com/smarty-php/smarty/issues/500
@@ -37,8 +108,8 @@
could fail in version 3.1.32 and 3.1.33 because PHP preg_match() restrictions
https://github.com/smarty-php/smarty/issues/488
===== 3.1.33 release ===== 12.09.2018
===== 3.1.33-dev-12 =====
## 3.1.33 release - 12.09.2018
## 3.1.33-dev-12 -
03.09.2018
- bugfix {foreach} using new style property access like {$item@property} on
Smarty 2 style named foreach loop could produce errors https://github.com/smarty-php/smarty/issues/484
@@ -60,14 +131,14 @@
- bugfix/enhancement {capture} allow variable as capture block name in Smarty special variable
like $smarty.capture.$foo https://github.com/smarty-php/smarty/issues/478 https://github.com/smarty-php/smarty/pull/481
===== 3.1.33-dev-6 =====
## 3.1.33-dev-6 -
19.08.2018
- fix PSR-2 coding standards and PHPDoc blocks https://github.com/smarty-php/smarty/pull/452
https://github.com/smarty-php/smarty/pull/475
https://github.com/smarty-php/smarty/pull/473
- bugfix PHP5.2 compatibility https://github.com/smarty-php/smarty/pull/472
===== 3.1.33-dev-4 =====
## 3.1.33-dev-4 -
17.05.2018
- bugfix strip-block produces different output in Smarty v3.1.32 https://github.com/smarty-php/smarty/issues/436
- bugfix Smarty::compileAllTemplates ignores `$extension` parameter https://github.com/smarty-php/smarty/issues/437
@@ -79,7 +150,7 @@
- bugfix regarding Security Vulnerability did not solve the problem under Linux.
Security issue CVE-2018-16831
===== 3.1.32 ===== (24.04.2018)
## 3.1.32 - (24.04.2018)
24.04.2018
- bugfix possible Security Vulnerability in Smarty_Security class.
@@ -220,7 +291,7 @@
13.4.2017
- bugfix array_merge() parameter should be checked https://github.com/smarty-php/smarty/issues/350
===== 3.1.31 ===== (14.12.2016)
## 3.1.31 - (14.12.2016)
23.11.2016
- move template object cache into static variables
@@ -334,7 +405,7 @@
compiled or cached template files https://github.com/smarty-php/smarty/issues/269
- optimization remove unneeded call to update acopes when {assign} scope and template scope was local (default)
===== 3.1.30 ===== (07.08.2016)
## 3.1.30 - (07.08.2016)
07.08.2016
- bugfix update of 04.08.2016 was incomplete
@@ -557,7 +628,7 @@
- optimization of filepath normalization
- bugfix {strip} must remove all blanks between html tags https://github.com/smarty-php/smarty/issues/136
===== 3.1.29 ===== (21.12.2015)
- 3.1.29 - (21.12.2015)
21.12.2015
- optimization improve speed of filetime checks on extends and extendsall resource
@@ -593,7 +664,7 @@
- bugfix {$smarty.config.foo} broken in 3.1.28 https://github.com/smarty-php/smarty/issues/120
- bugfix multiple calls of {section} with same name droped E_NOTICE error https://github.com/smarty-php/smarty/issues/118
===== 3.1.28 ===== (13.12.2015)
- 3.1.28 - (13.12.2015)
13.12.2015
- bugfix {foreach} and {section} with uppercase characters in name attribute did not work (forum topic 25819)
- bugfix $smarty->debugging_ctrl = 'URL' did not work (forum topic 25811)
@@ -772,18 +843,18 @@
19.06.2015
- improvement allow closures as callback at $smarty->registerFilter() https://github.com/smarty-php/smarty/issues/59
===== 3.1.27===== (18.06.2015)
- 3.1.27- (18.06.2015)
18.06.2015
- bugfix another update on file path normalization failed on path containing something like "/.foo/" https://github.com/smarty-php/smarty/issues/56
===== 3.1.26===== (18.06.2015)
- 3.1.26- (18.06.2015)
18.06.2015
- bugfix file path normalization failed on path containing something like "/.foo/" https://github.com/smarty-php/smarty/issues/56
17.06.2015
- bugfix calling a plugin with nocache option but no other attributes like {foo nocache} caused call to undefined function https://github.com/smarty-php/smarty/issues/55
===== 3.1.25===== (15.06.2015)
- 3.1.25- (15.06.2015)
15.06.2015
- optimization of smarty_cachereource_keyvaluestore.php code
@@ -813,7 +884,7 @@
24.05.2015
- bugfix if condition string 'neq' broken due to a typo https://github.com/smarty-php/smarty/issues/42
===== 3.1.24===== (23.05.2015)
- 3.1.24- (23.05.2015)
23.05.2015
- improvement on php_handling to allow very large PHP sections, better error handling
- improvement allow extreme large comment sections (forum 25538)
@@ -851,12 +922,12 @@
- bugfix access to undefined config variable like {#undef#} did fail https://github.com/smarty-php/smarty/issues/29
- bugfix in nested {foreach} saved item attributes got overwritten https://github.com/smarty-php/smarty/issues/33
===== 3.1.23 ===== (12.05.2015)
- 3.1.23 - (12.05.2015)
12.05.2015
- bugfix of smaller performance issue introduce in 3.1.22 when caching is enabled
- bugfix missig entry for smarty-temmplate-config in autoloader
===== 3.1.22 ===== tag was deleted because 3.1.22 did fail caused by the missing entry for smarty-temmplate-config in autoloader
- 3.1.22 - tag was deleted because 3.1.22 did fail caused by the missing entry for smarty-temmplate-config in autoloader
10.05.2015
- bugfix custom cache resource did not observe compile_id and cache_id when $cache_locking == true
- bugfix cache lock was not handled correctly after timeout when $cache_locking == true
@@ -1008,7 +1079,7 @@
- bugfix E_NOTICE message was created during compilation when ASP tags '<%' or '%>' are in template source text
- bugfix merge_compiled_includes option failed when caching enables and same subtemplate was included cached and not cached
===== 3.1.21 ===== (18.10.2014)
- 3.1.21 - (18.10.2014)
18.10.2014
- composer moved to github
@@ -1031,7 +1102,7 @@
- bugfix change of 08.10.2014 could create E_NOTICE meassage when using "<?php" tags
- bugfix "<script language=php>" with $php_handling PHP_PASSTHRU was executed in {nocache} sections
===== 3.1.20 ===== (09.10.2014)
- 3.1.20 - (09.10.2014)
08.10.2014
- bugfix security mode of "<script language=php>" must be controlled by $php_handling property (Thue Kristensen)
@@ -1051,7 +1122,7 @@
04.07.2014
- bugfix the bufix of 02.06.2014 broke correct handling of child templates with same name but different template folders in extends resource (issue 194 and topic 25099)
===== 3.1.19 ===== (30.06.2014)
- 3.1.19 - (30.06.2014)
20.06.2014
- bugfix template variables could not be passed as parameter in {include} when the include was in a {nocache} section (topic 25131)
@@ -1078,7 +1149,7 @@
18.04.2014
- revert bugfix of 5.4.2014 because %-e date format is not supported on all operating systems
===== 3.1.18 ===== (07.04.2014)
- 3.1.18 - (07.04.2014)
06.04.2014
- bugfix template inheritance fail when using custom resource after patch of 8.3.2014 (Issue 187)
- bugfix update of composer file (Issue 168 and 184)
@@ -1107,7 +1178,7 @@
13.03.2014
- bugfix clearXxx() change of 27.1.2014 did not work when specifing cache_id or compile_id (forum topic 24868 and 24867)
===== 3.1.17 =====
- 3.1.17 -
08.03.2014
- bugfix relative file path {include} within {block} of child templates did throw exception on first call (Issue 177)
@@ -1138,7 +1209,7 @@
- bugfix Smarty_CacheResource_Custom did not handle template resource type specifications on clearCache() calls (Issue 169)
- bugfix SmartyBC.class.php should use require_once to load Smarty.class.php (forum topic 24683)
===== 3.1.16 =====
- 3.1.16 -
15.12.2013
- bugfix {include} with {block} tag handling (forum topic 24599, 24594, 24682) (Issue 161)
Read 3.1.16_RELEASE_NOTES for more details
@@ -1171,7 +1242,7 @@
03.10.2013
- bugfix loops using modifier capitalize did eat up memory (issue 159)
===== Smarty 3.1.15 =====
- Smarty 3.1.15 -
01.10.2013
- use current delimiters in compiler error messages (issue 157)
- improvement on performance when using error handler and multiple template folders (issue 152)
@@ -1235,7 +1306,7 @@
2.7.2013
- bugfix trimwhitespace would replace captured items in wrong order (forum topic 24387)
===== Smarty-3.1.14 =====
## Smarty-3.1.14 -
27.06.2013
- bugfix removed PHP 5.5 deprecated preg_replace /e option in modifier capitalize (forum topic 24389)
@@ -1268,7 +1339,7 @@
24.01.2013
- bugfix wrong tag type in smarty_internal_templatecompilerbase.php could cause wrong plugin search order (Forum Topic 24028)
===== Smarty-3.1.13 =====
## Smarty-3.1.13 -
13.01.2013
- enhancement allow to disable exception message escaping by SmartyException::$escape = false; (Issue #130)
@@ -1299,7 +1370,7 @@
01.11.2012
- bugfix muteExcpetedErrors() would screw up for non-readable paths (Issue #118)
===== Smarty-3.1.12 =====
## Smarty-3.1.12 -
14.09.2012
- bugfix template inheritance failed to compile with delimiters {/ and /} (Forum Topic 23008)
@@ -1344,7 +1415,7 @@
- bugfix the default plugin handler did create wrong compiled code for static class methods
from external script files (issue 108)
===== Smarty-3.1.11 =====
## Smarty-3.1.11 -
30.06.2012
- bugfix {block.. hide} did not work as nested child (Forum Topic 22216)
@@ -1357,12 +1428,12 @@
11.06.2012
- bugfix the patch for Topic 21856 did break tabs between tag attributes (Forum Topic 22124)
===== Smarty-3.1.10 =====
## Smarty-3.1.10 -
09.06.2012
- bugfix the compiler did ignore registered compiler plugins for closing tags (Forum Topic 22094)
- bugfix the patch for Topic 21856 did break multiline tags (Forum Topic 22124)
===== Smarty-3.1.9 =====
## Smarty-3.1.9 -
07.06.2012
- bugfix fetch() and display() with relative paths (Issue 104)
- bugfix treat "0000-00-00" as 0 in modifier.date_format (Issue 103)
@@ -1416,7 +1487,7 @@
- enhancement the default plugin handler can now also resolve undefined modifier (Smarty::PLUGIN_MODIFIER)
(Issue 85)
===== Smarty-3.1.8 =====
## Smarty-3.1.8 -
19.02.2012
- bugfix {include} could result in a fatal error if used in appended or prepended nested {block} tags
(reported by mh and Issue 83)
@@ -1463,7 +1534,7 @@
- bugfix template inheritance: {$smarty.block.child} in nested child {block} tags did not return
content after {$smarty.block.child} (Forum Topic 20564)
===== Smarty-3.1.7 =====
## Smarty-3.1.7 -
18.12.2011
- bugfix strings ending with " in multiline strings of config files failed to compile (issue #67)
- added chaining to Smarty_Internal_Templatebase
@@ -1488,7 +1559,7 @@
- bugfix template inheritance: {$smarty.block.child} in nested child {block} tags did not return expected
result (Forum Topic 20564)
===== Smarty-3.1.6 =====
## Smarty-3.1.6 -
30.11.2011
- bugfix is_cache() for individual cached subtemplates with $smarty->caching = CACHING_OFF did produce
an exception (Forum Topic 20531)
@@ -1513,7 +1584,7 @@
- bugfix Smarty_Resource::load() did not always return a proper resource handler (Forum Topic 20414)
- added escape argument to html_checkboxes and html_radios (Forum Topic 20425)
===== Smarty-3.1.5 =====
## Smarty-3.1.5 -
14.11.2011
- bugfix allow space between function name and open bracket (forum topic 20375)
@@ -1545,7 +1616,7 @@
- revert PHP4 constructor message
- fixed PHP4 constructor message
===== Smarty-3.1.4 =====
## Smarty-3.1.4 -
19.10.2011
- added exception when using PHP4 style constructor
@@ -1574,7 +1645,7 @@
- bugfix <?xml> tag did create wrong output when caching enabled and the tag was in included subtemplate
- bugfix Smarty_CacheResource_mysql example was missing strtotime() calls
===== Smarty-3.1.3 =====
## Smarty-3.1.3 -
07.10.2011
- improvement removed html comments from {mailto} (Forum Topic 20092)
- bugfix testInstall() would not show path to internal plugins_dir (Forum Post 74627)
@@ -1601,7 +1672,7 @@
- add unloadFilter() method
- bugfix has_nocache_code flag was not reset before compilation
===== Smarty-3.1.2 =====
## Smarty-3.1.2 -
03.10.2011
- improvement add internal $joined_template_dir property instead computing it on the fly several times
@@ -1641,7 +1712,7 @@
extended Smarty class created problems
- bugfix error muting was not implemented for cache locking
===== Smarty 3.1.1 =====
## Smarty 3.1.1 -
22.09.2011
- bugfix {foreachelse} does fail if {section} was nested inside {foreach}
- bugfix debug.tpl did not display correctly when it was compiled with escape_html = true
@@ -1674,7 +1745,7 @@
- bugfix lock_id for file resource would create invalid filepath
- bugfix resource caching did not care about file.tpl in different template_dir
===== Smarty 3.1.0 =====
## Smarty 3.1.0 -
15/09/2011
- optimization of {foreach}; call internal _count() method only when "total" or "last" {foreach} properties are used
@@ -1767,7 +1838,7 @@
- update of README_3_1_DEV.txt and moved into the distribution folder
- improvement show first characters of eval and string templates instead sha1 Uid in debug window
===== Smarty 3.1-RC1 =====
## Smarty 3.1-RC1 -
25/06/2011
- revert change of 17/06/2011. $_smarty varibale removed. call loadPlugin() from inside plugin code if required
- code cleanup, remove no longer used properties and methods
@@ -1968,7 +2039,7 @@
24/12/2010
- optimize smarty_function_escape_special_chars() for PHP >= 5.2.3
===== SVN 3.0 trunk =====
## SVN 3.0 trunk -
14/05/2011
- bugfix error handling at stream resources
@@ -2028,7 +2099,7 @@
- removed obsolete {popup_init..} plugin from demo templates
- bugfix replace $smarty->triggerError() by exception in smarty_internal_resource_extends.php
===== Smarty 3.0.7 =====
## Smarty 3.0.7 -
09/02/2011
- patched vulnerability when using {$smarty.template}
@@ -2082,7 +2153,7 @@
- bugfix {$smarty.template} in child template did not return right content
- bugfix Smarty3 did not search the PHP include_path for template files
===== Smarty 3.0.6 =====
## Smarty 3.0.6 -
12/12/2010
- bugfix fixed typo regarding yesterdays change to allow streamWrapper
@@ -2117,7 +2188,7 @@
- bugfix on template inheritance when an {extends} tag was inserted by a prefilter
- added error message for illegal variable file attributes at {extends...} tags
===== Smarty 3.0.5 =====
## Smarty 3.0.5 -
19/11/2010
@@ -2144,7 +2215,7 @@
- bugfix captured content could not be accessed globally
- bugfix Smarty2 wrapper functions could not be call from within plugins
===== Smarty 3.0.4 =====
## Smarty 3.0.4 -
14/11/2010
- bugfix isset() did not allow multiple parameter
@@ -2157,7 +2228,7 @@
(introduced with 3.0.2)
- code cleanup
===== Smarty 3.0.3 =====
## Smarty 3.0.3 -
13/11/2010
- bugfix on {debug}
@@ -2166,7 +2237,7 @@
- fixed internal_config (removed unwanted code line)
- improvement remove last linebreak from {function} definition
===== Smarty 3.0.2 =====
## Smarty 3.0.2 -
12/11/2010
- reactivated $error_reporting property handling
@@ -2176,7 +2247,7 @@
with transparent access to Smarty object
- fixed {config_load} scoping form compile time to run time
===== Smarty 3.0.0 =====
## Smarty 3.0.0 -
@@ -2218,7 +2289,7 @@ request_use_auto_globals
- bugfix on template inheritance using nested eval or string resource in {extends} tags
- bugfix on output buffer handling in isCached() method
===== RC4 =====
## RC4 -
01/10/2010
- added {break} and {continue} tags for flow control of {foreach},{section},{for} and {while} loops
@@ -2315,7 +2386,7 @@ request_use_auto_globals
15/07/2010
- bufix {$smarty.template} does include now the relative path, not just filename
===== RC3 =====
## RC3 -
@@ -2369,7 +2440,7 @@ request_use_auto_globals
- make handling of Smarty comments followed by newline BC to Smarty2
===== RC2 =====
## RC2 -
@@ -2441,7 +2512,7 @@ request_use_auto_globals
- bugfix on {function} tag with name attribute in doublequoted strings
- fix to make calling of template functions unambiguously by madatory usage of the {call} tag
===== RC1 =====
## RC1 -
27/04/2010
- change default of $debugging_ctrl to 'NONE'
+1 -1
View File
@@ -3,7 +3,7 @@ Smarty: the PHP compiling template engine
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
+1 -1
View File
@@ -18,7 +18,7 @@ Smarty can be run with PHP 5.2 to PHP 7.4.
> Read the NEW_FEATURES and INHERITANCE_RELEASE_NOTES file for recent extensions to Smarty 3.1 functionality
Smarty versions 3.1.11 or later are now on github and can be installed with Composer.
Smarty versions 3.1.11 or later are now on GitHub and can be installed with Composer.
The "smarty/smarty" package will start at libs/.... subfolder.
+19
View File
@@ -0,0 +1,19 @@
# Security Policy
## Supported Versions
Smarty currently supports the latest minor version of Smarty 3 and Smarty 4. (Smarty 4 has not been released yet.)
| Version | Supported |
| ------- | ------------------ |
| 4.0.x | :white_check_mark: |
| 3.1.x | :white_check_mark: |
| < 3.1 | :x: |
## Reporting a Vulnerability
If you have discovered a security issue with Smarty, please contact us at mail [at] simonwisselink.nl. Do not
disclose your findings publicly and PLEASE PLEASE do not file an Issue.
We will try to confirm the vulnerability and develop a fix if appropriate. When we release the fix, we will publish
a security release. Please let us know if you want to be credited.
+2
View File
@@ -0,0 +1,2 @@
# Pre-release Todos
+2 -1
View File
@@ -40,6 +40,7 @@
}
},
"require-dev": {
"phpunit/phpunit": "6.4.1"
"phpunit/phpunit": "^7.5 || ^6.5 || ^5.7 || ^4.8",
"smarty/smarty-lexer": "^3.1"
}
}
-1
View File
@@ -1 +0,0 @@
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
+11 -2
View File
@@ -249,7 +249,13 @@ template ::= template PHP(B). {
// template text
template ::= template TEXT(B). {
$this->current_buffer->append_subtree($this, $this->compiler->processText(B));
$text = $this->yystack[ $this->yyidx + 0 ]->minor;
if ((string)$text == '') {
$this->current_buffer->append_subtree($this, null);
}
$this->current_buffer->append_subtree($this, new Smarty_Internal_ParseTree_Text($text, $this->strip));
}
// strip on
template ::= template STRIPON. {
@@ -308,7 +314,7 @@ smartytag(A)::= SIMPLETAG(B). {
$tag = trim(substr(B, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength()));
if ($tag == 'strip') {
$this->strip = true;
A = null;;
A = null;
} else {
if (defined($tag)) {
if ($this->security) {
@@ -752,6 +758,9 @@ value(res) ::= doublequoted_with_quotes(s). {
value(res) ::= varindexed(vi) DOUBLECOLON static_class_access(r). {
if ($this->security && $this->security->static_classes !== array()) {
$this->compiler->trigger_template_error('dynamic static class not allowed by security setting');
}
$prefixVar = $this->compiler->getNewPrefixVariable();
if (vi['var'] === '\'smarty\'') {
$this->compiler->appendPrefixCode("<?php {$prefixVar} = ". $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']).';?>');
+3 -4
View File
@@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -27,7 +27,6 @@
* @author Uwe Tews <uwe dot tews at gmail dot com>
* @author Rodney Rehm
* @package Smarty
* @version 3.1.34-dev
*/
/**
* set SMARTY_DIR to absolute path to Smarty library files.
@@ -112,7 +111,7 @@ class Smarty extends Smarty_Internal_TemplateBase
/**
* smarty version
*/
const SMARTY_VERSION = '3.1.34-dev-7';
const SMARTY_VERSION = '3.1.44';
/**
* define variable scopes
*/
@@ -800,7 +799,7 @@ class Smarty extends Smarty_Internal_TemplateBase
* @param mixed $index index of directory to get, null to get all
* @param bool $isConfig true for config_dir
*
* @return array list of template directories, or directory of $index
* @return array|string list of template directories, or directory of $index
*/
public function getTemplateDir($index = null, $isConfig = false)
{
+1 -1
View File
@@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* version 3.0 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+4 -7
View File
@@ -94,22 +94,19 @@ function smarty_function_mailto($params)
);
return;
}
// FIXME: (rodneyrehm) document.write() excues me what? 1998 has passed!
if ($encode === 'javascript') {
$string = 'document.write(\'<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>\');';
$string = '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
$js_encode = '';
for ($x = 0, $_length = strlen($string); $x < $_length; $x++) {
$js_encode .= '%' . bin2hex($string[ $x ]);
}
return '<script type="text/javascript">eval(unescape(\'' . $js_encode . '\'))</script>';
return '<script type="text/javascript">document.write(unescape(\'' . $js_encode . '\'))</script>';
} elseif ($encode === 'javascript_charcode') {
$string = '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
for ($x = 0, $y = strlen($string); $x < $y; $x++) {
for ($x = 0, $_length = strlen($string); $x < $_length; $x++) {
$ord[] = ord($string[ $x ]);
}
$_ret = "<script type=\"text/javascript\" language=\"javascript\">\n" . "{document.write(String.fromCharCode(" .
implode(',', $ord) . "))" . "}\n" . "</script>\n";
return $_ret;
return '<script type="text/javascript">document.write(String.fromCharCode(' . implode(',', $ord) . '))</script>';
} elseif ($encode === 'hex') {
preg_match('!^(.*)(\?.*)$!', $address, $match);
if (!empty($match[ 2 ])) {
+31 -1
View File
@@ -28,7 +28,12 @@ function smarty_function_math($params, $template)
'int' => true,
'abs' => true,
'ceil' => true,
'acos' => true,
'acosh' => true,
'cos' => true,
'cosh' => true,
'deg2rad' => true,
'rad2deg' => true,
'exp' => true,
'floor' => true,
'log' => true,
@@ -39,27 +44,51 @@ function smarty_function_math($params, $template)
'pow' => true,
'rand' => true,
'round' => true,
'asin' => true,
'asinh' => true,
'sin' => true,
'sinh' => true,
'sqrt' => true,
'srand' => true,
'tan' => true
'atan' => true,
'atanh' => true,
'tan' => true,
'tanh' => true
);
// be sure equation parameter is present
if (empty($params[ 'equation' ])) {
trigger_error("math: missing equation parameter", E_USER_WARNING);
return;
}
$equation = $params[ 'equation' ];
// Remove whitespaces
$equation = preg_replace('/\s+/', '', $equation);
// Adapted from https://www.php.net/manual/en/function.eval.php#107377
$number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number
$functionsOrVars = '((?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))';
$operators = '[+\/*\^%-]'; // Allowed math operators
$regexp = '/^(('.$number.'|'.$functionsOrVars.'|('.$functionsOrVars.'\s*\((?1)+\)|\((?1)+\)))(?:'.$operators.'(?1))?)+$/';
if (!preg_match($regexp, $equation)) {
trigger_error("math: illegal characters", E_USER_WARNING);
return;
}
// make sure parenthesis are balanced
if (substr_count($equation, '(') !== substr_count($equation, ')')) {
trigger_error("math: unbalanced parenthesis", E_USER_WARNING);
return;
}
// disallow backticks
if (strpos($equation, '`') !== false) {
trigger_error("math: backtick character not allowed in equation", E_USER_WARNING);
return;
}
// also disallow dollar signs
if (strpos($equation, '$') !== false) {
trigger_error("math: dollar signs not allowed in equation", E_USER_WARNING);
@@ -96,6 +125,7 @@ function smarty_function_math($params, $template)
}
$smarty_math_result = null;
eval("\$smarty_math_result = " . $equation . ";");
if (empty($params[ 'format' ])) {
if (empty($params[ 'assign' ])) {
return $smarty_math_result;
+6 -1
View File
@@ -184,7 +184,11 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
'"' => '\\"',
"\r" => '\\r',
"\n" => '\\n',
'</' => '<\/'
'</' => '<\/',
// see https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements
'<!--' => '<\!--',
'<s' => '<\s',
'<S' => '<\S'
)
);
case 'mail':
@@ -250,6 +254,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
}
return $return;
default:
trigger_error("escape: unsupported type: $esc_type - returning unmodified string", E_USER_NOTICE);
return $string;
}
}
+2 -1
View File
@@ -89,9 +89,10 @@ function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompile
return 'preg_replace("%(?<!\\\\\\\\)\'%", "\\\'",' . $params[ 0 ] . ')';
case 'javascript':
// escape quotes and backslashes, newlines, etc.
// see https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements
return 'strtr(' .
$params[ 0 ] .
', array("\\\\" => "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", "</" => "<\/" ))';
', array("\\\\" => "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", "</" => "<\/", "<!--" => "<\!--", "<s" => "<\s", "<S" => "<\S" ))';
}
} catch (SmartyException $e) {
// pass through to regular plugin fallback
@@ -58,6 +58,11 @@ class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase
}
unset($_attr[ 'nocache' ]);
$_name = trim($_attr[ 'name' ], '\'"');
if (!preg_match('/^[a-zA-Z0-9_\x80-\xff]+$/', $_name)) {
$compiler->trigger_template_error("Function name contains invalid characters: {$_name}", null, true);
}
$compiler->parent_compiler->tpl_function[ $_name ] = array();
$save = array(
$_attr, $compiler->parser->current_buffer, $compiler->template->compiled->has_nocache_code,
@@ -81,6 +81,10 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
case 'template':
return 'basename($_smarty_tpl->source->filepath)';
case 'template_object':
if (isset($compiler->smarty->security_policy)) {
$compiler->trigger_template_error("(secure mode) template_object not permitted");
break;
}
return '$_smarty_tpl';
case 'current_dir':
return 'dirname($_smarty_tpl->source->filepath)';
@@ -94,9 +98,9 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
break;
}
if (strpos($_index[ 1 ], '$') === false && strpos($_index[ 1 ], '\'') === false) {
return "@constant('{$_index[1]}')";
return "(defined('{$_index[1]}') ? constant('{$_index[1]}') : null)";
} else {
return "@constant({$_index[1]})";
return "(defined({$_index[1]}) ? constant({$_index[1]}) : null)";
}
// no break
case 'config':
@@ -115,7 +115,7 @@ class Smarty_Internal_Config_File_Compiler
$this->smarty->_debug->start_compile($this->template);
}
// init the lexer/parser to compile the config file
/* @var Smarty_Internal_ConfigFileLexer $this ->lex */
/* @var Smarty_Internal_ConfigFileLexer $this->lex */
$this->lex = new $this->lexer_class(
str_replace(
array(
@@ -127,7 +127,7 @@ class Smarty_Internal_Config_File_Compiler
) . "\n",
$this
);
/* @var Smarty_Internal_ConfigFileParser $this ->parser */
/* @var Smarty_Internal_ConfigFileParser $this->parser */
$this->parser = new $this->parser_class($this->lex, $this);
if (function_exists('mb_internal_encoding')
&& function_exists('ini_get')
@@ -65,7 +65,7 @@ class Smarty_Internal_ErrorHandler
*
* @return bool
*/
public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext)
public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext = array())
{
$_is_muted_directory = false;
// add the SMARTY_DIR to the list of muted directories
@@ -48,6 +48,8 @@ class Smarty_Internal_Method_RegisterPlugin
throw new SmartyException("Plugin tag '{$name}' already registered");
} elseif (!is_callable($callback)) {
throw new SmartyException("Plugin '{$name}' not callable");
} elseif ($cacheable && $cache_attr) {
throw new SmartyException("Cannot set caching attributes for plugin '{$name}' when it is cacheable.");
} else {
$smarty->registered_plugins[ $type ][ $name ] = array($callback, (bool)$cacheable, (array)$cache_attr);
}
@@ -85,45 +85,85 @@ class Smarty_Internal_ParseTree_Template extends Smarty_Internal_ParseTree
public function to_smarty_php(Smarty_Internal_Templateparser $parser)
{
$code = '';
for ($key = 0, $cnt = count($this->subtrees); $key < $cnt; $key++) {
if ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Text) {
$subtree = $this->subtrees[ $key ]->to_smarty_php($parser);
while ($key + 1 < $cnt && ($this->subtrees[ $key + 1 ] instanceof Smarty_Internal_ParseTree_Text ||
$this->subtrees[ $key + 1 ]->data === '')) {
$key++;
if ($this->subtrees[ $key ]->data === '') {
continue;
}
$subtree .= $this->subtrees[ $key ]->to_smarty_php($parser);
}
if ($subtree === '') {
continue;
}
$code .= preg_replace(
'/((<%)|(%>)|(<\?php)|(<\?)|(\?>)|(<\/?script))/',
"<?php echo '\$1'; ?>\n",
$subtree
);
continue;
}
if ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Tag) {
$subtree = $this->subtrees[ $key ]->to_smarty_php($parser);
while ($key + 1 < $cnt && ($this->subtrees[ $key + 1 ] instanceof Smarty_Internal_ParseTree_Tag ||
$this->subtrees[ $key + 1 ]->data === '')) {
$key++;
if ($this->subtrees[ $key ]->data === '') {
continue;
}
$subtree = $parser->compiler->appendCode($subtree, $this->subtrees[ $key ]->to_smarty_php($parser));
}
if ($subtree === '') {
continue;
}
$code .= $subtree;
continue;
}
$code .= $this->subtrees[ $key ]->to_smarty_php($parser);
foreach ($this->getChunkedSubtrees() as $chunk) {
$text = '';
switch ($chunk['mode']) {
case 'textstripped':
foreach ($chunk['subtrees'] as $subtree) {
$text .= $subtree->to_smarty_php($parser);
}
$code .= preg_replace(
'/((<%)|(%>)|(<\?php)|(<\?)|(\?>)|(<\/?script))/',
"<?php echo '\$1'; ?>\n",
$parser->compiler->processText($text)
);
break;
case 'text':
foreach ($chunk['subtrees'] as $subtree) {
$text .= $subtree->to_smarty_php($parser);
}
$code .= preg_replace(
'/((<%)|(%>)|(<\?php)|(<\?)|(\?>)|(<\/?script))/',
"<?php echo '\$1'; ?>\n",
$text
);
break;
case 'tag':
foreach ($chunk['subtrees'] as $subtree) {
$text = $parser->compiler->appendCode($text, $subtree->to_smarty_php($parser));
}
$code .= $text;
break;
default:
foreach ($chunk['subtrees'] as $subtree) {
$text = $subtree->to_smarty_php($parser);
}
$code .= $text;
}
}
return $code;
}
private function getChunkedSubtrees() {
$chunks = array();
$currentMode = null;
$currentChunk = array();
for ($key = 0, $cnt = count($this->subtrees); $key < $cnt; $key++) {
if ($this->subtrees[ $key ]->data === '' && in_array($currentMode, array('textstripped', 'text', 'tag'))) {
continue;
}
if ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Text
&& $this->subtrees[ $key ]->isToBeStripped()) {
$newMode = 'textstripped';
} elseif ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Text) {
$newMode = 'text';
} elseif ($this->subtrees[ $key ] instanceof Smarty_Internal_ParseTree_Tag) {
$newMode = 'tag';
} else {
$newMode = 'other';
}
if ($newMode == $currentMode) {
$currentChunk[] = $this->subtrees[ $key ];
} else {
$chunks[] = array(
'mode' => $currentMode,
'subtrees' => $currentChunk
);
$currentMode = $newMode;
$currentChunk = array($this->subtrees[ $key ]);
}
}
if ($currentMode && $currentChunk) {
$chunks[] = array(
'mode' => $currentMode,
'subtrees' => $currentChunk
);
}
return $chunks;
}
}
@@ -16,14 +16,31 @@
*/
class Smarty_Internal_ParseTree_Text extends Smarty_Internal_ParseTree
{
/**
* Create template text buffer
*
* @param string $data text
*/
public function __construct($data)
/**
* Wether this section should be stripped on output to smarty php
* @var bool
*/
private $toBeStripped = false;
/**
* Create template text buffer
*
* @param string $data text
* @param bool $toBeStripped wether this section should be stripped on output to smarty php
*/
public function __construct($data, $toBeStripped = false)
{
$this->data = $data;
$this->toBeStripped = $toBeStripped;
}
/**
* Wether this section should be stripped on output to smarty php
* @return bool
*/
public function isToBeStripped() {
return $this->toBeStripped;
}
/**
@@ -621,22 +621,18 @@ abstract class Smarty_Internal_TemplateCompilerBase
|| strcasecmp($name, 'array') === 0 || is_callable($name)
) {
$func_name = strtolower($name);
$par = implode(',', $parameter);
$parHasFuction = strpos($par, '(') !== false;
if ($func_name === 'isset') {
if (count($parameter) === 0) {
$this->trigger_template_error('Illegal number of parameter in "isset()"');
}
if ($parHasFuction) {
$pa = array();
foreach ($parameter as $p) {
$pa[] = (strpos($p, '(') === false) ? ('isset(' . $p . ')') : ('(' . $p . ' !== null )');
}
return '(' . implode(' && ', $pa) . ')';
} else {
$isset_par = str_replace("')->value", "',null,true,false)->value", $par);
}
return $name . '(' . $isset_par . ')';
$pa = array();
foreach ($parameter as $p) {
$pa[] = $this->syntaxMatchesVariable($p) ? 'isset(' . $p . ')' : '(' . $p . ' !== null )';
}
return '(' . implode(' && ', $pa) . ')';
} elseif (in_array(
$func_name,
array(
@@ -653,7 +649,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
$this->trigger_template_error("Illegal number of parameter in '{$func_name()}'");
}
if ($func_name === 'empty') {
if ($parHasFuction && version_compare(PHP_VERSION, '5.5.0', '<')) {
if (!$this->syntaxMatchesVariable($parameter[0]) && version_compare(PHP_VERSION, '5.5.0', '<')) {
return '(' . $parameter[ 0 ] . ' === false )';
} else {
return $func_name . '(' .
@@ -671,74 +667,82 @@ abstract class Smarty_Internal_TemplateCompilerBase
}
}
/**
* Determines whether the passed string represents a valid (PHP) variable.
* This is important, because `isset()` only works on variables and `empty()` can only be passed
* a variable prior to php5.5
* @param $string
* @return bool
*/
private function syntaxMatchesVariable($string) {
static $regex_pattern = '/^\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*((->)[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*|\[.*]*\])*$/';
return 1 === preg_match($regex_pattern, trim($string));
}
/**
* This method is called from parser to process a text content section
* This method is called from parser to process a text content section if strip is enabled
* - remove text from inheritance child templates as they may generate output
* - strip text if strip is enabled
*
* @param string $text
*
* @return null|\Smarty_Internal_ParseTree_Text
* @return string
*/
public function processText($text)
{
if ((string)$text != '') {
$store = array();
$_store = 0;
if ($this->parser->strip) {
if (strpos($text, '<') !== false) {
// capture html elements not to be messed with
$_offset = 0;
if (preg_match_all(
'#(<script[^>]*>.*?</script[^>]*>)|(<textarea[^>]*>.*?</textarea[^>]*>)|(<pre[^>]*>.*?</pre[^>]*>)#is',
$text,
$matches,
PREG_OFFSET_CAPTURE | PREG_SET_ORDER
)
) {
foreach ($matches as $match) {
$store[] = $match[ 0 ][ 0 ];
$_length = strlen($match[ 0 ][ 0 ]);
$replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
$text = substr_replace($text, $replace, $match[ 0 ][ 1 ] - $_offset, $_length);
$_offset += $_length - strlen($replace);
$_store++;
}
}
$expressions = array(// replace multiple spaces between tags by a single space
'#(:SMARTY@!@|>)[\040\011]+(?=@!@SMARTY:|<)#s' => '\1 \2',
// remove newline between tags
'#(:SMARTY@!@|>)[\040\011]*[\n]\s*(?=@!@SMARTY:|<)#s' => '\1\2',
// remove multiple spaces between attributes (but not in attribute values!)
'#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5',
'#>[\040\011]+$#Ss' => '> ',
'#>[\040\011]*[\n]\s*$#Ss' => '>',
$this->stripRegEx => '',
);
$text = preg_replace(array_keys($expressions), array_values($expressions), $text);
$_offset = 0;
if (preg_match_all(
'#@!@SMARTY:([0-9]+):SMARTY@!@#is',
$text,
$matches,
PREG_OFFSET_CAPTURE | PREG_SET_ORDER
)
) {
foreach ($matches as $match) {
$_length = strlen($match[ 0 ][ 0 ]);
$replace = $store[ $match[ 1 ][ 0 ] ];
$text = substr_replace($text, $replace, $match[ 0 ][ 1 ] + $_offset, $_length);
$_offset += strlen($replace) - $_length;
$_store++;
}
}
} else {
$text = preg_replace($this->stripRegEx, '', $text);
}
}
return new Smarty_Internal_ParseTree_Text($text);
if (strpos($text, '<') === false) {
return preg_replace($this->stripRegEx, '', $text);
}
return null;
$store = array();
$_store = 0;
// capture html elements not to be messed with
$_offset = 0;
if (preg_match_all(
'#(<script[^>]*>.*?</script[^>]*>)|(<textarea[^>]*>.*?</textarea[^>]*>)|(<pre[^>]*>.*?</pre[^>]*>)#is',
$text,
$matches,
PREG_OFFSET_CAPTURE | PREG_SET_ORDER
)
) {
foreach ($matches as $match) {
$store[] = $match[ 0 ][ 0 ];
$_length = strlen($match[ 0 ][ 0 ]);
$replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
$text = substr_replace($text, $replace, $match[ 0 ][ 1 ] - $_offset, $_length);
$_offset += $_length - strlen($replace);
$_store++;
}
}
$expressions = array(// replace multiple spaces between tags by a single space
'#(:SMARTY@!@|>)[\040\011]+(?=@!@SMARTY:|<)#s' => '\1 \2',
// remove newline between tags
'#(:SMARTY@!@|>)[\040\011]*[\n]\s*(?=@!@SMARTY:|<)#s' => '\1\2',
// remove multiple spaces between attributes (but not in attribute values!)
'#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5',
'#>[\040\011]+$#Ss' => '> ',
'#>[\040\011]*[\n]\s*$#Ss' => '>',
$this->stripRegEx => '',
);
$text = preg_replace(array_keys($expressions), array_values($expressions), $text);
$_offset = 0;
if (preg_match_all(
'#@!@SMARTY:([0-9]+):SMARTY@!@#is',
$text,
$matches,
PREG_OFFSET_CAPTURE | PREG_SET_ORDER
)
) {
foreach ($matches as $match) {
$_length = strlen($match[ 0 ][ 0 ]);
$replace = $store[ $match[ 1 ][ 0 ] ];
$text = substr_replace($text, $replace, $match[ 0 ][ 1 ] + $_offset, $_length);
$_offset += strlen($replace) - $_length;
$_store++;
}
}
return $text;
}
/**
@@ -2169,8 +2169,13 @@ class Smarty_Internal_Templateparser
// line 255 "../smarty/lexer/smarty_internal_templateparser.y"
public function yy_r2()
{
$this->current_buffer->append_subtree($this,
$this->compiler->processText($this->yystack[ $this->yyidx + 0 ]->minor));
$text = $this->yystack[ $this->yyidx + 0 ]->minor;
if ((string)$text == '') {
$this->current_buffer->append_subtree($this, null);
}
$this->current_buffer->append_subtree($this, new Smarty_Internal_ParseTree_Text($text, $this->strip));
}
// line 259 "../smarty/lexer/smarty_internal_templateparser.y"
@@ -2832,6 +2837,10 @@ class Smarty_Internal_Templateparser
// line 765 "../smarty/lexer/smarty_internal_templateparser.y"
public function yy_r95()
{
if ($this->security && $this->security->static_classes !== array()) {
$this->compiler->trigger_template_error('dynamic static class not allowed by security setting');
}
$prefixVar = $this->compiler->getNewPrefixVariable();
if ($this->yystack[ $this->yyidx + -2 ]->minor[ 'var' ] === '\'smarty\'') {
$this->compiler->appendPrefixCode("<?php {$prefixVar} = " .
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
if [[ "$1" =~ ^3\.[0-9\.-rc]+$ ]]; then
printf 'Creating release %s\n' "$1"
else
echo "Invalid version number: $1. This script can only make v3.x.x releases."
exit 1;
fi
git checkout -b "release/$1"
sed -i "s/## \\[Unreleased\\]/## \\[Unreleased\\]\\n\\n## \\[$1\\] - $(date +%Y-%m-%d)/" CHANGELOG.md
sed -i "s/const SMARTY_VERSION = '[^']\+';/const SMARTY_VERSION = '$1';/" libs/Smarty.class.php
git add CHANGELOG.md libs/Smarty.class.php
git commit -m "version bump"
git checkout support/3.1
git pull
git merge --no-ff "release/$1"
git branch -d "release/$1"
git tag -a "v$1" -m "Release $1"
printf 'Done creating release %s\n' "$1"
# shellcheck disable=SC2016
printf 'Run `git push --follow-tags origin` to publish it.\n'
Executable
+2
View File
@@ -0,0 +1,2 @@
#! /bin/bash
vendor/phpunit/phpunit/phpunit tests/UnitTests
+43
View File
@@ -0,0 +1,43 @@
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.5/phpunit.xsd"
bootstrap="tests/Bootstrap.php"
colors="true"
backupGlobals="false"
backupStaticAttributes="true"
forceCoversAnnotation="false"
mapTestClassNameToCoveredClassName="false"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
stopOnRisky="false"
timeoutForSmallTests="1"
timeoutForMediumTests="10"
timeoutForLargeTests="60"
verbose="false">
<filter>
<testsuites>
<testsuite name="Smarty Test Suite">
<directory>tests/UnitTests</directory>
</testsuite>
</testsuites>
<blacklist>
<directory suffix=".php">tests</directory>
<directory suffix=".php">tests/cache</directory>
<directory suffix=".php">tests/templates_c</directory>
</blacklist>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">libs</directory>
<directory suffix=".php">libs/plugins</directory>
<directory suffix=".php">libs/sysplugins</directory>
<directory suffix=".php">demo/plugins</directory>
</whitelist>
</filter>
<logging>
<log type="tap" target="tests/TestResults.tap"/>
</logging>
</phpunit>
+11
View File
@@ -0,0 +1,11 @@
.idea
# Unit test / coverage reports
.coverage
.tox
#Smarty
testdox.html
TestResults.tap
TestResults.txt
+27
View File
@@ -0,0 +1,27 @@
<?php
/*
* This file is part of the Smarty PHPUnit tests.
*
*/
/*
* Smarty PHPUnit Bootstrap
*/
require_once dirname(__FILE__) . '/Config.php';
require_once dirname(__FILE__) . '/../vendor/autoload.php';
require_once dirname(__FILE__) . '/../libs/bootstrap.php';
if (!class_exists('\PHPUnit_Framework_TestCase') && class_exists('\PHPUnit\Framework\TestCase')) {
class_alias('\PHPUnit\Framework\TestCase', '\PHPUnit_Framework_TestCase');
class_alias('\PHPUnit\Framework\Error\Notice', '\PHPUnit_Framework_Error_Notice');
class_alias('\PHPUnit\Framework\Error\Error', '\PHPUnit_Framework_Error_Error');
class_alias('\PHPUnit\Framework\Error\Warning', '\PHPUnit_Framework_Error_Warning');
class_alias('\PHPUnit\Framework\Error\Warning', '\PHPUnit_Framework_Error_Deprecated');
}
require_once 'PHPUnit_Smarty.php';
if (!ini_get('date.timezone')) {
ini_set('date.timezone', 'Europe/Berlin');
}
+18
View File
@@ -0,0 +1,18 @@
<?php
/*
* This file is part of the Smarty PHPUnit tests.
*
*/
/*
* Smarty PHPUnit Config
*/
define('individualFolders', true);
define('MemCacheEnable', false);
define('ApcCacheEnable', false);
define('MysqlCacheEnable', false);
define('PdoCacheEnable', false);
define('PdoGzipCacheEnable', false);
define('MysqlResourceEnable', false);
define('DB_DSN', "mysql:dbname=test;host=localhost");
define('DB_USER', "travis");
define('DB_PASSWD', "");
@@ -0,0 +1,5 @@
<?php
function smarty_function_plugin1($params, $template)
{
return 'plugin1';
}
@@ -0,0 +1,5 @@
<?php
function smarty_function_plugin2($params, $template)
{
return 'plugin2';
}
@@ -0,0 +1 @@
include_test2
@@ -0,0 +1 @@
include_test4
@@ -0,0 +1 @@
{include 'include_test4.tpl'}
+1
View File
@@ -0,0 +1 @@
include path root
+699
View File
@@ -0,0 +1,699 @@
<?php
/*
* This file is part of the Smarty PHPUnit tests.
*
*/
/**
* Smarty Test Case Fixture
*/
class PHPUnit_Smarty extends PHPUnit_Framework_TestCase
{
/**
* Smarty object
*
* @var SmartyBC
*/
public $smartyBC = null;
/**
* SmartyBC object
*
* @var Smarty
*/
public $smarty = null;
/**
* Flag if test is using the Smarty object
*
* @var bool
*/
public $loadSmarty = true;
/**
* Flag if test is using the SmartyBC object
*
* @var bool
*/
public $loadSmartyBC = false;
/**
* Flag for initialization at first test
*
* @var bool
*/
public static $init = true;
/**
* Count test number
*
* @var bool
*/
public static $testNumber = 0;
/**
* Configuration data from config.xml
*
* @var array
*/
public static $config = null;
/**
* Saved current working directory
*
* @var null
*/
public static $cwd = null;
/**
* PDO object for Mysql tests
*
* @var PDO
*/
public static $pdo = null;
public static $pluginsdir = null;
/**
* Default blacklist
*
* @var array
*/
protected $backupStaticAttributesBlacklist = array('PHPUnit_Smarty' => array('config', 'pdo', 'init',
'testNumver', 'pluginsdir'),);
/**
* This method is called before the first test of this test class is run.
*
*/
public static function setUpBeforeClass()
{
error_reporting(E_ALL & ~E_STRICT);
self::$init = true;
self::$pluginsdir =self::getSmartyPluginsDir();
}
/**
* This method is called after the last test of this test class is run.
*
*/
public static function tearDownAfterClass()
{
//self::$pdo = null;
self::$testNumber = 0;
}
/**
* Constructs a test case with the given name.
*
* @param string $name
* @param array $data
* @param string $dataName
*/
public function __construct($name = null, array $data = array(), $dataName = '')
{
date_default_timezone_set('Europe/Berlin');
if (!defined('individualFolders')) {
define('individualFolders', true);
}
parent::__construct($name, $data, $dataName);
$this->backupStaticAttributesBlacklist[ get_class($this) ] = array('init', 'config', 'pdo', 'testNumber');
}
/**
* Setup Smarty instance called for each test
*
* @param null $dir working directory
*/
public function setUpSmarty($dir = null)
{
static $s_dir;
// set up current working directory
chdir($dir);
self::$cwd = getcwd();
// create missing folders for test
if (self::$init) {
if (!is_dir($dir . '/templates')) {
mkdir($dir . '/templates');
}
if (!is_dir($dir . '/configs')) {
mkdir($dir . '/configs');
}
if (individualFolders != 'true') {
if (!isset($s_dir[ $dir ])) {
$this->cleanDir($dir . '/templates_c');
$this->cleanDir($dir . '/cache');
if (is_dir($dir . '/templates_tmp')) {
$this->cleanDir($dir . '/templates_tmp');
}
$s_dir[ $dir ] = true;
}
$dir = dirname(__FILE__);
}
if (!is_dir($dir . '/templates_c')) {
mkdir($dir . '/templates_c');
}
chmod($dir . '/templates_c', 0775);
if (!is_dir($dir . '/cache')) {
mkdir($dir . '/cache');
chmod($dir . '/cache', 0775);
}
self::$init = false;
}
clearstatcache();
// instance Smarty class
if ($this->loadSmarty) {
$this->smarty = new Smarty;
if (individualFolders != 'true') {
$this->smarty->setCompileDir(dirname(__FILE__) . '/templates_c');
$this->smarty->setCacheDir(dirname(__FILE__) . '/cache');
}
}
// instance SmartyBC class
if ($this->loadSmartyBC) {
$this->smartyBC = new SmartyBC;
if (individualFolders != 'true') {
$this->smartyBC->setCompileDir(dirname(__FILE__) . '/templates_c');
$this->smartyBC->setCacheDir(dirname(__FILE__) . '/cache');
}
}
$smarty = $this->getSmartyObj();
}
/**
* Create Mysql PDO object
*
*/
final public function getConnection()
{
if (PHPUnit_Smarty::$pdo == null) {
try {
PHPUnit_Smarty::$pdo = new PDO(DB_DSN, DB_USER, DB_PASSWD);
}
catch (PDOException $e) {
throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
}
$timezone = date_default_timezone_get();
$j = PHPUnit_Smarty::$pdo->exec("SET time_zone = '{$timezone}';");
}
}
/**
* Create table for Mysql resource
*
*/
public function initMysqlResource()
{
$this->getConnection();
PHPUnit_Smarty::$pdo->exec("DROP TABLE `templates`");
PHPUnit_Smarty::$pdo->exec("CREATE TABLE IF NOT EXISTS `templates` (
`name` varchar(100) NOT NULL,
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`source` text,
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8");
}
/**
* Create table for Mysql cache resource
*
*/
public function initMysqlCache()
{
$this->getConnection();
PHPUnit_Smarty::$pdo->exec("DROP TABLE `output_cache`");
PHPUnit_Smarty::$pdo->exec("CREATE TABLE IF NOT EXISTS `output_cache` (
`name` varchar(256) NOT NULL,
`id` char(40) NOT NULL,
`cache_id` varchar(250) DEFAULT NULL,
`compile_id` varchar(250) DEFAULT NULL,
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`content` mediumblob NOT NULL,
PRIMARY KEY (`id`),
KEY `cache_id` (`cache_id`),
KEY `compile_id` (`compile_id`),
KEY `modified` (`modified`),
KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8");
// PHPUnit_Smarty::$pdo->exec("CREATE TABLE IF NOT EXISTS `output_cache` (
//`id` char(40) NOT NULL,
//`name` varchar(250) NOT NULL,
//`cache_id` varchar(250) DEFAULT NULL,
//`compile_id` varchar(250) DEFAULT NULL,
//`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
//`expire` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
//`content` mediumblob NOT NULL,
///PRIMARY KEY (`id`),
//KEY `name` (`name`),
//KEY `cache_id` (`cache_id`),
//KEY `compile_id` (`compile_id`),
//KEY `modified` (`modified`),
//KEY `expire` (`expire`)
//) ENGINE=InnoDB DEFAULT CHARSET=utf8");
}
/**
* Delete files in templates_c and cache folders
*
*/
public function cleanDirs()
{
$this->cleanCompileDir();
$this->cleanCacheDir();
if (is_dir(self::$cwd . '/templates_tmp')) {
$this->cleanDir(self::$cwd . '/templates_tmp');
}
$this->assertTrue(true);
}
/**
* Make temporary template file
*
*/
public function makeTemplateFile($name, $code)
{
if (!is_dir(self::$cwd . '/templates_tmp')) {
mkdir(self::$cwd . '/templates_tmp');
chmod(self::$cwd . '/templates_tmp', 0775);
}
$fileName = self::$cwd . '/templates_tmp/' . "{$name}";
file_put_contents($fileName, $code);
}
/**
* Delete files in templates_c folder
*
*/
public function cleanCompileDir()
{
$smarty = $this->getSmartyObj();
if (isset($smarty)) {
$dir = $smarty->getCompileDir();
$this->cleanDir($dir);
}
}
/**
* Delete files in cache folder
*
*/
public function cleanCacheDir()
{
$smarty = $this->getSmartyObj();
if (isset($smarty)) {
$dir = $smarty->getCacheDir();
$this->cleanDir($dir);
}
}
/**
* Delete files and sub folders
*
* @param string $dir
*/
public function cleanDir($dir)
{
$di = new RecursiveDirectoryIterator($dir);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($ri as $file) {
if (substr(basename($file->getPathname()), 0, 1) === '.' || substr((string)$file,-4) === '.txt') {
continue;
}
// directory ?
if ($file->isDir()) {
if (!$ri->isDot()) {
// delete folder if empty
@rmdir($file->getPathname());
}
} else {
unlink($file->getPathname());
}
}
}
/**
* Get PDO object
*
* @return null|PDO
*/
final public function getPDO()
{
return PHPUnit_Smarty::$pdo;
}
/**
* Remove "\r" and replace "\t" with spaces
*
* @param string $in
*
* @return mixed
*/
public function normalizeString($in)
{
if (is_string($in)) {
return str_replace(array("\r", "\t"), array('', ' '), $in);
} else {
return $in;
}
}
/**
* Remove all spaces
*
* @param string $in
*
* @return mixed
*/
public function strip($in)
{
if (is_string($in)) {
return preg_replace('/\s/', '', $in);
} else {
return $in;
}
}
/**
* Return source path
*
* @param Smarty_Internal_TemplateBase $tpl template object
* @param null|string $name optional template name
* @param null|string $type optional template type
* @param null|string $dir optional template folder
*
* @return string
* @throws \Exception
*/
public function buildSourcePath($tpl, $name = null, $type = null, $dir = null)
{
$name = isset($name) ? $name : $tpl->source->name;
$type = isset($type) ? $type : $tpl->source->type;
$dir = isset($dir) ? $dir : $this->smarty->getTemplateDir(0);
switch ($type) {
case 'file':
case 'filetest':
case 'php':
return $this->normalizePath($dir . $name);
case 'mysqltest':
case 'mysql':
return sha1($type . ':' . $name);
case 'string':
$this->smarty->getTemplateDir();
return sha1($name . $this->smarty->_joined_template_dir);
default:
throw new Exception("Unhandled source resource type '{$type}'");
}
}
/**
* Build template uid
*
* @param Smarty_Internal_TemplateBase $tpl template object
* @param null|string $value
* @param null|string $name optional template name
* @param null|string $type optional template type
*
* @return string
* @throws \Exception
*/
public function buildUid($tpl, $value = null, $name = null, $type = null)
{
$type = isset($type) ? $type : $tpl->source->type;
$name = isset($name) ? $name : $tpl->source->name;
switch ($type) {
case 'php':
case 'file':
case 'filetest':
if ($tpl instanceof Smarty) {
return sha1($this->normalizePath($this->smarty->getTemplateDir(0) . $name) .
$this->smarty->_joined_template_dir);
}
return sha1($tpl->source->filepath . $this->smarty->_joined_template_dir);
case 'mysqltest':
case 'mysql':
return sha1($type . ':' . $name);
case 'string':
$this->smarty->getTemplateDir();
return sha1($name . $this->smarty->_joined_template_dir);
default:
throw new Exception("Unhandled source resource type '{$type}'");
}
}
/**
* Normalize path
* - remove /./ and /../
* - make it absolute
*
* @param string $path file path
*
* @return string
*/
public function normalizePath($path, $ds =null ,$absolute = true)
{
$ds = isset($ds) ? $ds : DIRECTORY_SEPARATOR;
$nds = $ds == '/' ? '\\' : '/';
$getcwd = getcwd();
// normalize $ds
$path = str_replace($nds, $ds, $path);
preg_match('#^([a-zA-Z][:])?([.]{1,2}[\/\\\]+)?([\\\])?([.]{0,2}[\/\\\]+)?([[:print:]]*)#', $path, $match);
if ($match[1] === '') {
if ($match[ 2 ] !== '' || $match[ 2 ] . $match[ 3 ] . $match[ 4 ] === '') {
$path = $getcwd . $ds . $path;
} else if (Smarty::$_IS_WINDOWS && $match[ 3 ] !== '') {
$path = substr($getcwd, 0, 2) . $path;
}
}
$path = preg_replace('#[\\\/]+([.][\\\/]+)*#', $ds, $path);
while (strrpos($path, '.' . $ds) !== false) {
$path =
preg_replace('#([\\\/]([^\\\/]+[\\\/]){2}([.][.][\\\/]){2})|([\\\/][^\\\/]+[\\\/][.][.][\\\/])#', $ds,
$path);
}
$cwd = preg_replace('#[\\\/]#', $ds, $getcwd);
$path = str_ireplace($cwd,$getcwd, $path);
if (!$absolute) {
$path = preg_replace('#'.$getcwd.'#', '', $path);
}
return $path;
}
/**
* Return base name
*
* @param \Smarty_Internal_Template|\Smarty_Internal_TemplateBase $tpl template object
* @param null|string $name optional template name
* @param null|string $type optional template type
*
* @return null|string
*/
public function getBasename(Smarty_Internal_Template $tpl, $name = null, $type = null)
{
$name = isset($name) ? $name : $tpl->source->name;
$type = isset($type) ? $type : $tpl->source->type;
switch ($type) {
case 'file':
case 'filetest':
if (($_pos = strpos($name, ']')) !== false) {
$name = substr($name, $_pos + 1);
}
return basename($name);
case 'mysqltest':
case 'mysql':
return $name;
case 'string':
return '';
default:
return null;
}
}
/**
* Return compiled file path
*
* @param \Smarty_Internal_Template|\Smarty_Internal_TemplateBase $tpl template object
* @param bool $sub use sub directory flag
* @param bool $caching caching flag
* @param null|string $compile_id optional compile id
* @param null|string $name optional template name
* @param null|string $type optional template type
* @param null|string $dir optional template folder
*
* @return string
* @throws \Exception
*/
public function buildCompiledPath(Smarty_Internal_Template $tpl, $sub = true, $caching = false, $compile_id = null,
$name = null, $type = null, $dir = null)
{
$sep = DIRECTORY_SEPARATOR;
$_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
$sp = $this->buildSourcePath($tpl, $name, $type, $dir);
$uid = $this->buildUid($tpl, $sp, $name, $type);
$_flag = '';
if (isset($tpl->source) && $tpl->source->isConfig) {
$_flag = '_' . ((int) $tpl->smarty->config_read_hidden + (int) $tpl->smarty->config_booleanize * 2 +
(int) $tpl->smarty->config_overwrite * 4);
} else {
$_flag = '_' . ((int) $tpl->smarty->merge_compiled_includes + (int) $tpl->smarty->escape_html * 2);
}
$_filepath = $uid . $_flag;
// if use_sub_dirs, break file into directories
if ($sub) {
$_filepath =
substr($_filepath, 0, 2) . $sep . substr($_filepath, 2, 2) . $sep . substr($_filepath, 4, 2) . $sep .
$_filepath;
}
$_compile_dir_sep = $sub ? $sep : '^';
if (isset($_compile_id)) {
$_filepath = $_compile_id . $_compile_dir_sep . $_filepath;
}
// caching token
if ($caching) {
$_cache = '.cache';
} else {
$_cache = '';
}
$_compile_dir = $tpl->smarty->getCompileDir();
// set basename if not specified
$_basename = $this->getBasename($tpl, $name, $type);
if ($_basename === null) {
$_basename = basename(preg_replace('![^\w\/]+!', '_', $name));
}
// separate (optional) basename by dot
if ($_basename) {
$_basename = '.' . $_basename;
}
return $_compile_dir . $_filepath . '.' . $type . $_basename . $_cache . '.php';
}
/**
* Return cache file path
*
* @param Smarty_Internal_TemplateBase $tpl template object
* @param bool $sub use sub directory flag
* @param null|string $cache_id optional cache id
* @param null|string $compile_id optional compile id
* @param null|string $name optional template name
* @param null|string $type optional template type
* @param null|string $dir optional template folder
* @param null|string $cacheType optional cache resource type
*
* @return string
* @throws \Exception
*/
public function buildCachedPath($tpl, $sub = true, $cache_id = null, $compile_id = null, $name = null, $type = null,
$dir = null, $cacheType = null)
{
$cacheType = isset($cacheType) ? $cacheType : $tpl->smarty->caching_type;
switch ($cacheType) {
case 'file':
case 'filetest':
$sep = DIRECTORY_SEPARATOR;
$_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
$_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null;
$sp = $this->buildSourcePath($tpl, $name, $type, $dir);
$uid = $this->buildUid($tpl, $sp, $name, $type);
$_filepath = sha1($uid . $this->smarty->_joined_template_dir);
// if use_sub_dirs, break file into directories
if ($sub) {
$_filepath =
substr($_filepath, 0, 2) . $sep . substr($_filepath, 2, 2) . $sep . substr($_filepath, 4, 2) .
$sep . $_filepath;
}
$_compile_dir_sep = $sub ? $sep : '^';
if (isset($_cache_id)) {
$_cache_id = str_replace('|', $_compile_dir_sep, $_cache_id) . $_compile_dir_sep;
} else {
$_cache_id = '';
}
if (isset($_compile_id)) {
$_compile_id = $_compile_id . $_compile_dir_sep;
} else {
$_compile_id = '';
}
$smarty = isset($tpl->smarty) ? $tpl->smarty : $tpl;
$_cache_dir = $smarty->getCacheDir();
return $_cache_dir . $_cache_id . $_compile_id . $_filepath . '.' . basename($sp) . '.php';
case 'mysql':
case 'mysqltest':
case 'pdo':
case 'foobar':
$sp = $this->buildSourcePath($tpl, $name, $type, $dir);
$uid = $this->buildUid($tpl, $sp, $name, $type);
$_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
$_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null;
return sha1($uid . $_cache_id . $_compile_id);
case 'memcachetest':
case 'acp':
$sp = $this->buildSourcePath($tpl, $name, $type, $dir);
$uid = $this->buildUid($tpl, $sp, $name, $type);
$_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
$_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null;
return sha1($uid) . '#' . preg_replace('#[^\w\|]+#S', '_', $tpl->template_resource) . '#' . $_cache_id .
'#' . $_compile_id;
default:
throw new Exception("Unhandled cache resource type '{$cacheType}'");
}
}
/**
* prefilter to insert test number
*
* @param string $source
* @param \Smarty_Internal_Template $tpl
*
* @return string
*/
public function prefilterTest($source, Smarty_Internal_Template $tpl)
{
return str_replace('#test#', "test:{\$test nocache} compiled:{$tpl->getTemplateVars('test')} rendered:{\$test}",
$source);
}
/**
* Gat Smarty object
* @return null|\Smarty|\SmartyBC
*/
public function getSmartyObj(){
return isset($this->smarty) ? $this->smarty : (isset($this->smartyBC) ? $this->smartyBC : null);
}
public static function getSmartyPluginsDir(){
if (is_dir(dirname(__FILE__) . '/../smarty/libs/plugins')) {
return dirname(__FILE__) . '/../smarty/libs/plugins';
} else if(is_dir(dirname(__FILE__) . '/../libs/plugins')) {
return dirname(__FILE__) . '/../libs/plugins';
}
}
/**
* Tears down the fixture
* This method is called after a test is executed.
*
*/
protected function tearDown()
{
if (class_exists('Smarty_Internal_TemplateCompilerBase') &&
isset(Smarty_Internal_TemplateCompilerBase::$_tag_objects)
) {
Smarty_Internal_TemplateCompilerBase::$_tag_objects = array();
}
if (isset($this->smarty->smarty)) {
$this->smarty->smarty = null;
}
if (isset($this->smarty)) {
$this->smarty = null;
}
if (isset($this->smartyBC->smarty)) {
$this->smartyBC->smarty = null;
}
if (isset($this->smartyBC)) {
$this->smartyBC = null;
}
}
}
@@ -0,0 +1,78 @@
<?php
/*
* This file is part of the Smarty PHPUnit tests.
*/
/**
* class for path normalization tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class PathNormalizationTest extends PHPUnit_Smarty
{
/*
* Setup test fixture
*/
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
}
public function testNormalizeToAbsolute() {
$d = $this->smarty->_realpath('./foo/a.foo', true);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR . 'a.foo', $d);
}
/**public function testNormalizeAbsolute() {
if (DIRECTORY_SEPARATOR == '/') {
$d = $this->smarty->_realpath('\\foo\\a.foo', true);
$this->assertEquals('/foo/a.foo', $d);
} else {
$d = $this->smarty->_realpath('/foo/a.foo', true);
$this->assertEquals(substr(getcwd(), 0, 2) . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR . 'a.foo', $d);
$d = $this->smarty->_realpath(substr(getcwd(), 0, 2) . '/foo/a.foo', true);
$this->assertEquals(substr(getcwd(), 0, 2) . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR . 'a.foo', $d);
}
}
* */
public function testNormalizeToAbsoluteNoStart() {
$d = $this->smarty->_realpath('foo/a.foo', true);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR . 'a.foo', $d);
}
public function testNormalizeToAbsoluteNoStart2() {
$d = $this->smarty->_realpath('a.foo', true);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'a.foo', $d);
}
public function testNormalizeToAbsolutePathLeadingDot() {
$d = $this->smarty->_realpath('.foo/a.foo', true);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . '.foo' . DIRECTORY_SEPARATOR . 'a.foo', $d);
}
public function testNormalizeToAbsolutePathTrailingDot() {
$d = $this->smarty->_realpath('./foo./a.foo', true);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo.' . DIRECTORY_SEPARATOR . 'a.foo', $d);
}
public function testNormalizeToAbsolutePathBubbleUp() {
$ds = '\\' . DIRECTORY_SEPARATOR;
$prefix = preg_replace("#[{$ds}][^{$ds}]+$#", '', getcwd());
$d = $this->smarty->_realpath('./../a.foo', true);
$this->assertEquals($prefix . DIRECTORY_SEPARATOR . 'a.foo', $d);
}
public function testNormalizeToAbsolutePathBubbleUp2() {
$ds = '\\' . DIRECTORY_SEPARATOR;
$prefix = preg_replace("#[{$ds}][^{$ds}]+$#", '', getcwd());
$d = $this->smarty->_realpath('././../././a.foo', true);
$this->assertEquals($prefix . DIRECTORY_SEPARATOR . 'a.foo', $d);
}
public function testNormalizeToAbsolutePathBubbleUp3() {
$ds = '\\' . DIRECTORY_SEPARATOR;
$prefix = preg_replace("#[{$ds}][^{$ds}]+[{$ds}][^{$ds}]+$#", '', getcwd());
$d = $this->smarty->_realpath('././.././.././a.foo', true);
$this->assertEquals($prefix . DIRECTORY_SEPARATOR . 'a.foo', $d);
}
public function testNormalizeToAbsoluteKomplex() {
$d = $this->smarty->_realpath('./foo/\\./bar/jo/wie/so/../..///.././././../aa/bb/cc/../../go/a.foo', true);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR . 'aa'. DIRECTORY_SEPARATOR . 'go' . DIRECTORY_SEPARATOR .'a.foo', $d);
}
}
@@ -0,0 +1,145 @@
<?php
/*
* This file is part of the Smarty PHPUnit tests.
*/
/**
* class for path normalization tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class PluginNormalizationTest extends PHPUnit_Smarty
{
/*
* Setup test fixture
*/
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
}
public function testGetPluginsDefaultDir()
{
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->assertEquals(SMARTY_PLUGINS_DIR, $result[ 0 ]);
}
public function testGetPluginsDefaultDir2()
{
$this->smarty->addPluginsDir('./foo/');
$result = $this->smarty->getPluginsDir();
$this->assertEquals(2, count($result));
$this->assertEquals(SMARTY_PLUGINS_DIR, $result[ 0 ]);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 1 ]);
}
public function testSetPluginsDir1()
{
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->smarty->setPluginsDir('foo');
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
}
public function testSetPluginsDir2()
{
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->smarty->setPluginsDir('foo/');
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
}
public function testSetPluginsDir3()
{
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->smarty->setPluginsDir('foo/.');
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
}
public function testSetPluginsDir4()
{
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->smarty->setPluginsDir('foo/./');
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
}
public function testSetPluginsDir5()
{
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->smarty->setPluginsDir('.foo');
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . '.foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
}
public function testSetPluginsDir6()
{
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->smarty->setPluginsDir('..foo');
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . '..foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
}
public function testSetPluginsDir7()
{
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->smarty->setPluginsDir('../foo');
$result = $this->smarty->getPluginsDir();
$this->assertEquals(1, count($result));
$this->assertEquals(substr(getcwd(), 0, - strlen(basename(getcwd()))) . 'foo' . DIRECTORY_SEPARATOR,
$result[ 0 ]);
}
public function testSetPluginsDir8()
{
$this->smarty->setPluginsDir(array('foo', 'bah'));
$result = $this->smarty->getPluginsDir();
$this->assertEquals(2, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'bah' . DIRECTORY_SEPARATOR, $result[ 1 ]);
}
public function testSetPluginsDir9()
{
$this->smarty->setPluginsDir(array('foo', 'bah'));
$result = $this->smarty->getPluginsDir();
$this->assertEquals(2, count($result));
$this->smarty->addPluginsDir('blar');
$result = $this->smarty->getPluginsDir();
$this->assertEquals(3, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'bah' . DIRECTORY_SEPARATOR, $result[ 1 ]);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'blar' . DIRECTORY_SEPARATOR, $result[ 2 ]);
}
public function testSetPluginsDir10()
{
$this->smarty->setPluginsDir(array('foo', 'bah'));
$result = $this->smarty->getPluginsDir();
$this->assertEquals(2, count($result));
$this->smarty->addPluginsDir(array('blar', 'smarty'));
$result = $this->smarty->getPluginsDir();
$this->assertEquals(4, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'bah' . DIRECTORY_SEPARATOR, $result[ 1 ]);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'blar' . DIRECTORY_SEPARATOR, $result[ 2 ]);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'smarty' . DIRECTORY_SEPARATOR, $result[ 3 ]);
}
}
@@ -0,0 +1,137 @@
<?php
/*
* This file is part of the Smarty PHPUnit tests.
*/
/**
* class for path normalization tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class TemplateNormalizationTest extends PHPUnit_Smarty
{
/*
* Setup test fixture
*/
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
}
public function testGetTemplateDir()
{
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR, $result[ 0 ]);
}
public function testSetTemplateDir1()
{
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->smarty->setTemplateDir('foo');
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
}
public function testSetTemplateDir2()
{
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->smarty->setTemplateDir('foo/');
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
}
public function testSetTemplateDir3()
{
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->smarty->setTemplateDir('foo/.');
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
}
public function testSetTemplateDir4()
{
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->smarty->setTemplateDir('foo/./');
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
}
public function testSetTemplateDir5()
{
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->smarty->setTemplateDir('.foo');
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . '.foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
}
public function testSetTemplateDir6()
{
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->smarty->setTemplateDir('..foo');
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . '..foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
}
public function testSetTemplateDir7()
{
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->smarty->setTemplateDir('../foo');
$result = $this->smarty->getTemplateDir();
$this->assertEquals(1, count($result));
$this->assertEquals(substr(getcwd(), 0, - strlen(basename(getcwd()))) . 'foo' . DIRECTORY_SEPARATOR,
$result[ 0 ]);
}
public function testSetTemplateDir8()
{
$this->smarty->setTemplateDir(array('foo', 'bah'));
$result = $this->smarty->getTemplateDir();
$this->assertEquals(2, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'bah' . DIRECTORY_SEPARATOR, $result[ 1 ]);
}
public function testSetTemplateDir9()
{
$this->smarty->setTemplateDir(array('foo', 'bah'));
$result = $this->smarty->getTemplateDir();
$this->assertEquals(2, count($result));
$this->smarty->addTemplateDir('blar');
$result = $this->smarty->getTemplateDir();
$this->assertEquals(3, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'bah' . DIRECTORY_SEPARATOR, $result[ 1 ]);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'blar' . DIRECTORY_SEPARATOR, $result[ 2 ]);
}
public function testSetTemplateDir10()
{
$this->smarty->setTemplateDir(array('foo', 'bah'));
$result = $this->smarty->getTemplateDir();
$this->assertEquals(2, count($result));
$this->smarty->addTemplateDir(array('blar', 'smarty'));
$result = $this->smarty->getTemplateDir();
$this->assertEquals(4, count($result));
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $result[ 0 ]);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'bah' . DIRECTORY_SEPARATOR, $result[ 1 ]);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'blar' . DIRECTORY_SEPARATOR, $result[ 2 ]);
$this->assertEquals(getcwd() . DIRECTORY_SEPARATOR . 'smarty' . DIRECTORY_SEPARATOR, $result[ 3 ]);
}
}
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1,226 @@
<?php
/*
* This file is part of the Smarty PHPUnit tests.
*/
/**
* class for protected $template_dir, $compile_dir, $cache_dir, $config_dir, $plugins_dir property tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class ProtectedFolderVarsTest extends PHPUnit_Smarty
{
/*
* Setup test fixture
*/
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
}
/*
* template_dir
*/
public function testTemplateDirDirectRelative()
{
$s = new Smarty();
$s->template_dir = './foo';
$d = $s->getTemplateDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $d[ 0 ]);
}
public function testTemplateDirDirectRelativeArray()
{
$s = new Smarty();
$s->template_dir = array('./foo', './bar/');
$d = $s->template_dir;
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $d[ 0 ]);
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'bar' . DIRECTORY_SEPARATOR, $d[ 1 ]);
}
public function testTemplateDirDirectRelativeArrayAdd()
{
$s = new Smarty();
$s->template_dir = './foo';
$s->addTemplateDir('./bar/');
$d = $s->getTemplateDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $d[ 0 ]);
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'bar' . DIRECTORY_SEPARATOR, $d[ 1 ]);
}
public function testTemplateDirDirectRelativeExtends()
{
$s = new FolderT();
$d = $s->getTemplateDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $d[ 0 ]);
}
public function testTemplateDirDirectRelativeExtends2()
{
$s = new FolderT();
$s->template_dir = './bar';
$d = $s->getTemplateDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'bar' . DIRECTORY_SEPARATOR, $d[ 0 ]);
}
/*
* config_dir
*/
public function testConfigDirDirectRelative()
{
$s = new Smarty();
$s->config_dir = './foo';
$d = $s->getConfigDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $d[ 0 ]);
}
public function testConfigDirDirectRelativeArray()
{
$s = new Smarty();
$s->config_dir = array('./foo', './bar/');
$d = $s->config_dir;
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $d[ 0 ]);
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'bar' . DIRECTORY_SEPARATOR, $d[ 1 ]);
}
public function testConfigDirDirectRelativeArrayAdd()
{
$s = new Smarty();
$s->config_dir = './foo';
$s->addConfigDir('./bar/');
$d = $s->getConfigDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $d[ 0 ]);
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'bar' . DIRECTORY_SEPARATOR, $d[ 1 ]);
}
public function testConfigDirDirectRelativeExtends()
{
$s = new FolderT();
$d = $s->getConfigDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'conf' . DIRECTORY_SEPARATOR, $d[ 0 ]);
}
public function testConfigDirDirectRelativeExtends2()
{
$s = new FolderT();
$s->config_dir = './bar';
$d = $s->getConfigDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'bar' . DIRECTORY_SEPARATOR, $d[ 0 ]);
}
/*
* plugins_dir
*/
public function testPluginDirDirectRelative()
{
$s = new Smarty();
$s->plugins_dir = './foo';
$d = $s->getPluginsDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $d[ 0 ]);
}
public function testPluginDirDirectRelativeArray()
{
$s = new Smarty();
$s->plugins_dir = array('./foo', './bar/');
$d = $s->plugins_dir;
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $d[ 0 ]);
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'bar' . DIRECTORY_SEPARATOR, $d[ 1 ]);
}
public function testPluginDirDirectRelativeArrayAdd()
{
$s = new Smarty();
$s->plugins_dir = './foo';
$s->addPluginsDir('./bar/');
$d = $s->getPluginsDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $d[ 0 ]);
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'bar' . DIRECTORY_SEPARATOR, $d[ 1 ]);
}
public function testPluginDirDirectRelativeExtends()
{
$s = new FolderT();
$d = $s->getPluginsDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'plug' . DIRECTORY_SEPARATOR, $d[ 0 ]);
}
public function testPluginDirDirectRelativeExtends2()
{
$s = new FolderT();
$s->plugins_dir = './bar';
$d = $s->getPluginsDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'bar' . DIRECTORY_SEPARATOR, $d[ 0 ]);
}
/*
* compile_dir
*/
public function testCompileDirDirectRelative()
{
$s = new Smarty();
$s->compile_dir = './foo';
$d = $s->getCompileDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $d);
}
public function testCompileDirDirectRelativeExtends()
{
$s = new FolderT();
$d = $s->getCompileDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'comp' . DIRECTORY_SEPARATOR, $d);
}
public function testCompileDirDirectRelativeExtends2()
{
$s = new FolderT();
$s->compile_dir = './bar';
$d = $s->getCompileDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'bar' . DIRECTORY_SEPARATOR, $d);
}
/*
* cache_dir
*/
public function testCacheDirDirectRelative()
{
$s = new Smarty();
$s->cache_dir = './foo';
$d = $s->getCacheDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'foo' . DIRECTORY_SEPARATOR, $d);
}
public function testCacheDirDirectRelativeExtends()
{
$s = new FolderT();
$d = $s->getCacheDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR, $d);
}
public function testCacheDirDirectRelativeExtends2()
{
$s = new FolderT();
$s->cache_dir = './bar';
$d = $s->getCacheDir();
$this->assertEquals(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'bar' . DIRECTORY_SEPARATOR, $d);
}
}
class FolderT extends Smarty
{
protected $template_dir = './foo';
protected $compile_dir = './comp/';
protected $plugins_dir = './plug/';
protected $cache_dir = './cache/';
protected $config_dir = array('./conf/');
}
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1,92 @@
<?php
/*
* This file is part of the Smarty PHPUnit tests.
*/
/**
* class for protected $template_dir, $compile_dir, $cache_dir, $config_dir, $plugins_dir property tests
*
* @backupStaticAttributes enabled
*/
class UndefinedTemplateVarTest extends PHPUnit_Smarty
{
/*
* Setup test fixture
*/
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
error_reporting(E_ALL | E_STRICT);
}
public function testInit()
{
$this->cleanDirs();
}
/**
* Test Error suppression template fetched by Smarty object
*/
public function testErrorDisabled()
{
$e1 = error_reporting();
$this->smarty->setErrorReporting(E_ALL & ~E_WARNING & ~E_NOTICE);
$this->assertEquals('undefined = ', $this->smarty->fetch('001_main.tpl'));
$e2 = error_reporting();
$this->assertEquals($e1, $e2);
}
/**
* Test Error suppression template fetched by template object
*/
public function testErrorDisabledTplObject_1()
{
$e1 = error_reporting();
$this->smarty->setErrorReporting(E_ALL & ~E_WARNING & ~E_NOTICE);
$tpl = $this->smarty->createTemplate('001_main.tpl');
$this->assertEquals('undefined = ', $tpl->fetch());
$e2 = error_reporting();
$this->assertEquals($e1, $e2);
}
/**
* Test Error suppression template object fetched by Smarty object
*/
public function testErrorDisabledTplObject_2()
{
$e1 = error_reporting();
$this->smarty->setErrorReporting(E_ALL & ~E_WARNING & ~E_NOTICE);
$tpl = $this->smarty->createTemplate('001_main.tpl');
$this->assertEquals('undefined = ', $this->smarty->fetch($tpl));
$e2 = error_reporting();
$this->assertEquals($e1, $e2);
}
/**
* Throw Error message
*/
public function testError()
{
$exceptionThrown = false;
try {
$e1 = error_reporting();
$this->assertEquals('undefined = ', $this->smarty->fetch('001_main.tpl'));
$e2 = error_reporting();
$this->assertEquals($e1, $e2);
} catch (Exception $e) {
$exceptionThrown = true;
$this->assertStringStartsWith('Undefined ', $e->getMessage());
$this->assertTrue(in_array(
get_class($e),
array(
'PHPUnit_Framework_Error_Warning',
'PHPUnit_Framework_Error_Notice',
'PHPUnit\Framework\Error\Warning',
'PHPUnit\Framework\Error\Notice',
)
));
}
$this->assertTrue($exceptionThrown);
}
}
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1 @@
undefined = {$foo}
@@ -0,0 +1 @@
{include '001_include.tpl'}
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1,33 @@
<?php
/*
* This file is part of the Smarty PHPUnit tests.
*/
/**
* class for 'escapeHtml' property tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class AutoEscapeTest extends PHPUnit_Smarty
{
/*
* Setup test fixture
*/
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
$this->smarty->setEscapeHtml(true);
}
/**
* test 'escapeHtml' property
*/
public function testAutoEscape()
{
$tpl = $this->smarty->createTemplate('eval:{$foo}');
$tpl->assign('foo', '<a@b.c>');
$this->assertEquals("&lt;a@b.c&gt;", $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
*
@@ -0,0 +1,14 @@
<?php
/**
* test registered pre filter closure
* @requires PHP 5.3
*/
$this->smarty->registerFilter(Smarty::FILTER_PRE, function ($input) {
return '{$foo}' . $input;
});
$tpl = $this->smarty->createTemplate('eval:{" hello world"}');
$tpl->assign('foo', 'buh');
$this->assertEquals("buh hello world", $this->smarty->fetch($tpl));
@@ -0,0 +1,279 @@
<?php
/**
* Smarty PHPunit tests of filter
*
* @package PHPunit
* @author Uwe Tews
*/
/**
* class for filter tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class FilterTest extends PHPUnit_Smarty
{
public $loadSmartyBC = true;
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
}
public function testInit()
{
$this->cleanDirs();
}
/**
* test autoload output filter
*/
public function testAutoloadOutputFilter()
{
$this->smarty->autoload_filters[ 'output' ] = 'trimwhitespace';
$tpl = $this->smarty->createTemplate('eval:{" <br>hello world"}');
$this->assertEquals("<br>hello world", $this->smarty->fetch($tpl));
}
/**
* test autoload variable filter
*/
public function testAutoloadVariableFilter()
{
$this->smarty->autoload_filters[ 'variable' ] = 'htmlspecialchars';
$tpl = $this->smarty->createTemplate('eval:{"<test>"}');
$this->assertEquals("&lt;test&gt;", $this->smarty->fetch($tpl));
}
/**
* test loaded filter
*/
public function testLoadedOutputFilter()
{
$this->smarty->loadFilter(Smarty::FILTER_OUTPUT, 'trimwhitespace');
$tpl = $this->smarty->createTemplate('string:{" <br>hello world"}');
$this->assertEquals("<br>hello world", $this->smarty->fetch($tpl));
}
public function testLoadedOutputFilterWrapper()
{
$this->smartyBC->load_filter(Smarty::FILTER_OUTPUT, 'trimwhitespace');
$tpl = $this->smartyBC->createTemplate('eval:{" <br>hello world"}');
$this->assertEquals("<br>hello world", $this->smartyBC->fetch($tpl));
}
/**
* test registered output filter
*/
public function testRegisteredOutputFilter()
{
$this->smarty->registerFilter(Smarty::FILTER_OUTPUT, 'myoutputfilter');
$tpl = $this->smarty->createTemplate('eval:{"hello world"}');
$this->assertEquals("hello world", $this->smarty->fetch($tpl));
}
/**
* test registered output filter not cached
*
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testRegisteredOutputFilter_001()
{
$this->smarty->assign('foo', 1);
$this->smarty->assign('bar', 2);
$this->smarty->registerFilter(Smarty::FILTER_OUTPUT, 'myoutputfilter2');
$this->assertEquals('1 filter 2', $this->smarty->fetch('output_001.tpl'));
}
/**
* test registered output filter not cached 2"
*
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testRegisteredOutputFilter_001_2()
{
$this->smarty->assign('foo', 3);
$this->smarty->assign('bar', 4);
$this->smarty->registerFilter(Smarty::FILTER_OUTPUT, 'myoutputfilter2');
$this->assertEquals('3 filter 4', $this->smarty->fetch('output_001.tpl'));
}
/**
* test registered output filter cached 1"
*
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testRegisteredOutputFilter_001_3()
{
$this->smarty->setCaching(true);
$this->smarty->assign('foo', 5);
$this->smarty->assign('bar', 6);
$this->smarty->registerFilter(Smarty::FILTER_OUTPUT, 'myoutputfilter2');
$this->assertEquals('5 filter 6', $this->smarty->fetch('output_001.tpl'));
}
/**
* test registered output filter cached 1"
*
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testRegisteredOutputFilter_001_4()
{
$this->smarty->setCaching(true);
$this->smarty->assign('foo', 7);
$this->smarty->assign('bar', 8);
$this->smarty->registerFilter(Smarty::FILTER_OUTPUT, 'myoutputfilter2');
$this->assertEquals('5 filter 6', $this->smarty->fetch('output_001.tpl'));
}
/**
* test registered output filter cached nocache"
*
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testRegisteredOutputFilter_002_1()
{
$this->smarty->setCaching(true);
$this->smarty->assign('foo', 10);
$this->smarty->assign('bar', 11);
$this->smarty->registerFilter(Smarty::FILTER_OUTPUT, 'myoutputfilter2');
$this->assertEquals('10 filter 11', $this->smarty->fetch('output_002.tpl'));
}
/**
* test registered output filter cached nocache"
*
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testRegisteredOutputFilter_002_2()
{
$this->smarty->setCaching(true);
$this->smarty->assign('foo', 12);
$this->smarty->assign('bar', 13);
$this->smarty->registerFilter(Smarty::FILTER_OUTPUT, 'myoutputfilter2');
$this->assertEquals('12 filter 13', $this->smarty->fetch('output_002.tpl'));
}
public function testRegisteredOutputFilterWrapper()
{
$this->smartyBC->register_outputfilter('myoutputfilter');
$tpl = $this->smartyBC->createTemplate('eval:{"hello world"}');
$this->assertEquals("hello world", $this->smartyBC->fetch($tpl));
}
/**
* test registered pre filter
*/
public function testRegisteredPreFilter()
{
function myprefilter($input)
{
return '{$foo}' . $input;
}
$this->smarty->registerFilter(Smarty::FILTER_PRE, 'myprefilter');
$tpl = $this->smarty->createTemplate('eval:{" hello world"}');
$tpl->assign('foo', 'bar');
$this->assertEquals("bar hello world", $this->smarty->fetch($tpl));
}
/**
* test registered pre filter closure
* @requires PHP 5.3
*/
public function testRegisteredPreFilterClosure()
{
if (version_compare(PHP_VERSION,'5.3','<'))
{
$this->markTestSkipped('does not run for PHP 5.2');
} else {
include 'FilterClosure.php';
}
}
/**
* test registered pre filter class
*/
public function testRegisteredPreFilterClass()
{
$this->smarty->registerFilter(Smarty::FILTER_PRE, array('myprefilterclass', 'myprefilter'));
$tpl = $this->smarty->createTemplate('eval:{" hello world"}');
$tpl->assign('foo', 'bar');
$this->assertEquals("bar hello world", $this->smarty->fetch($tpl));
}
/**
* test registered post filter
*/
public function testRegisteredPostFilter()
{
function mypostfilter($input)
{
return '{$foo}' . $input;
}
$this->smarty->registerFilter(Smarty::FILTER_POST, 'mypostfilter');
$tpl = $this->smarty->createTemplate('eval:{" hello world"}');
$tpl->assign('foo', 'bar');
$this->assertEquals('{$foo} hello world', $this->smarty->fetch($tpl));
}
/**
* test variable filter
*/
public function testLoadedVariableFilter()
{
$this->smarty->loadFilter("variable", "htmlspecialchars");
$tpl = $this->smarty->createTemplate('eval:{$foo}');
$tpl->assign('foo', '<?php ?>');
$this->assertEquals('&lt;?php ?&gt;', $this->smarty->fetch($tpl));
}
/**
* test registered post filter
*/
public function testRegisteredVariableFilter2()
{
$var = new VarFilter();
$this->smarty->registerFilter(Smarty::FILTER_VARIABLE, array($var, 'variablefilter'));
$tpl = $this->smarty->createTemplate('string:{$foo}');
$tpl->assign('foo', 'bar');
$this->assertEquals('var{$foo}bar', $this->smarty->fetch($tpl));
}
}
Class VarFilter
{
function variablefilter($input, $smarty)
{
return 'var{$foo}' . $input;
}
}
function myoutputfilter($input)
{
return str_replace(' ', ' ', $input);
}
function myoutputfilter2($input, $tpl)
{
return $input . ' filter ' . $tpl->tpl_vars[ 'bar' ];
}
class myprefilterclass
{
static function myprefilter($input)
{
return '{$foo}' . $input;
}
}
@@ -0,0 +1,31 @@
<?php
/**
* Smarty PHPunit tests loadFilter method
*
* @package PHPunit
* @author Uwe Tews
*/
/**
* class for loadFilter method tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class LoadFilterTest extends PHPUnit_Smarty
{
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
}
/**
* test loadFilter method
*/
public function testLoadFilter()
{
$this->smarty->loadFilter('output', 'trimwhitespace');
$this->assertTrue(is_callable($this->smarty->registered_filters['output']['smarty_outputfilter_trimwhitespace']));
}
}
@@ -0,0 +1,158 @@
<?php
/**
* Smarty PHPunit tests register_filter / unregister_filter methods
*
* @package PHPunit
* @author Uwe Tews
*/
/**
* class for register_filter / unregister_filter methods tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class RegisterFilterTest extends PHPUnit_Smarty
{
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
}
/**
* test register->preFilter method for function
*/
public function testRegisterPrefilterFunction()
{
$this->smarty->registerFilter(Smarty::FILTER_PRE, 'myfilter');
$this->assertTrue(is_callable($this->smarty->registered_filters['pre']['myfilter']));
}
/**
* test register->preFilter method for class method
*/
public function testRegisterPrefiltermethod()
{
$this->smarty->registerFilter(Smarty::FILTER_PRE, array('myfilterclass', 'execute'));
$this->assertTrue(is_callable($this->smarty->registered_filters['pre']['myfilterclass_execute']));
}
/**
* test register->preFilter method for class object
*/
public function testRegisterPrefilterObject()
{
$this->smarty->registerFilter(Smarty::FILTER_PRE, array(new myfilterclass, 'execute'));
$this->assertTrue(is_callable($this->smarty->registered_filters['pre']['myfilterclass_execute']));
}
/**
* test unregister->preFilter method for function
*/
public function testUnegisterPrefilterFunction()
{
$this->smarty->registerFilter(Smarty::FILTER_PRE, 'myfilter');
$this->smarty->unregisterFilter(Smarty::FILTER_PRE, 'myfilter');
$this->assertFalse(isset($this->smarty->registered_filters['pre']['myfilter']));
}
/**
* test unregister->preFilter method for class method
*/
public function testUnregisterPrefiltermethod()
{
$this->smarty->registerFilter(Smarty::FILTER_PRE, array('myfilterclass', 'execute'));
$this->smarty->unregisterFilter(Smarty::FILTER_PRE, array('myfilterclass', 'execute'));
$this->assertFalse(isset($this->smarty->registered_filters['pre']['myfilterclass_execute']));
}
/**
* test register->postFilter method for function
*/
public function testRegisterPostfilterFunction()
{
$this->smarty->registerFilter(Smarty::FILTER_POST, 'myfilter');
$this->assertTrue(is_callable($this->smarty->registered_filters['post']['myfilter']));
}
/**
* test register->postFilter method for class method
*/
public function testRegisterPostfiltermethod()
{
$this->smarty->registerFilter(Smarty::FILTER_POST, array('myfilterclass', 'execute'));
$this->assertTrue(is_callable($this->smarty->registered_filters['post']['myfilterclass_execute']));
}
/**
* test unregister->postFilter method for function
*/
public function testUnegisterPostfilterFunction()
{
$this->smarty->registerFilter(Smarty::FILTER_POST, 'myfilter');
$this->smarty->unregisterFilter(Smarty::FILTER_POST, 'myfilter');
$this->assertFalse(isset($this->smarty->registered_filters['post']['myfilter']));
}
/**
* test unregister->postFilter method for class method
*/
public function testUnregisterPostfiltermethod()
{
$this->smarty->registerFilter(Smarty::FILTER_POST, array('myfilterclass', 'execute'));
$this->smarty->unregisterFilter(Smarty::FILTER_POST, array('myfilterclass', 'execute'));
$this->assertFalse(isset($this->smarty->registered_filters['post']['myfilterclass_execute']));
}
/**
* test register->outputFilter method for function
*/
public function testRegisterOutputfilterFunction()
{
$this->smarty->registerFilter(Smarty::FILTER_OUTPUT, 'myfilter');
$this->assertTrue(is_callable($this->smarty->registered_filters['output']['myfilter']));
}
/**
* test register->outputFilter method for class method
*/
public function testRegisterOutputfiltermethod()
{
$this->smarty->registerFilter(Smarty::FILTER_OUTPUT, array('myfilterclass', 'execute'));
$this->assertTrue(is_callable($this->smarty->registered_filters['output']['myfilterclass_execute']));
}
/**
* test unregister->outputFilter method for function
*/
public function testUnegisterOutputfilterFunction()
{
$this->smarty->registerFilter(Smarty::FILTER_OUTPUT, 'myfilter');
$this->smarty->unregisterFilter(Smarty::FILTER_OUTPUT, 'myfilter');
$this->assertFalse(isset($this->smarty->registered_filters['output']['myfilter']));
}
/**
* test unregister->outputFilter method for class method
*/
public function testUnregisterOutputfiltermethod()
{
$this->smarty->registerFilter(Smarty::FILTER_OUTPUT, array('myfilterclass', 'execute'));
$this->smarty->unregisterFilter(Smarty::FILTER_OUTPUT, array('myfilterclass', 'execute'));
$this->assertFalse(isset($this->smarty->registered_filters['output']['myfilterclass_execute']));
}
}
function myfilter($input)
{
return $input;
}
class myfilterclass
{
static function execute($input)
{
return $input;
}
}
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1 @@
{$foo}
@@ -0,0 +1 @@
{$foo nocache}
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1,75 @@
<?php
/**
* Smarty PHPunit tests of generic getter/setter
*
* @package PHPunit
* @author Uwe Tews
*/
/**
* class for generic getter/setter tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class GetterSetterTest extends PHPUnit_Smarty
{
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
}
public function testInit()
{
$this->cleanDirs();
}
/**
* test setter on Smarty object
*/
public function testSmartySetter()
{
$this->smarty->setLeftDelimiter('<{');
$this->smarty->setRightDelimiter('}>');
$this->assertEquals('<{', $this->smarty->left_delimiter);
$this->assertEquals('}>', $this->smarty->right_delimiter);
}
/**
* test getter on Smarty object
*/
public function testSmartyGetter()
{
$this->smarty->setLeftDelimiter('<{');
$this->smarty->setRightDelimiter('}>');
$this->assertEquals('<{', $this->smarty->getLeftDelimiter());
$this->assertEquals('}>', $this->smarty->getRightDelimiter());
}
/**
* test setter on Template object
*/
public function testTemplateSetter()
{
$tpl = $this->smarty->createTemplate('helloworld.tpl');
$tpl->setLeftDelimiter('<{');
$tpl->setRightDelimiter('}>');
$this->assertEquals('<{', $tpl->smarty->left_delimiter);
$this->assertEquals('}>', $tpl->smarty->right_delimiter);
$this->assertEquals('{', $this->smarty->left_delimiter);
$this->assertEquals('}', $this->smarty->right_delimiter);
}
/**
* test getter on Template object
*/
public function testTemplateGetter()
{
$tpl = $this->smarty->createTemplate('helloworld.tpl');
$tpl->setLeftDelimiter('<{');
$tpl->setRightDelimiter('}>');
$this->assertEquals('<{', $tpl->getLeftDelimiter());
$this->assertEquals('}>', $tpl->getRightDelimiter());
}
}
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1,182 @@
<?php
/**
* Smarty PHPunit tests deault plugin handler
*
* @package PHPunit
* @author Uwe Tews
*/
/**
* class for plugin handler tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class DefaultPluginHandlerTest extends PHPUnit_Smarty
{
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
$this->smarty->setForceCompile(true);
$this->smarty->disableSecurity();
$this->smarty->registerDefaultPluginHandler('my_plugin_handler');
}
public function testInit()
{
$this->cleanDirs();
}
public function testDefaultFunctionScript()
{
$this->assertEquals("scriptfunction foo bar", $this->smarty->fetch('test_default_function_script.tpl'));
}
public function testDefaultFunctionScriptNotCachable1()
{
$this->smarty->assign('foo', 'foo');
$this->smarty->caching = 1;
$this->assertEquals("scriptfunction foo", $this->smarty->fetch('test_default_function_script_notcachable.tpl'));
}
public function testDefaultFunctionScriptNotCachable2()
{
$this->smarty->assign('foo', 'bar');
$this->smarty->caching = 1;
$this->assertEquals("scriptfunction bar", $this->smarty->fetch('test_default_function_script_notcachable.tpl'));
}
public function testDefaultFunctionLocal()
{
$this->assertEquals("localfunction foo bar", $this->smarty->fetch('test_default_function_local.tpl'));
}
public function testDefaultCompilerFunctionScript()
{
$this->assertEquals("echo 'scriptcompilerfunction '.'foo bar';", $this->smarty->fetch('test_default_compiler_function_script.tpl'));
}
public function testDefaultCompilerObject()
{
$this->assertEquals('Public World', $this->smarty->fetch('test_default_compiler_object.tpl'));
}
public function testDefaultBlockScript()
{
$this->assertEquals("scriptblock foo bar", $this->smarty->fetch('test_default_block_script.tpl'));
}
public function testDefaultModifierScript()
{
$this->smarty->assign('foo', 'bar');
$this->assertEquals("scriptmodifier default bar", $this->smarty->fetch('test_default_modifier_script.tpl'));
}
public function testDefaultModifier()
{
$this->smarty->assign('foo', 'bar');
$this->assertEquals("localmodifier bar", $this->smarty->fetch('test_default_modifier.tpl'));
}
public function testDefaultModifierStaticClassMethodCaching1()
{
$this->smarty->assign('foo', 'bar');
$this->smarty->caching = 1;
$this->assertEquals("staticmodifier bar", $this->smarty->fetch('test_default_static_modifier.tpl'));
}
public function testDefaultModifierStaticClassMethodCaching2()
{
$this->smarty->assign('foo', 'bar');
$this->smarty->caching = 1;
$this->assertEquals("staticmodifier bar", $this->smarty->fetch('test_default_static_modifier.tpl'));
}
}
function my_plugin_handler($tag, $type, $template, &$callback, &$script, &$cachable)
{
switch ($type) {
case Smarty::PLUGIN_FUNCTION:
switch ($tag) {
case 'scriptfunction':
$script = './scripts/script_function_tag.php';
$callback = 'default_script_function_tag';
return true;
case 'scriptfunctionnotcachable':
$script = './scripts/script_function_tag.php';
$callback = 'default_script_function_tag';
$cachable = false;
return true;
case 'localfunction':
$callback = 'default_local_function_tag';
return true;
default:
return false;
}
case Smarty::PLUGIN_COMPILER:
switch ($tag) {
case 'scriptcompilerfunction':
$script = './scripts/script_compiler_function_tag.php';
$callback = 'default_script_compiler_function_tag';
return true;
case 'compilerobject':
$callback = array(new CompilerDefaultPluginClass, 'compile');
return true;
default:
return false;
}
case Smarty::PLUGIN_BLOCK:
switch ($tag) {
case 'scriptblock':
$script = './scripts/script_block_tag.php';
$callback = 'default_script_block_tag';
return true;
default:
return false;
}
case Smarty::PLUGIN_MODIFIER:
switch ($tag) {
case 'scriptmodifier':
$script = './scripts/script_modifier.php';
$callback = 'default_script_modifier';
return true;
case 'mydefaultmodifier':
$callback = 'default_local_modifier';
return true;
case 'mydefaultstaticmodifier':
$script = './scripts/script_default_static_modifier.php';
$callback = array('DefModifier', 'default_static_modifier');
return true;
default:
return false;
}
default:
return false;
}
}
function default_local_function_tag($params, $template)
{
return 'localfunction ' . $params['value'];
}
function default_local_modifier($input)
{
return 'localmodifier ' . $input;
}
class CompilerDefaultPluginClass
{
static function statCompile ($params, $compiler) {
return '<?php echo \'Static World\';?>';
}
public function compile ($params, $compiler) {
return '<?php echo \'Public World\';?>';
}
}
@@ -0,0 +1,51 @@
<?php
/**
* Smarty PHPunit tests for File resources
*
* @package PHPunit
* @author Rodney Rehm
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class IncludePathTest extends PHPUnit_Smarty
{
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
$this->smarty->use_include_path = true;
$this->smarty->setPluginsDir(array('./include','./include1'));
$this->smarty->enableSecurity();
$ds = DIRECTORY_SEPARATOR;
set_include_path($this->smarty->_realpath(dirname(__FILE__) . "{$ds}..{$ds}..{$ds}..{$ds}Include_Path{$ds}Plugins{$ds}", true) . PATH_SEPARATOR . get_include_path());
}
/**
* Tears down the fixture
* This method is called after a test is executed.
*
*/
protected function tearDown()
{
ini_restore('include_path');
$this->smarty->disableSecurity();
parent::tearDown();
}
public function testInit()
{
$this->cleanDirs();
}
public function testInclude1()
{
$this->assertContains('plugin1', $this->smarty->fetch('test_include_path1.tpl'));
}
public function testInclude2()
{
$this->assertContains('plugin2', $this->smarty->fetch('test_include_path2.tpl'));
}
public function testInclude3()
{
$this->assertContains('plugin3', $this->smarty->fetch('test_include_path3.tpl'));
}
}
@@ -0,0 +1,54 @@
<?php
/**
* Smarty PHPunit basic core function tests
*
* @package PHPunit
* @author Uwe Tews
*/
/**
* class core function tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class LoadPluginTest extends PHPUnit_Smarty
{
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
}
/**
* loadPlugin test unkown plugin
*/
public function testLoadPluginErrorReturn()
{
$this->assertFalse($this->smarty->loadPlugin('Smarty_Not_Known'));
}
/**
* loadPlugin test Smarty_Internal_Debug exists
*/
public function testLoadPluginSmartyInternalDebug()
{
$this->assertTrue($this->smarty->loadPlugin('Smarty_Internal_Debug') == true);
}
/**
* loadPlugin test $template_class exists
*/
public function testLoadPluginSmartyTemplateClass()
{
$this->assertTrue($this->smarty->loadPlugin($this->smarty->template_class) == true);
}
/**
* loadPlugin test loaging from plugins_dir
*/
public function testLoadPluginSmartyPluginCounter()
{
$this->assertTrue($this->smarty->loadPlugin('Smarty_Function_Counter') == true);
}
}
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1,5 @@
<?php
function smarty_function_plugin3($params, $template)
{
return 'plugin3';
}
@@ -0,0 +1,7 @@
<?php
function default_script_block_tag($params, $content, $template, &$repeat)
{
if (isset($content)) {
return 'scriptblock ' . $content;
}
}
@@ -0,0 +1,5 @@
<?php
function default_script_compiler_function_tag($params, $template)
{
return "echo 'scriptcompilerfunction '." . $params['value'] . ";";
}
@@ -0,0 +1,10 @@
<?php
if (!class_exists('DefModifier')) {
Class DefModifier
{
static function default_static_modifier($input)
{
return 'staticmodifier ' . $input;
}
}
}
@@ -0,0 +1,5 @@
<?php
function default_script_function_tag($params, $template)
{
return 'scriptfunction ' . $params['value'];
}
@@ -0,0 +1,5 @@
<?php
function default_script_modifier($input, $text = null)
{
return $text . $input;
}
@@ -0,0 +1,2 @@
<?php
echo 'test include php';
@@ -0,0 +1 @@
{scriptblock}foo bar{/scriptblock}
@@ -0,0 +1 @@
{scriptcompilerfunction value='foo bar'}
@@ -0,0 +1 @@
{compilerobject value='foo bar'}
@@ -0,0 +1 @@
{localfunction value='foo bar'}
@@ -0,0 +1 @@
{scriptfunction value='foo bar'}
@@ -0,0 +1 @@
{scriptfunctionnotcachable value=$foo}
@@ -0,0 +1 @@
{$foo|mydefaultmodifier}
@@ -0,0 +1 @@
{$foo|scriptmodifier:'scriptmodifier default '}
@@ -0,0 +1 @@
{$foo|mydefaultstaticmodifier nocache}
@@ -0,0 +1 @@
{plugin1}
@@ -0,0 +1 @@
{plugin2}
@@ -0,0 +1 @@
{plugin3}
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1,123 @@
<?php
/**
* Smarty PHPunit tests of filter
*
* @package PHPunit
* @author Rodney Rehm
*/
/**
* class for filter tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class MuteExpectedErrorsTest extends PHPUnit_Smarty
{
protected $_errors = array();
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
}
public function testInit()
{
$this->cleanDirs();
}
public function error_handler($errno, $errstr, $errfile, $errline, $errcontext = array())
{
$this->_errors[] = $errfile . ' line ' . $errline;
}
public function testMuted()
{
set_error_handler(array($this, 'error_handler'));
Smarty::muteExpectedErrors();
$this->smarty->clearCache('default.tpl');
$this->smarty->clearCompiledTemplate('default.tpl');
$this->smarty->fetch('default.tpl');
$this->assertEquals($this->_errors, array());
@filemtime('ckxladanwijicajscaslyxck');
$error = array(__FILE__ . ' line ' . (__LINE__ - 1));
$this->assertEquals($this->_errors, $error);
Smarty::unmuteExpectedErrors();
restore_error_handler();
}
/**
*
* @rrunInSeparateProcess
*
*/
public function testUnmuted()
{
set_error_handler(array($this, 'error_handler'));
$this->smarty->clearCache('default.tpl');
$this->smarty->clearCompiledTemplate('default.tpl');
$this->smarty->fetch('default.tpl');
$this->assertEquals(Smarty::$_IS_WINDOWS ? 2 : 2, count($this->_errors));
@filemtime('ckxladanwijicajscaslyxck');
$this->assertEquals(Smarty::$_IS_WINDOWS ? 3 : 3, count($this->_errors));
restore_error_handler();
}
/**
*
* @runInSeparateProcess
* @preserveGlobalState disabled
*
*/
public function testMutedCaching()
{
set_error_handler(array($this, 'error_handler'));
Smarty::muteExpectedErrors();
$this->smarty->caching = true;
$this->smarty->clearCache('default.tpl');
$this->smarty->clearCompiledTemplate('default.tpl');
$this->smarty->fetch('default.tpl');
$this->assertEquals($this->_errors, array());
@filemtime('ckxladanwijicajscaslyxck');
$error = array(__FILE__ . ' line ' . (__LINE__ - 1));
$this->assertEquals($error, $this->_errors);
Smarty::unmuteExpectedErrors();
restore_error_handler();
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*
*/
public function testUnmutedCaching()
{
set_error_handler(array($this, 'error_handler'));
$this->smarty->caching = true;
$this->smarty->clearCache('default.tpl');
$this->smarty->clearCompiledTemplate('default.tpl');
$this->smarty->fetch('default.tpl');
$this->assertEquals(Smarty::$_IS_WINDOWS ? 2 : 2, count($this->_errors));
@filemtime('ckxladanwijicajscaslyxck');
$error = array(__FILE__ . ' line ' . (__LINE__ - 1));
$this->assertEquals(Smarty::$_IS_WINDOWS ? 3 : 3, count($this->_errors));
restore_error_handler();
}
}
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1 @@
{$foo|default:""} /* should compile something with @silence error suppression */
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*
@@ -0,0 +1,7 @@
<?php
function smarty_function_chain1($params, $tpl)
{
$tpl->smarty->loadPlugin('smarty_function_chain2');
return smarty_function_chain2($params, $tpl);
}
@@ -0,0 +1,7 @@
<?php
function smarty_function_chain2($params, $tpl)
{
$tpl->smarty->loadPlugin('smarty_function_chain3');
return smarty_function_chain3($params, $tpl);
}
@@ -0,0 +1,5 @@
<?php
function smarty_function_chain3($params, $tpl)
{
return 'from chain3';
}
@@ -0,0 +1,33 @@
<?php
/**
* Smarty PHPunit tests chained loading of dependend pluglind
*
* @package PHPunit
* @author Rodney Rehm
*/
/**
* class for modifier tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class PluginChainedLoadTest extends PHPUnit_Smarty
{
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
}
public function testInit()
{
$this->cleanDirs();
}
public function testPluginChainedLoad()
{
$this->smarty->addPluginsDir(dirname(__FILE__) . "/PHPunitplugins/");
$this->assertContains('from chain3', $this->smarty->fetch('test_plugin_chained_load.tpl'));
}
}
@@ -0,0 +1,29 @@
<?php
/**
* Smarty PHPunit tests of shared plugin functions
*
* @package PHPunit
* @author Rodney Rehm
*/
/**
* class for function tests
*/
class SharedFunctionsTest extends PHPUnit_Smarty
{
public function setUp()
{
$this->setUpSmarty(dirname(__FILE__));
}
/**
* test smarty_function_escape_special_chars()
*/
public function testEscapeSpecialChars()
{
require_once SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php';
$this->assertEquals('hello&lt;world &copy;', smarty_function_escape_special_chars('hello<world &copy;'));
$this->assertEquals('ö€', smarty_function_escape_special_chars('ö€'));
}
}
@@ -0,0 +1,2 @@
# Ignore anything in here, but keep this directory
*

Some files were not shown because too many files have changed in this diff Show More