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
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"roave/security-advisories": "dev-latest",
"smalot/pdfparser": "^2.12.5",
"symfony/process": "^6.4",
"twig/twig": "^3.21.1",
"twig/twig": "^3.30.0",
"wobeto/email-blur": "^1.0.0"
}
}
14 changes: 7 additions & 7 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion composer/composer/autoload_classmap.php

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion composer/composer/autoload_static.php

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions composer/composer/installed.json
Original file line number Diff line number Diff line change
Expand Up @@ -2797,17 +2797,17 @@
},
{
"name": "twig\/twig",
"version": "v3.24.0",
"version_normalized": "3.24.0.0",
"version": "v3.30.0",
"version_normalized": "3.30.0.0",
"source": {
"type": "git",
"url": "https:\/\/github.com\/twigphp\/Twig.git",
"reference": "a6769aefb305efef849dc25c9fd1653358c148f0"
"reference": "8c737079b726af72ff8ef3c595be9f6a810ea1ef"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/twigphp\/Twig\/zipball\/a6769aefb305efef849dc25c9fd1653358c148f0",
"reference": "a6769aefb305efef849dc25c9fd1653358c148f0",
"url": "https:\/\/api.github.com\/repos\/twigphp\/Twig\/zipball\/8c737079b726af72ff8ef3c595be9f6a810ea1ef",
"reference": "8c737079b726af72ff8ef3c595be9f6a810ea1ef",
"shasum": ""
},
"require": {
Expand All @@ -2822,7 +2822,7 @@
"psr\/container": "^1.0|^2.0",
"symfony\/phpunit-bridge": "^5.4.9|^6.4|^7.0"
},
"time": "2026-03-17T21:31:11+00:00",
"time": "2026-09-25T13:20:01+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
Expand Down Expand Up @@ -2864,7 +2864,7 @@
],
"support": {
"issues": "https:\/\/github.com\/twigphp\/Twig\/issues",
"source": "https:\/\/github.com\/twigphp\/Twig\/tree\/v3.24.0"
"source": "https:\/\/github.com\/twigphp\/Twig\/tree\/v3.30.0"
},
"funding": [
{
Expand Down
142 changes: 142 additions & 0 deletions composer/twig/twig/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,145 @@
# 3.30.0 (2026-09-25)

* Fix `split`, `random`, and `shuffle` merging a trailing newline into the last character of a string
* Speed up splitting a string into characters in `split`, `random`, and `shuffle`
* Speed up escaping by fetching the escaper runtime once per template
* Speed up adding extensions to an environment
* Fix the escaping safe analysis retaining every compiled template node for the lifetime of the environment
* Speed up loading a template that the environment has already loaded
* Speed up rendering by compiling a cheaper generator guard into templates
* Speed up compiling filter, function, and test calls
* Fix `IntlExtension` letting the pattern derived from a date formatter prototype override an explicit locale
* Fix `IntlExtension` not honoring the locale of a date formatter prototype configured with no date and time styles
* Speed up macro calls
* Fix `TemplateWrapper::unwrap()` failing when called without arguments, which is now deprecated
* Add `TemplateWrapper::getDefaultEscapeStrategy()` to know the escaping strategy a template was compiled with
* Report a clear error when `random`, `reverse`, `shuffle`, and `split` receive a string that is not valid UTF-8
* Fix the deprecation about omitting parentheses when calling a macro being reported twice for the same call
* Add the macro name to the deprecation about omitting parentheses when calling a macro
* Deprecate cloning a `Twig\Environment` instance
* Fix array access with a `Stringable` key on subclasses of `ArrayObject` and `ArrayIterator`

# 3.29.0 (2026-09-18)

* Fix the PHP warning and cryptic error when a block or a macro rendered on its own uses macros imported in the template body
* Fix `{% cache %}` always missing in the Symfony bundle when `framework.cache.app` uses a natively tag aware adapter
* Fix the sandbox resolving `use` trait templates before checking that the `use` tag is allowed
* Fix `html_attr` dropping `style` declarations whose value is `0`, `0.0` or `'0'`
* Fix the `default` filter fallback emitting an undefined variable warning when it uses the null-safe operator
* Fix the `matches` operator silently treating PCRE execution errors as non-matches; it now throws a `RuntimeError`
* Fix `TemplateWrapper::streamBlock()`, `TemplateWrapper::hasBlock()`, and `TemplateWrapper::getBlockNames()` omitting environment globals
* Fix exceptions from dynamic parent expressions escaping without template context
* Add the `BlockChain` class to compose blocks from multiple templates without using template internals
* Fix `TemplateWrapper::hasBlock()` and `TemplateWrapper::getBlockNames()` losing the `extends` line when the parent template does not exist
* Fix an output buffer leak when a parent block rendered in an expression throws in non-yield mode
* Add the `HtmlExtension::htmlAttrValue()` method to resolve a single HTML attribute value the way the `html_attr` function renders it
* Fix `html_attr` JSON encoding a `Stringable` value in a `data-*` attribute instead of using its string representation
* Add documentation comments to attach metadata to nodes (experimental)
* Fix destructuring patterns containing no variables (empty patterns or sequences with only empty slots) triggering a PHP fatal error instead of a `SyntaxError`
* Fix object and mapping destructuring evaluating the right-hand expression more than once
* Fix sequence destructuring of iterators throwing a `TypeError`
* Fix `MissingExtensionSuggestor` not suggesting the `twig/*-extra` package to install for some `html-extra`, `intl-extra`, and `string-extra` filters and functions
* Add `TempestMarkdown` to use `tempest/markdown` as the `markdown_to_html` converter
* Add the `include_only` function to render a template without giving it access to the current context
* Add the `Twig\Sandbox\SandboxInterface` interface and `Twig\Sandbox\Sandbox` class to render untrusted templates through a dedicated, always-sandboxed environment crafted for it
* Reject `TemplateWrapper` instances created by another `Environment`
* Add the `Twig\Extension\SandboxBridgeExtension` to render sandboxed templates from trusted templates with an explicit output escaping strategy
* Extract the sandbox runtime enforcement into a new internal `Twig\Sandbox\SecurityChecker` class used by compiled templates and `CoreExtension`
* Mark `SandboxExtension` as internal, use `Twig\Sandbox\Sandbox` instead
* Deprecate the `sandboxed` argument of the `include` function, use `Twig\Sandbox\Sandbox` instead
* Deprecate `SandboxExtension::enableSandbox()`, `disableSandbox()`, and `isSandboxedGlobally()`
* Normalize destructuring variable AST nodes as assignment targets
* Fix `IntlExtension` ignoring explicit date/time formats and configured calendars when using a date formatter prototype
* Add a `format_list` filter to `IntlExtension` to format a list of strings using PHP 8.5's `IntlListFormatter`
* Fix array access with a `Stringable` key for `ArrayObject` and `ArrayIterator` while preserving object keys for `SplObjectStorage`
* Fix duplicated macro argument names triggering a PHP fatal error instead of a `SyntaxError`
* Deprecate defining a macro more than once in the same template
* Deprecate `TemplateVariable` and `AssignTemplateVariable`; use `MacroVariable` and `AssignMacroVariable` instead
* Deprecate calling or testing a macro with a name whose case differs from its definition; macro names will be case-sensitive in 4.0
* Deprecate omitting parentheses when calling a macro; it will throw a `SyntaxError` in 4.0
* Deprecate using parentheses when testing a macro with the `defined` test; it will throw a `SyntaxError` in 4.0
* Deprecate calling a macro without a value for an argument that has no default value; the argument will be required in 4.0
* Deprecate passing extra or unknown arguments to a macro that does not declare a variadic argument; it will throw in 4.0
* Add support for declaring an explicit variadic macro argument (`{% macro foo(a, ...rest) %}`)
* Compile macros as closures stored in a per-template registry instead of `macro_`-prefixed PHP methods
* Represent imported macro namespaces with a narrow capability object instead of template instances
* Mark `Twig\Node\MacroNode` as `@final`; it will be final in Twig 4.0
* Deprecate not passing a `MacrosNode` instance as the macros of a `ModuleNode` constructor
* Change `MacroReferenceExpression` to take the bare macro name instead of a `macro_`-prefixed method name
* Deprecate resolving a macro through a `macro_`-prefixed name; pass the bare macro name to `MacroReferenceExpression`

# 3.28.0 (2026-07-03)

* Render backed enums using their backing value in the `html_attr` function
* Fix empty Markup values being treated as truthy in and, or, xor, not, ternary, and elvis expressions
* Fix a PHP 8.5 `chr()` deprecation when decoding an octal string escape sequence larger than `\377` (such as `"\777"`)
* Mark `Twig\Markup` as `@final`; it will be final in Twig 4.0
* Reduce memory usage and speed up the context restoration compiled at the end of `for` loops
* Allow calling a macro with a dynamic name via the dot operator (`macros.(name)(args)`)
* Report the column number in syntax errors and expose it via `Error::getTemplateColumn()`
* Track the source offset of each token and expose it via `Token::getOffset()`
* Fix nested `block()` calls to resolve against the overriding template when a block rendered through `block(name, template)` calls `parent()`
* Deprecate the possibility to use a `block` tag within a capture node (like `set`)
* Deprecate the possibility to use a `block` tag within a capture node (like `set`) in child templates
* Deprecate using a `macro`, `extends`, or `use` tag outside the root of a template
* Stop reporting a skipped test in `IntegrationTestCase` when there is no legacy test to run
* Fix `markdown_to_html` to strip the indentation shared by all lines instead of mangling content that starts with a blank line
* Make the `IntegrationTestCase` and `NodeTestCase` test helpers compatible with PHPUnit 11
* Cast printed expressions to string so values that cannot be converted to a string (arrays, non-`Stringable` objects, ...) report a usable stack trace at the print location
* Make the `include()` function return a `Markup` object so an assigned result is not re-escaped when printed
* Skip the sandbox `__toString` check on arguments whose PHP parameter type cannot implicitly coerce to string
* Document the criteria for marking a callable or tag as always allowed in a sandbox, and the list of built-in tags, filters, and functions that will be always allowed in Twig 4.0
* Add an `always_allowed_in_sandbox` option for filters, functions, and tests, and an `isAlwaysAllowedInSandbox()` method for token parsers, to let authors mark callables and tags that are always allowed in sandbox mode without explicit allow-listing
* Add an allow-list for tests to `Twig\Sandbox\SecurityPolicy`, with the safe built-in tests flagged as always allowed so they keep working without allow-listing

# 3.27.1 (2026-05-30)

* Fix array access with a `Stringable` key to coerce the key to string consistently instead of throwing in the optimized path
* Fix sandbox replacing `IteratorAggregate` arguments (e.g. Symfony's `FormView`) by a plain array

# 3.27.0 (2026-05-27)

* Add a strict mode to `Twig\Sandbox\SecurityPolicy` to opt-in to the 4.0 behavior for the `extends`/`use` tags and the `parent`/`block`/`attribute` functions, which are otherwise still implicitly allowed in a sandbox
* Deprecate the fact that the `parent`, `block`, and `attribute` functions are always allowed in a sandboxed template
* Fix sandbox filter/tag/function allow-list bypass when the sandbox state changed between renders of a cached `Template` instance
* Fix PHP 8.1+ implicit float-to-int deprecation triggered by sandboxed `ArrayAccess` attribute access with a float key
* Restrict allowed classes in `Twig\Profiler\Profile::unserialize()` to prevent arbitrary class instantiation
* Escape root profile name in `HtmlDumper`
* Fix sandbox bypass in deprecated internal wrappers `twig_array_some()`, `twig_array_every()`, and `twig_check_arrow_in_sandbox()` (`src/Resources/core.php`)
* Deprecate the `Twig\Sandbox\SourcePolicyInterface` interface with no replacement
* Fix sandbox bypass in the "column" filter when sandboxing is enabled via `SourcePolicyInterface`
* Fix sandbox `__toString` bypass via `Traversable` arguments to the `join` and `replace` filters (also covers containers that implement both `Stringable` and `Traversable`)
* Fix sandbox `__toString` bypass via the `in` and `not in` operators
* Prevent a stack overflow in `SandboxExtension::ensureToStringAllowed()` when a self-referencing iterable is passed to a sandboxed template
* Add support for any expression as a dynamic mapping key (attribute access, filters, ...)
* Fix sandbox `__toString` policy bypass via dynamic mapping keys

# 3.26.0 (2026-05-20)

* Document that the sandbox doesn't protect against resource exhaustion
* Document `template_from_string` caveats when used in a sandboxed environment
* Add docs on `Markup` about the goal of this class in the context of a sandbox
* Pre-escape HTML input on the `spaceless` filter
* Pre-escape HTML input on `inline_css` and `inky_to_html` filters
* Fix XSS by adjusting `is_safe` annotation on HTML-emitting filters
* [Profiler] Escape template and profile names in `HtmlDumper`
* Fix unbounded memoisation of `IntlDateFormatter` / `NumberFormatter`
* Fix sandbox bypass in the "column" filter
* Fix sandbox bypass in the `{% sandbox %}` tag when including a preloaded template
* Fix sandbox bypass: PHP code injection via `{% use %}` template name
* Fix sandbox bypass: PHP code injection via `_self` / import macro reference
* Fix sandbox bypass in object destructuring assignment
* Fix sandbox bypass: propagate `Source` to `checkArrow` for source-policy sandboxing
* Encode single quotes as `\x27` in `Compiler::string()` as a defense-in-depth measure
* Fix sandbox `__toString` bypasses
* Add `Twig\Node\CoercesChildrenToStringInterface` to let nodes declare which of their child nodes will be string-coerced at runtime so the sandbox wraps them with a `__toString` check

# 3.25.0 (2026-05-17)

* Add a `needs_is_sandboxed` option for filters, functions, and tests
* Use deterministic suffixes for generated embed classes
* Lazy-load `EscaperRuntime` in `EscaperExtension`

# 3.24.0 (2026-03-17)

* Deprecate not implementing the `getOperatorTokens()` method in `ExpressionParserInterface` implementations
Expand Down
12 changes: 10 additions & 2 deletions composer/twig/twig/src/AbstractTwigCallable.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function __construct(string $name, $callable = null, array $options = [])
$this->name = $this->dynamicName = $name;
$this->callable = $callable;
$this->arguments = [];
$this->options = \array_merge(['needs_environment' => \false, 'needs_context' => \false, 'needs_charset' => \false, 'is_variadic' => \false, 'deprecation_info' => null, 'deprecated' => \false, 'deprecating_package' => '', 'alternative' => null], $options);
$this->options = \array_merge(['needs_environment' => \false, 'needs_context' => \false, 'needs_charset' => \false, 'needs_is_sandboxed' => \false, 'is_variadic' => \false, 'always_allowed_in_sandbox' => \false, 'deprecation_info' => null, 'deprecated' => \false, 'deprecating_package' => '', 'alternative' => null], $options);
if ($this->options['deprecation_info'] && !$this->options['deprecation_info'] instanceof DeprecatedCallableInfo) {
throw new \LogicException(\sprintf('The "deprecation_info" option must be an instance of "%s".', DeprecatedCallableInfo::class));
}
Expand Down Expand Up @@ -77,6 +77,14 @@ public function needsContext() : bool
{
return $this->options['needs_context'];
}
public function needsIsSandboxed() : bool
{
return $this->options['needs_is_sandboxed'];
}
public function isAlwaysAllowedInSandbox() : bool
{
return $this->options['always_allowed_in_sandbox'];
}
/**
* @return static
*/
Expand Down Expand Up @@ -138,6 +146,6 @@ public function getAlternative() : ?string
}
public function getMinimalNumberOfRequiredArguments() : int
{
return ($this->options['needs_charset'] ? 1 : 0) + ($this->options['needs_environment'] ? 1 : 0) + ($this->options['needs_context'] ? 1 : 0) + \count($this->arguments);
return ($this->options['needs_charset'] ? 1 : 0) + ($this->options['needs_environment'] ? 1 : 0) + ($this->options['needs_context'] ? 1 : 0) + ($this->options['needs_is_sandboxed'] ? 1 : 0) + \count($this->arguments);
}
}
Loading
Loading