Skip to content

\Stringable when strict_variables: true silently becomes string in array key. When strict_variables: false exception thrown #4804

Description

@zukk

Try following template (test.twig):

{{ array[object] }}

For context:

$object = new class implements \Stringable {
    public function __toString()
    {
        return 'string';
    }
};
$this->render('test.twig', ['array' => ['string' => 'value'], 'object' => $object]);

Rendered template, strict_variables: false

(($_v0 = ($context["array"] ?? null)) && is_array($_v0) || $_v0 instanceof ArrayAccess ?
        ($_v0[($context["object"] ?? null)] ?? null) : null)

No casting key into string here. Exception: Cannot access offset of type Stringable@anonymous on array.

Rendered template, strict_variables: true

 CoreExtension::getAttribute(
        $this->env,
        $this->source,
        (isset($context["array"]) || array_key_exists("array", $context) ? $context["array"] : (function () {
            throw new RuntimeError('Variable "array" does not exist.', 1, $this->source);
        })()),
        (isset($context["object"]) || array_key_exists("object", $context) ? $context["object"] : (function () {
            throw new RuntimeError('Variable "object" does not exist.', 1, $this->source);
        })()),
        [],
        "array",
        false,
        false,
        false,
        1
    )

And inside CoreExtension::getAttribute:

if (match (true) {
    \is_array($object) => \array_key_exists($arrayItem = (string) $arrayItem, $object),
    $object instanceof \ArrayAccess => $object->offsetExists($arrayItem),
    default => false,
}) {

    ....

    return $object[$arrayItem];
}

Array key casts into string on

\is_array($object) => \array_key_exists($arrayItem = (string) $arrayItem, $object),

no exception thrown.

Expected behaviour: No cast $arrayItem into string in CoreExtension::getAttribute.
If render throws exception in strict_variables: false mode, it must be thrown in strict_variables: true too.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions