Sandbox `foreachVars` in templates
authorAlexander Ebert <ebert@woltlab.com>
Sun, 8 Aug 2021 09:29:26 +0000 (11:29 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Sun, 8 Aug 2021 09:29:26 +0000 (11:29 +0200)
Nesting the same template inside a `foreach` loop that is also accessed inside the nested call will overwrite the values from the outer template due to identical identifiers being used.

The sandbox did not protected `$this->foreachVars` despite being stateful.

See #4431
Fixes #4444

wcfsetup/install/files/lib/system/template/TemplateEngine.class.php

index cbf84b053771d61bd78c460a820b48b50227bc3e..6521671e9c212d347a46ce94141bce2bc05758a5 100755 (executable)
@@ -543,7 +543,10 @@ class TemplateEngine extends SingletonFactory
     public function enableSandbox()
     {
         $index = \count($this->sandboxVars);
-        $this->sandboxVars[$index] = $this->v;
+        $this->sandboxVars[$index] = [
+            'foreachVars' => $this->foreachVars,
+            'v' => $this->v,
+        ];
     }
 
     /**
@@ -555,7 +558,9 @@ class TemplateEngine extends SingletonFactory
             throw new SystemException('TemplateEngine is currently not running in a sandbox.');
         }
 
-        $this->v = \array_pop($this->sandboxVars);
+        $values = \array_pop($this->sandboxVars);
+        $this->foreachVars = $values['foreachVars'];
+        $this->v = $values['v'];
     }
 
     /**