Commit Graph

244 Commits

Author SHA1 Message Date
Fabien Potencier b91dbaa1ba Fix merge conflict resolution 2026-05-21 14:11:53 +02:00
Fabien Potencier 8dd0383353 Merge branch '3.x' into 4.x
* 3.x: (23 commits)
  Bump version
  Prepare the 3.26.0 release
  Update CHANGELOG
  Document that the sandbox doesn't protect against resource exhaustion
  Document template_from_string caveats when used in a sandboxed env
  Pre-escape HTML input on the `spaceless` filter
  Add docs on Markup about the goal of this class in the context of a sandbox
  Fix sandbox bypass in the "column" filter
  Fix sandbox `__toString` bypasses
  Validate macro name in MacroReferenceExpression constructor
  Fix sandbox bypass: PHP code injection via _self / import macro reference
  Fix deprecations in tests
  Fix sandbox bypass in the `{% sandbox %}` tag when including a preloaded template
  Encode single quotes as \x27 in Compiler::string()
  Fix sandbox bypass: PHP code injection via {% use %} template name
  Fix unbounded memoisation of `IntlDateFormatter` / `NumberFormatter`
  Fix deprecation
  [Profiler] Escape template and profile names in HtmlDumper
  Bump version
  Fix sandbox bypass: propagate sandbox state to checkArrow for source-policy sandboxing
  ...

# Conflicts:
#	CHANGELOG
#	doc/filters/spaceless.rst
#	extra/cssinliner-extra/CssInlinerExtension.php
#	extra/inky-extra/InkyExtension.php
#	extra/markdown-extra/MarkdownExtension.php
#	src/Environment.php
#	src/ExpressionParser/Infix/DotExpressionParser.php
#	src/Extension/CoreExtension.php
#	src/Node/Expression/FilterExpression.php
#	src/Node/Expression/FunctionExpression.php
#	src/Node/Expression/TestExpression.php
#	src/Node/ModuleNode.php
#	src/NodeVisitor/SandboxNodeVisitor.php
#	src/Resources/core.php
#	src/TokenParser/SandboxTokenParser.php
#	tests/Extension/SandboxTest.php
2026-05-21 13:58:45 +02:00
Fabien Potencier ea3f7a2844 Validate macro name in MacroReferenceExpression constructor
The name passed to MacroReferenceExpression is emitted as raw PHP in
compile() via "->{$name}(...)". Callers were expected to validate
the name, but a missing check led to CVE-2026-XXXXX (PHP code injection
via _self / import macro reference): defense-in-depth, validate the
name in the constructor so the class is safe by construction.
2026-05-19 23:42:31 +02:00
Alexandre Daubois e9ff55f691 Fix sandbox bypass: PHP code injection via {% use %} template name 2026-05-19 22:50:45 +02:00
Fabien Potencier 0c515667d2 Merge remote-tracking branch 'origin/3.x' into 4.x
* origin/3.x:
  Add a `needs_is_sandboxed` option for filters, functions, and tests
  Bump version
  Make embeds deterministic
  [Doc] Document loose comparison in the `in` operator
  [Doc] Reword whitespace control note about first-newline removal
  Stop publishing extra package minor versions with no changes
  Lazy load EscaperRuntime in EscaperExtension
  Fix typo
  Replace parent-child analogy in `doc/tags/extends.rst`
  doc: Add missing toctree entries and fix ordering
  Fix CHANGELOG
  Bump version
  Prepare the 3.24.0 release
2026-05-17 08:18:04 +01:00
Fabien Potencier 5462817da0 Add a needs_is_sandboxed option for filters, functions, and tests 2026-05-16 18:52:17 +01:00
Fabien Potencier 9a198ce169 Fix tests 2026-02-09 12:32:40 +01:00
Fabien Potencier 463ef4018d Merge branch '3.x' into 4.x
* 3.x:
  Update CHANGELOG
  Add `html_attr_relaxed` escaping strategy
  re-add mixed return type
  Support short-circuiting in null-safe operator chains
  Add support for renaming variables in object destructuring
  Update .gitattributes to remove splitsh.json
  Fix intro for operator precedence table ?
2026-02-09 12:29:34 +01:00
Fabien Potencier 751a187f07 feature #4748 Support short-circuiting in null-safe operator chains (HypeMC)
This PR was merged into the 3.x branch.

Discussion
----------

Support short-circuiting in null-safe operator chains

This PR adds short-circuiting for null-safe operator chains, using the same rules as PHP, `PropertyAccess`, and the `ExpressionLanguage`.

Previously, only the immediate null-safe access was guarded. With this change, as soon as a `null` is encountered at a null-safe access, the rest of the chain is skipped.

My approach was to move the null check outside of the `getAttribute()` calls so the expression can immediately return `null`, eg:

```twig
foo?.bar.baz
```

Before:

