@@ -29,14 +29,25 @@ public function __toString(): string
2929 return $ this ->decoratedExpression ->__toString ();
3030 }
3131
32+ public function enableDefinedTest (): void
33+ {
34+ $ this ->decoratedExpression ->enableDefinedTest ();
35+ }
36+
37+ public function isDefinedTestEnabled (): bool
38+ {
39+ return $ this ->decoratedExpression ->isDefinedTestEnabled ();
40+ }
41+
3242 public function compile (Compiler $ compiler ): void
3343 {
3444 $ env = $ compiler ->getEnvironment ();
45+ $ arrayAccessSandbox = false ;
3546
3647 // optimize array calls
3748 if (
3849 $ this ->getAttribute ('optimizable ' )
39- && !$ this ->getAttribute ( ' is_defined_test ' )
50+ && !$ this ->isDefinedTestEnabled ( )
4051 && $ this ->getAttribute ('type ' ) === Template::ARRAY_CALL
4152 && (!$ env ->isStrictVariables () || $ this ->getAttribute ('ignore_strict_check ' ))
4253 ) {
@@ -45,16 +56,33 @@ public function compile(Compiler $compiler): void
4556 ->raw ('(( ' . $ var . ' = ' )
4657 ->subcompile ($ this ->getNode ('node ' ))
4758 ->raw (') && is_array( ' )
48- ->raw ($ var )
59+ ->raw ($ var );
60+
61+ if (!$ env ->hasExtension (SandboxExtension::class)) {
62+ $ compiler
63+ ->raw (') || ' )
64+ ->raw ($ var )
65+ ->raw (' instanceof ArrayAccess ? ( ' )
66+ ->raw ($ var )
67+ ->raw ('[ ' )
68+ ->subcompile ($ this ->getNode ('attribute ' ))
69+ ->raw ('] ?? null) : null) ' );
70+
71+ return ;
72+ }
73+
74+ $ arrayAccessSandbox = true ;
75+
76+ $ compiler
4977 ->raw (') || ' )
5078 ->raw ($ var )
51- ->raw (' instanceof ArrayAccess ? ( ' )
79+ ->raw (' instanceof ArrayAccess && in_array( ' )
80+ ->raw ($ var .'::class ' )
81+ ->raw (', CoreExtension::ARRAY_LIKE_CLASSES, true) ? ( ' )
5282 ->raw ($ var )
5383 ->raw ('[ ' )
5484 ->subcompile ($ this ->getNode ('attribute ' ))
55- ->raw ('] ?? null) : null) ' );
56-
57- return ;
85+ ->raw ('] ?? null) : ' );
5886 }
5987
6088 $ compiler ->raw (self ::class . '::twigGetAttribute($this->env, $this->source, ' );
@@ -76,11 +104,15 @@ public function compile(Compiler $compiler): void
76104
77105 $ compiler ->raw (', ' )
78106 ->repr ($ this ->getAttribute ('type ' ))
79- ->raw (', ' )->repr ($ this ->getAttribute ( ' is_defined_test ' ))
107+ ->raw (', ' )->repr ($ this ->isDefinedTestEnabled ( ))
80108 ->raw (', ' )->repr ($ this ->getAttribute ('ignore_strict_check ' ))
81109 ->raw (', ' )->repr ($ env ->hasExtension (SandboxExtension::class))
82110 ->raw (', ' )->repr ($ this ->getNode ('node ' )->getTemplateLine ())
83111 ->raw (') ' );
112+
113+ if ($ arrayAccessSandbox ) {
114+ $ compiler ->raw (') ' );
115+ }
84116 }
85117
86118 public function getTemplateLine (): int
@@ -98,9 +130,9 @@ public function hasAttribute(string $name): bool
98130 return $ this ->decoratedExpression ->hasAttribute ($ name );
99131 }
100132
101- public function getAttribute (string $ name )
133+ public function getAttribute ($ name, $ default = null )
102134 {
103- return $ this ->decoratedExpression ->getAttribute ($ name );
135+ return $ this ->decoratedExpression ->getAttribute ($ name, $ default );
104136 }
105137
106138 public function setAttribute (string $ name , $ value ): void
@@ -171,7 +203,7 @@ public static function twigGetAttribute(
171203 mixed $ object ,
172204 mixed $ item ,
173205 array $ arguments = [],
174- $ type = ' any ' ,
206+ $ type = Template:: ANY_CALL ,
175207 $ isDefinedTest = false ,
176208 $ ignoreStrictCheck = false ,
177209 $ sandboxed = false ,
0 commit comments