[BUGFIX] Prevent XSS in ViewHelpers
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Classes / ViewHelpers / CaseViewHelper.php
index 28bc487..41a4e4c 100644 (file)
@@ -11,38 +11,73 @@ namespace TYPO3\CMS\Fluid\ViewHelpers;
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
 
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
+use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
+use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
+use TYPO3Fluid\Fluid\ViewHelpers\SwitchViewHelper as OriginalSwitchViewHelper;
+
 /**
  * Case view helper that is only usable within the SwitchViewHelper.
  * @see \TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper
  *
  * @api
  */
-class CaseViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
+class CaseViewHelper extends AbstractViewHelper
+{
+    /**
+     * @var bool
+     */
+    protected $escapeOutput = false;
+
+    /**
+     * @param mixed $value The switch value. If it matches, the child will be rendered
+     * @param bool $default If this is set, this child will be rendered, if none else matches
+     *
+     * @return string the contents of this view helper if $value equals the expression of the surrounding switch view helper, or $default is TRUE. otherwise an empty string
+     * @throws Exception
+     *
+     * @api
+     */
+    public function render($value = null, $default = false)
+    {
+        return static::renderStatic(
+            array(
+                'value' => $value,
+                'default' => $default
+            ),
+            $this->buildRenderChildrenClosure(),
+            $this->renderingContext
+        );
+    }
+
+    /**
+     * @param array $arguments
+     * @param callable $renderChildrenClosure
+     * @param RenderingContextInterface $renderingContext
+     *
+     * @return mixed|string
+     * @throws Exception
+     */
+    public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
+    {
+        $value = $arguments['value'];
+        $default = $arguments['default'];
+        $viewHelperVariableContainer = $renderingContext->getViewHelperVariableContainer();
+        if ($default !== false) {
+            GeneralUtility::deprecationLog('Argument "default" on f:case is deprecated - use f:defaultCase instead');
+        }
+        if ($value === null && $default === false) {
+            throw new Exception('The case View helper must have either value or default argument', 1382867521);
+        }
+        $expression = $viewHelperVariableContainer->get(OriginalSwitchViewHelper::class, 'switchExpression');
 
-       /**
-        * @param mixed $value The switch value. If it matches, the child will be rendered
-        * @param boolean $default If this is set, this child will be rendered, if none else matches
-        *
-        * @return string the contents of this view helper if $value equals the expression of the surrounding switch view helper, or $default is TRUE. otherwise an empty string
-        * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
-        *
-        * @api
-        */
-       public function render($value = NULL, $default = FALSE) {
-               $viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
-               if (!$viewHelperVariableContainer->exists('TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper', 'switchExpression')) {
-                       throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('The case View helper can only be used within a switch View helper', 1368112037);
-               }
-               if (is_null($value) && $default === FALSE) {
-                       throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('The case View helper must have either value or default argument', 1382867521);
-               }
-               $switchExpression = $viewHelperVariableContainer->get('TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper', 'switchExpression');
+        // non-type-safe comparison by intention
+        if ($default === true || $expression == $value) {
+            $viewHelperVariableContainer->addOrUpdate(OriginalSwitchViewHelper::class, 'break', true);
+            return $renderChildrenClosure();
+        }
 
-               // non-type-safe comparison by intention
-               if ($default === TRUE || $switchExpression == $value) {
-                       $viewHelperVariableContainer->addOrUpdate('TYPO3\CMS\Fluid\ViewHelpers\SwitchViewHelper', 'break', TRUE);
-                       return $this->renderChildren();
-               }
-               return '';
-       }
+        return '';
+    }
 }