5107 Commits

Author SHA1 Message Date
colemanw 1f9eef51c7 Fix double semicolon in getRightDelimiter method (#1202) 2026-07-04 13:37:14 +02:00
Simon Wisselink 94a27cbbc7 Merge branch 'release/5.8.4' v5.8.4 2026-06-29 12:46:32 +02:00
Simon Wisselink badc5ef3a0 version bump 2026-06-29 12:46:30 +02:00
Simon Wisselink 2ae0f9a65f Fix TypeError for non-array static_classes in Security policy (#1198) 2026-06-29 12:45:58 +02:00
Simon Wisselink b668745acf drop unused version attribute from docker-compose.yml 2026-06-29 12:40:41 +02:00
Simon Wisselink 3c9f77a2e0 Security: validate nested stream wrapper in stream: resource (CWE-22) (#1195)
The built-in stream: resource type let a template bypass Security stream
restrictions. BasePlugin::load() matches the 'stream' sysplugin before the
stream_get_wrappers()/isTrustedStream() check, so a resource such as
stream:php://filter/read=convert.base64-encode/resource=/path was opened by
StreamPlugin::getContent() via fopen() on the nested php:// wrapper without
ever validating it. This bypassed Security::$streams (including
Security::$streams = null) and allowed reading arbitrary local files.

Parse the wrapper scheme from the resolved path in StreamPlugin::getContent()
and validate it with Security::isTrustedStream() before fopen(), giving the
stream: resource the same check the direct wrapper path already receives.

Adds regression tests covering the disabled-streams bypass, the
not-on-allowlist case, and a positive test that an explicitly allowed wrapper
still works.
2026-06-29 11:47:32 +02:00
Simon Wisselink 042dff64a9 Merge branch 'release/5.8.3' v5.8.3 2026-06-29 00:15:09 +02:00
Simon Wisselink 1830aa7a12 version bump 2026-06-29 00:15:07 +02:00
Simon Wisselink b83ffdd2d6 requirements for building docs, switched test-runner from mutagen to basic docker compose 2026-06-29 00:14:40 +02:00
Simon Wisselink ac27e1e5b6 fixed a regression from #1189 where a child template's block override no longer applied to a template {include}d by the parent
Fixes #1192
2026-06-29 00:12:45 +02:00
Simon Wisselink 17fae11a38 update documentation for building and previewing with mkdocs, fix unit tests for windows 2026-06-24 10:33:14 +02:00
Simon Wisselink 06594a1149 Merge branch 'release/5.8.2' v5.8.2 2026-06-24 10:04:41 +02:00
Simon Wisselink 75a738ad44 version bump 2026-06-24 10:04:39 +02:00
Simon Wisselink 11e69eca68 Security: escape value-context attributes in html_image/html_select_date (CWE-79)
{html_image} already escaped alt and pass-through attributes, but emitted
file, path_prefix, href/link, width and height raw, letting an untrusted
value break out of the generated tag. Escape these at output time; the
unescaped values are still used for getimagesize()/DPI math. Escaping uses
htmlspecialchars with double_encode=false, so existing entities and values
like "100%" are preserved (no BC break for legitimate values).

{html_select_date} treated day_size/month_size/year_size as strings and
emitted them raw into size="…"; cast them to int to match
{html_select_time} and close the breakout.

The remaining flagged parameters (mailto extra; html_table *_attr/
trailpad/caption/loop; html_radios/html_checkboxes separator;
html_select_* *_extra/field_separator and the unrecognised-attribute
pass-through) intentionally emit raw markup as documented, so escaping
them would break backwards compatibility. Add a security note to those
docs pages instead, telling authors to escape untrusted values themselves.

Adds tests for html_image escaping (incl. benign-value/no-double-encode
checks) and the html_select_date size cast.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 00:48:01 +02:00
Simon Wisselink 31e06fc087 Security: stop {fetch} from following redirects past trusted_uri (CWE-918)
{fetch} validates the requested URL with Security::isTrustedUri(), but
for non-http schemes (e.g. https) it reads the resource via
file_get_contents(), which follows redirects by default. An open redirect
on an otherwise trusted host could therefore be used to reach a
non-trusted, internal target, bypassing the trusted_uri policy (SSRF).

When a security policy is active, pass a stream context that disables
redirect-following (follow_location => 0, max_redirects => 1) to
file_get_contents() for remote resources. Behavior is unchanged when no
security policy is set, since there is no trusted_uri to bypass.

Adds a regression test using a custom stream wrapper that captures the
context {fetch} passes to file_get_contents, plus a backwards-compat test
for the no-security-policy case.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 00:21:12 +02:00
Simon Wisselink 99c048ce7a Security: prevent symlink path traversal out of secure_dir (CWE-22)
Security::_checkDir() validated file access using Smarty::_realpath(),
which only normalizes paths as strings and never follows symlinks. A
symlink placed inside a trusted secure_dir/template directory therefore
passed the trust check while file_get_contents() followed it to an
arbitrary file (e.g. /etc/passwd), affecting {include} and {fetch} of
local files.

Resolve the requested file with native realpath() and re-validate the
canonical, symlink-free path against the trusted directories. The trusted
directories are canonicalized the same way so legitimate symlinked
deployment paths (e.g. a Capistrano "current" release symlink, or macOS'
/var -> /private/var) keep working. Falls back to string normalization
only when the file does not yet exist on disk.

Adds regression tests covering both the rejected escape and an allowed
in-sandbox symlink, and documents the changelog convention in AGENTS.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 00:15:19 +02:00
Antonio Norman 1c9b2ce1d3 fix for Error: Attempt to assign property "step" on null closes issue #1036 (#1071)
* fix for Error: Attempt to assign property "step" on null in extended templates + added tests closes issue #1036
2026-06-23 23:50:43 +02:00
Simon Wisselink 29a77ded2f Merge branch 'release/5.8.1' v5.8.1 2026-06-23 23:04:23 +02:00
Simon Wisselink 6d06c5e61f version bump 2026-06-23 23:04:21 +02:00
Simon Wisselink ba745f5b91 Added changelog for the fix for issue #1189 2026-06-23 23:03:58 +02:00
Simon Wisselink 0775fa84d1 Agents instructions 2026-06-23 22:52:51 +02:00
Simon Wisselink 56ab75df2c Bugfix/issue 1189 inheritance state leak (#1190)
* Reproduce block override leakage in template inheritance
* Fixes #1189
2026-06-23 22:50:39 +02:00
Masatoshi Ogiwara 383e20e6b4 fix: return type (#1180) 2026-05-16 00:34:29 +02:00
Simon Wisselink c139883770 update todos 2026-05-03 22:19:59 +02:00
Simon Wisselink 6e648ed809 Remove incomplete test cases for usesCompiler across multiple test files 2026-05-03 22:19:50 +02:00
Simon Wisselink 3577fc7091 Re-activate unit tests for user literals. 2026-04-13 22:31:06 +02:00
Simon Wisselink ff2ef3b0cb Redirect test temp dirs to system temp directory
* Redirect test temp dirs to system temp directory. Fixes #1178

Move all test-generated output (compiled templates, cache files, and
temporary template sources) from per-test-directory folders inside the
working tree to a parallel structure under sys_get_temp_dir()/smarty-tests/.

This removes 215 boilerplate .gitignore files from the repo and ensures
running the test suite leaves zero uncommitted files in the working tree.

All 2296 tests continue to pass with identical behavior.

* Isolate each test class in a unique temp directory

getTempDir() now appends a per-class uniqid token to the temp path, so
concurrent or sequential test runs never share compiled/cached output.
The token is generated lazily on first use and reset in
tearDownAfterClass(), giving every test class a fresh isolated directory.

As a result, the Bootstrap.php pre-run cleanup of smarty-tests/ is no
longer needed for correctness (stale paths are unreachable) and was
harmful to concurrent runs, so it has been removed.

* Remove individualFolders dead code and spurious assertTrue from cleanDirs()

- Remove the never-active individualFolders code path from setUpSmarty()
  (the constant was always true, making the branch unreachable)
- Remove define('individualFolders') from Config.php and the constructor
- Remove $this->assertTrue(true) from cleanDirs(): it existed solely to
  make testInit() count as a passing test; now that cleanDirs() is called
  from setUpSmarty() and from test methods directly, the assertion was
  spuriously inflating assertion counts
- Add tests/**/templates_c/, cache/, templates_tmp/ to .gitignore to
  prevent stale test output from appearing as untracked files

* Clean up each test class's unique temp dir in tearDownAfterClass()

Add a private static removeDir() helper and call it from
tearDownAfterClass() to recursively delete the per-class unique temp
directory after each test class finishes. Cleanup failures are silently
ignored (@ suppression) so they never cause test failures.

Set KEEP_SMARTY_TEST_ARTIFACTS=1 in the environment to skip cleanup and
keep the artifacts on disk for debugging.

* cleanup of unused template files, non-shared files stored in __shared folder, no longer required calls to add template folders et cetera

* fixed the unit tests

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* remove useless resetting of static properties in tearDownAfterClass

* changed an incorrect doc and formatted some code.

* add changelog

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-13 21:36:33 +02:00
Simon Wisselink aa2dcd82cf Added AGENTS.md for improved vibe coding experience 2026-04-10 22:57:32 +02:00
Simon Wisselink 78d259d3b9 Merge branch 'release/5.8.0' v5.8.0 2026-02-15 15:27:15 +01:00
Simon Wisselink 4ed569c674 version bump 2026-02-15 15:27:13 +01:00
Simon Wisselink a46478d0cb changelogs 2026-02-15 15:26:43 +01:00
Simon Wisselink 5487e31c4b Add support for Backed Enums (#1171)
* Add support for Backed Enums
Fixes #1012

Also added docs (and docs for matches operator)
2026-02-15 15:23:55 +01:00
Simon Wisselink 12ce28e265 Regex matches operator (#1169)
* Regex matches operator support
2026-02-15 14:44:48 +01:00
Simon Wisselink 139797a165 Support for Laravel Collections style object chaining (#1168)
* Support for Laravel Collections style object chaining for objects return from function calls implemented as modifiers
Fixes #1151

* explain publishing docs
2026-02-11 00:02:52 +01:00
hirosan 6709d000cd Fix static analysis warnings for isDot() and remove deprecated APC support (#1164)
* Fix static analysis warnings for isDot()
* Remove deprecated APC support
* Remove redundant isDot() check and fix static analysis warnings
2026-01-08 11:21:57 +01:00
Simon Wisselink aa6edc3c0b Document missing inline implementation. Fixed #1152 (#1156) 2025-12-21 22:58:11 +01:00
Simon Wisselink 73da7e90f3 Merge branch 'release/5.7.0' v5.7.0 2025-11-19 22:36:38 +01:00
Simon Wisselink c0d7a36124 version bump 2025-11-19 22:36:36 +01:00
Simon Wisselink 8cc9a75964 Php8.5 support (#1138)
* PHP 8.5 support (using RC docker image for php 8.5 unit tests)
2025-11-19 22:33:49 +01:00
Wim Wisselink 21d7fbb67e Non-canonical cast (boolean) fix (#1145) 2025-10-17 14:45:38 +02:00
Simon Wisselink 1fc41e385d Merge branch 'release/5.6.0' v5.6.0 2025-10-03 23:22:25 +02:00
Simon Wisselink fe325daec0 version bump 2025-10-03 23:22:23 +02:00
Simon Wisselink 3f0f308a7b added changelog 2025-10-03 23:19:22 +02:00
pharixces b390e50974 Add support for shorttags in functions (#1142)
* Add support for shorttags in functions

Co-authored-by: Anne Zijlstra <a.zijlstra@iwink.nl>
Co-authored-by: Simon Wisselink <s.wisselink@iwink.nl>
2025-10-03 23:17:55 +02:00
Simon Wisselink 0e46ae3add Merge branch 'release/5.5.2' v5.5.2 2025-08-26 10:38:06 +02:00
Simon Wisselink 4d793ee04c version bump 2025-08-26 10:38:05 +02:00
Simon Wisselink 7677b84058 Fixed escaping of array/object keys in debug_print_var 2025-08-26 10:32:02 +02:00
Simon Wisselink e7457d78cb Add iWink and Temma logos 2025-05-27 22:39:34 +02:00
Simon Wisselink cbcd66e1de Merge branch 'release/5.5.1' v5.5.1 2025-05-19 11:29:42 +02:00
Simon Wisselink 46cd224efb version bump 2025-05-19 11:29:40 +02:00