```php
yield $this->env
    ->getRuntime('Twig\Runtime\EscaperRuntime')
    ->escape(
        CoreExtension::getAttribute(
            $this->env,
            $this->source,
            (
                null === (
                    $_v0 = (
                        isset($context['foo']) || array_key_exists('foo', $context)
                            ? $context['foo']
                            : throw new RuntimeError('Variable "foo" does not exist.', 3, $this->source)
                    )
                )
                    ? null
                    : CoreExtension::getAttribute(
                        $this->env,
                        $this->source,
                        $_v0,
                        'bar',
                        [],
                        'any',
                        false,
                        false,
                        false,
                        3
                    )
            ),
            'baz',
            [],
            'any',
            false,
            false,
            false,
            3
        ),
        'html',
        null,
        true
    );
```

Now:

```php
yield $this->env
    ->getRuntime('Twig\Runtime\EscaperRuntime')
    ->escape(
        (
            null === (
                $_v0 = (
                    isset($context['foo']) || array_key_exists('foo', $context)
                        ? $context['foo']
                        : throw new RuntimeError('Variable "foo" does not exist.', 3, $this->source)
                )
            )
                ? null
                : CoreExtension::getAttribute(
                    $this->env,
                    $this->source,
                    CoreExtension::getAttribute(
                        $this->env,
                        $this->source,
                        $_v0,
                        'bar',
                        [],
                        'any',
                        false,
                        false,
                        false,
                        3
                    ),
                    'baz',
                    [],
                    'any',
                    false,
                    false,
                    false,
                    3
                )
        ),
        'html',
        null,
        true
    );
```

Commits
-------

d56e8e2dba Support short-circuiting in null-safe operator chains
2026-02-08 19:02:03 +01:00
Fabien Potencier 2fba06cba9 Fix tests 2026-02-07 09:18:21 +01:00
Fabien Potencier cdce18d02a Fix CS 2026-02-07 09:16:06 +01:00
Fabien Potencier 0facb551b0 Merge branch '3.x' into 4.x
* 3.x:
  Fix CS
2026-02-07 09:12:05 +01:00
Fabien Potencier 861215c507 Fix CS 2026-02-07 09:07:38 +01:00
HypeMC d56e8e2dba Support short-circuiting in null-safe operator chains 2026-02-06 22:36:57 +01:00
Fabien Potencier e968cf6591 Merge branch '3.x' into 4.x
* 3.x:
  Tweak null-safe operator implementation
  Add null-safe operator
  Update u.rst to clarify truncate method's third argument behavior
2026-01-17 15:17:13 +01:00
Felds Liscia 263c04fd1f Add null-safe operator 2026-01-17 14:57:47 +01:00
Fabien Potencier 8391928896 Fix deprecations 2026-01-12 09:52:14 +01:00
Fabien Potencier b03de9de05 Merge branch '3.x' into 4.x
* 3.x:
  Update CHANGELOG
  Fix accessing arrays with stringable objects as key
  Update inky_to_html.rst: Updating link
  Update replace.rst
  [Doc] Tweaks in the escaping article
  Compile 'index' with repr (not string) in EmbedNode
  Introduce registerUndefinedTestCallback
  Fix intl test
  Bump minimum Commonmark requirement
  Support two words test guard
  Bump version
  Improve documentation examples for `enum` and `enum_cases`
  Avoid errors when failing to guess the template info for an error
  Add note to format_datetime explaining how to install required extensions
  Fix compatibility layer
2025-10-29 11:55:46 -04:00
Simon André e4d7915702 Compile 'index' with repr (not string) in EmbedNode
Before this fix, the generated Template code had quotes around the
index (integer) parameter value.
2025-09-25 08:28:51 +02:00
Nicolas Grekas c649c1658b Merge branch '3.x' into 4.x
* 3.x:
  CS fixes
  Enable Fabbot as a GHA
2025-07-29 10:27:55 +02:00
Nicolas Grekas 85a4817128 CS fixes 2025-07-29 10:07:07 +02:00
Fabien Potencier 4a3f02f0b8 Merge branch '3.x' into 4.x
* 3.x:
  Move some tests
2025-02-26 22:11:29 +01:00
Fabien Potencier 56204e951a Move some tests 2025-02-26 22:10:10 +01:00
Fabien Potencier c1fdaf1290 Merge branch '3.x' into 4.x
* 3.x:
  Remove $templateName from Template::loadTemplate()
2025-02-22 18:27:45 +01:00
Fabien Potencier d7702840da Remove $templateName from Template::loadTemplate() 2025-02-21 23:48:41 +01:00
Fabien Potencier 4d9388dbe0 Merge branch '3.x' into 4.x
* 3.x:
  Fix testing and expression when it evaluates to an instance of Markup
  Simplify Error implementation
  Make the defined test implementation more generic
  fix typo
  fix the rst syntax of the operator precedence table
2025-02-21 18:55:21 +01:00
Fabien Potencier 2d84abfd08 Make the defined test implementation more generic 2025-02-21 08:36:21 +01:00
Fabien Potencier 54dea53382 Make the raw filter "sticky" 2025-02-13 09:30:12 +01:00
Fabien Potencier dd69b12bfe Merge branch '3.x' into 4.x
* 3.x:
  [SECURITY] Fix a security issue where escaping was missing when using ??
  Fix typo for html_cva code example
