Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .dist/phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ parameters:

# Scan for type resolution, but do not analyze
scanDirectories:
- ../fp-includes/smarty-5.8.4/src
- ../fp-includes/smarty-5.8.5/src
- ../fp-includes/fp-smartyplugins

excludePaths:
analyse:
- ../fp-includes/smarty-5.8.4/**
- ../fp-includes/smarty-5.8.5/**
- ../fp-content/compile/**
- ../fp-content/cache/**
- ../.setup.php (?)
Expand All @@ -70,12 +70,12 @@ parameters:
# Ignore error “does not accept null” only in Smarty core
- message: '#Property .* does not accept null#'
paths:
- ../fp-includes/smarty-5.8.4/src/*.php
- ../fp-includes/smarty-5.8.5/src/*.php

# Ignore error “Call to undefined method” only in Smarty core
- message: '#Call to an undefined method Smarty_Internal_.*::.*#'
paths:
- ../fp-includes/smarty-5.8.4/src/.*\.php
- ../fp-includes/smarty-5.8.5/src/.*\.php

checkMissingVarTagTypehint: false
reportUnmatchedIgnoredErrors: false
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
- Added "Location Migration Mode" ([#897](https://github.com/flatpressblog/flatpress/pull/897))
- The PHP code is now fully compliant with PHPStan Level 5 ([#893](https://github.com/flatpressblog/flatpress/pull/893), [#894](https://github.com/flatpressblog/flatpress/pull/894))
- Template engine Smarty:
- Updated to version 5.8.4 with PHP 8.5 support ([#932](https://github.com/flatpressblog/flatpress/pull/932))
- Updated to version 5.8.5 with PHP 8.5 support ([#932](https://github.com/flatpressblog/flatpress/pull/932))
- New core helpers: ``date_iso8601($timestamp, $offset = null)`` and ``date_id_to_iso8601($id, $offset = null)``. ([#856](https://github.com/flatpressblog/flatpress/pull/856))
- RSS and Atom feeds and the Categories widget use the Smarty block cache instead of having to go through the Smarty compiler every time. ([#864](https://github.com/flatpressblog/flatpress/pull/864))
- If APCu is available, the Smarty cache fragments are stored in the APCu cache instead of on disk. ([#865](https://github.com/flatpressblog/flatpress/pull/865))
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [5.8.5] - 2026-10-04
- Security: prevent attacker-controlled template output from forging a nocache marker that injects raw PHP into the generated cache file when a template is rendered through the `extends:`/inheritance path


## [5.8.4] - 2026-06-29
- Fixed a `TypeError` on PHP 8 when `Security::$static_classes` was set to a non-array value (e.g. the string `'none'`) to disable static class access; any non-array value now cleanly denies access. Use `Security::$static_classes = null` to disable access to all static classes.
- Security: the built-in `stream:` resource type now validates the nested stream wrapper against the security policy, so a template such as `stream:php://filter/...` can no longer bypass `Security::$streams` (including `Security::$streams = null`) to read local files (CWE-22)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ Smarty currently supports the latest minor version of Smarty 4 and Smarty 5.

## 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** do not file an Issue (because that would disclose your findings
publicly.)
If you have discovered a security issue with Smarty, please open a [new security advisory](https://github.com/smarty-php/smarty/security/advisories/new).
Do not disclose your findings publicly and **PLEASE** do not file an Issue (because that would disclose your findings publicly.)

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.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ $COMPOSE_CMD run --rm php73 ./run-tests.sh $@ && \
$COMPOSE_CMD run --rm php74 ./run-tests.sh $@ && \
$COMPOSE_CMD run --rm php80 ./run-tests.sh $@ && \
$COMPOSE_CMD run --rm php81 ./run-tests.sh $@ && \
$COMPOSE_CMD run --rm php82 ./run-tests.sh $@
$COMPOSE_CMD run --rm php83 ./run-tests.sh $@
$COMPOSE_CMD run --rm php84 ./run-tests.sh $@
$COMPOSE_CMD run --rm php82 ./run-tests.sh $@ && \
$COMPOSE_CMD run --rm php83 ./run-tests.sh $@ && \
$COMPOSE_CMD run --rm php84 ./run-tests.sh $@ && \
$COMPOSE_CMD run --rm php85 ./run-tests.sh $@
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@
# - ./run-tests.sh --exclude-group slow

composer update --quiet
#php -r 'echo "\nPHP version " . phpversion() . ". ";'
echo '------------------------------------------------------------'
php -v
echo '------------------------------------------------------------'
php ./vendor/phpunit/phpunit/phpunit $@
echo
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Smarty extends \Smarty\TemplateBase {
/**
* smarty version
*/
const SMARTY_VERSION = '5.8.4';
const SMARTY_VERSION = '5.8.5';

/**
* define caching modes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ public function setLeftDelimiter($left_delimiter)
*/
public function getRightDelimiter()
{
return $this->right_delimiter ?? $this->getSmarty()->getRightDelimiter();;
return $this->right_delimiter ?? $this->getSmarty()->getRightDelimiter();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,22 +300,42 @@ private function removeNoCacheHash(Template $_template, $no_output_filter) {
$php_pattern = '/(<%|%>|<\?php|<\?|\?>|<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>)/';
$content = ob_get_clean();
$hash_array = $this->hashes;
$hash_array[$_template->getCompiled()->nocache_hash] = true;
$hash_array = array_keys($hash_array);
$nocache_hash = '(' . implode('|', $hash_array) . ')';
// Only fold in the top-level nocache hash when it is actually set. A template
// compiled through the inheritance/component path produces a top-level unifunc
// that never restores its nocache_hash, leaving it null here. Using that null as
// an array offset is deprecated (PHP 8.1+), and an empty hash would produce an
// empty alternative "(realhash|)" in the pattern below, letting attacker-controlled
// output forge a nocache marker whose raw content is copied verbatim into the cache
// file (skipping PHP-tag neutralization) and executed as PHP on the next include
// (CWE-94 code injection).
if ((string) $_template->getCompiled()->nocache_hash !== '') {
$hash_array[$_template->getCompiled()->nocache_hash] = true;
}
// Defensive: never allow an empty hash (hence an empty regex alternative).
$hash_array = array_filter(array_keys($hash_array), function ($hash) {
return (string) $hash !== '';
});
$_template->getCached()->setNocacheCode(false);
// get text between non-cached items
$cache_split =
preg_split(
if ($hash_array === []) {
// No known nocache hashes: there is no legitimate nocache content to extract,
// so treat the whole buffer as ordinary output (PHP tags are neutralized below).
$cache_split = [$content];
$cache_parts = [];
} else {
$nocache_hash = '(' . implode('|', $hash_array) . ')';
// get text between non-cached items
$cache_split =
preg_split(
"!/\*%%SmartyNocache:{$nocache_hash}%%\*\/(.+?)/\*/%%SmartyNocache:{$nocache_hash}%%\*/!s",
$content
);
// get non-cached items
preg_match_all(
"!/\*%%SmartyNocache:{$nocache_hash}%%\*\/(.+?)/\*/%%SmartyNocache:{$nocache_hash}%%\*/!s",
$content
$content,
$cache_parts
);
// get non-cached items
preg_match_all(
"!/\*%%SmartyNocache:{$nocache_hash}%%\*\/(.+?)/\*/%%SmartyNocache:{$nocache_hash}%%\*/!s",
$content,
$cache_parts
);
}
$content = '';
// loop over items, stitch back together
foreach ($cache_split as $curr_idx => $curr_split) {
Expand Down
Loading