2025-01-29 07:59:13 +01:00
Fabien Potencier 445f74cfe0 [SECURITY] Fix a security issue where escaping was missing when using ?? 2025-01-29 07:52:07 +01:00
Fabien Potencier fc04fa6629 Merge branch '3.x' into 4.x
* 3.x:
  Add ForElseNode
2025-01-24 15:32:30 +01:00
Fabien Potencier 609767522a Add ForElseNode 2025-01-24 15:25:30 +01:00
Fabien Potencier 28246c5d4e Merge branch '3.x' into 4.x
* 3.x:
  Fixing minor typo in Update inline_css.rst
  Ignore static properties when using the dot operator
  Fix CS
  Fix constant() behavior when used with ??
  Finish the work
  fix indentation
  Apply suggestions from code review
  typo
  fix merge
  docs and changelog
  typehint instead of checkArrow
  checkArrow, typehints
  invoke filter
2025-01-24 11:32:17 +01:00
Fabien Potencier 76062c8d51 Fix CS 2025-01-19 16:54:05 +01:00
Fabien Potencier 9bcf837835 Fix test 2025-01-10 08:42:15 +01:00
Fabien Potencier ef7ade8ee3 Merge branch '3.x' into 4.x
* 3.x: (30 commits)
  Make {} optional for the types tag
  Remove the note about types mapping argument
  Add a note on the types locality
  Fix CS
  Fix typos in the docs
  Use spl_object_id() instead of spl_object_hash()
  Add `LastModifiedExtensionInterface` and implementation in `AbstractExtension` to track modification of runtime classes
  Bump version
  Optimize NameExpression compilation
  Fix typo in enum twig doc functions
  Remove dead method in ModuleNode
  Bump version
  Prepare the 3.18.0 release
  Add support for `Twig\Markup`
  Fix unary operator precedence change
  Replace Twigfiddle by the new Twig playground
  Fix MacroNode $name argument can be overridden
  Ignore exceptions from undefined handlers when using the guard tag
  [Doc] Update the docs about attribute() function
  Fix doc
  ...
2025-01-10 08:41:31 +01:00
Fabien Potencier efd12ef0cc Optimize NameExpression compilation 2025-01-02 12:32:36 +01:00
Fabien Potencier 80020a66a4 Fix CS 2024-11-30 10:08:56 +01:00
Fabien Potencier 82cde4edcb Fix CS 2024-11-30 09:45:07 +01:00
Fabien Potencier cf105b566a Merge branch '3.x' into 4.x
* 3.x:
  Fix CS
2024-11-30 09:43:08 +01:00
Fabien Potencier 14fc89ebea Fix CS 2024-11-30 09:42:13 +01:00
Fabien Potencier fd833197d3 Remove deprecation, update code 2024-11-29 19:28:34 +01:00
Fabien Potencier 81c7e8f86f Merge branch '3.x' into 4.x
* 3.x:
  Enforce AbstractBinary for all binary operators
  Fix CHANGELOG
  Bump version
  Prepare the 3.16.0 release
2024-11-29 19:26:31 +01:00
Fabien Potencier 4f8ba93600 Enforce AbstractBinary for all binary operators 2024-11-29 16:51:09 +01:00
Fabien Potencier e69c1abe6c Merge branch '3.x' into 4.x
* 3.x:
  Simplify EscaperNodeVisitor code
  Fix having macro variables starting with an underscore
  Fix CS
  Fix EscapeNodeVisitor::isSafeFor()
  Simplify code
2024-11-28 14:21:03 +01:00
Fabien Potencier bdb0f3c042 Fix having macro variables starting with an underscore 2024-11-26 16:59:45 +01:00
Fabien Potencier 429b13c9b0 Merge branch '3.x' into 4.x
* 3.x:
  Remove obsolete code
  Update CHANGELOG
  Sandbox ArrayAccess and do sandbox checks before isset() checks
  Fix sandbox handling for __toString()
  Fix mistake in docs for `keys` filter
  Update CHANGELOG
  [String] Add SpanishInflector support for singular and plural
  Add `find` to `Filters` docs
  Remove duplicate test case
  Revert "minor #4411 Add return type to getDebugInfo (ruudk)"
  Add `$this` return type to Template::unwrap
  Add link to TwigQI in docs "You might also be interested in" section
  Add return type to compiled macro
2024-11-06 21:52:30 +01:00
Fabien Potencier 494f010d29 Revert "minor #4411 Add return type to getDebugInfo (ruudk)"
This reverts commit 868b429853, reversing
changes made to b0017ad8c3.
2024-10-25 16:01:04 +02:00
Fabien Potencier 05550cafb1 minor #4410 Add return type to compiled macro (ruudk)
This PR was merged into the 3.x branch.

Discussion
----------

Add return type to compiled macro

This makes it easier for TwigStan to analyze the return type.

Commits
-------

1e7c719e24 Add return type to compiled macro
2024-10-25 08:22:06 +02:00
Fabien Potencier 89fdc7d31d Refactor code 2024-10-25 07:47:55 +02:00