Commit a3985b9c authored by Benni Mack's avatar Benni Mack Committed by Helmut Hummel
Browse files

[TASK] Streamline escaping for ViewHelpers of all sysexts

The Core does not strictly use $escapeChildren and
$escapeOutput as properly introduced by Fluid Standalone in 8.0.

This results in some weird HTML output when using the inline syntax
currently.

Since $escapeOutput and $escapeChildren is active by default,
some ViewHelpers even do HSC on their own (= twice) even if not
needed.

Resolves: #75575
Releases: master
Change-Id: I3bbebe75c0368519d3506360c68df92d30a3b80a
Reviewed-on: https://review.typo3.org/47644

Reviewed-by: default avatarHelmut Hummel <helmut.hummel@typo3.org>
Tested-by: default avatarHelmut Hummel <helmut.hummel@typo3.org>
Reviewed-by: Nicole Cordes's avatarNicole Cordes <typo3@cordes.co>
Tested-by: Nicole Cordes's avatarNicole Cordes <typo3@cordes.co>
parent ae981c9c
......@@ -25,6 +25,13 @@ use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
*/
class ErrorIconViewHelper extends AbstractBackendViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Renders an error icon link as known from the TYPO3 backend.
* Error codes 2 and three are mapped to "error" and 1 is mapped to "warning".
......
......@@ -68,7 +68,7 @@ class FormatDetailsViewHelper extends AbstractViewHelper
$detailString = vsprintf($detailString, $substitutes);
// Remove possible pending other %s
$detailString = str_replace('%s', '', $detailString);
return htmlspecialchars($detailString);
return $detailString;
}
/**
......
......@@ -31,6 +31,13 @@ use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
*/
class HistoryEntryViewHelper extends AbstractViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Get system history record
*
......@@ -89,6 +96,6 @@ class HistoryEntryViewHelper extends AbstractViewHelper
)
);
$historyLink = '<a href="' . htmlspecialchars($historyHref) . '" title="' . htmlspecialchars($titleLable) . '">' . $historyIcon . '</a>';
return $historyLabel . '&nbsp;' . $historyLink;
return htmlspecialchars($historyLabel) . '&nbsp;' . $historyLink;
}
}
......@@ -59,7 +59,7 @@ class UsernameViewHelper extends AbstractViewHelper
$uid = $arguments['uid'];
if (isset(static::$usernameRuntimeCache[$uid])) {
return htmlspecialchars(static::$usernameRuntimeCache[$uid]);
return static::$usernameRuntimeCache[$uid];
}
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
......@@ -68,6 +68,6 @@ class UsernameViewHelper extends AbstractViewHelper
$user = $backendUserRepository->findByUid($uid);
// $user may be NULL if user was deleted from DB, set it to empty string to always return a string
static::$usernameRuntimeCache[$uid] = ($user === null) ? '' : $user->getUserName();
return htmlspecialchars(static::$usernameRuntimeCache[$uid]);
return static::$usernameRuntimeCache[$uid];
}
}
......@@ -59,7 +59,7 @@ class WorkspaceTitleViewHelper extends AbstractViewHelper
$uid = $arguments['uid'];
if (isset(static::$workspaceTitleRuntimeCache[$uid])) {
return htmlspecialchars(static::$workspaceTitleRuntimeCache[$uid]);
return static::$workspaceTitleRuntimeCache[$uid];
}
if ($uid === 0) {
......@@ -75,6 +75,6 @@ class WorkspaceTitleViewHelper extends AbstractViewHelper
static::$workspaceTitleRuntimeCache[$uid] = ($workspace === null) ? '' : $workspace->getTitle();
}
return htmlspecialchars(static::$workspaceTitleRuntimeCache[$uid]);
return static::$workspaceTitleRuntimeCache[$uid];
}
}
......@@ -23,6 +23,13 @@ use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
*/
class PagesViewHelper extends AbstractViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Render unordered list for pages
*
......
......@@ -23,6 +23,13 @@ use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
*/
class SysFileMountsViewHelper extends AbstractViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Render unordered list for sys_filemounts
*
......
......@@ -23,6 +23,13 @@ use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
*/
class SysLanguageViewHelper extends AbstractViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Render unordered list for sys_language
*
......
......@@ -68,6 +68,6 @@ class IssueCommandViewHelper extends AbstractViewHelper
$parametersArray = GeneralUtility::explodeUrl2Array($arguments['parameters']);
$urlParameters += $parametersArray;
}
return htmlspecialchars(BackendUtility::getModuleUrl('tce_db', $urlParameters));
return BackendUtility::getModuleUrl('tce_db', $urlParameters);
}
}
......@@ -26,6 +26,13 @@ use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
*/
class PermissionsViewHelper extends AbstractViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* @var array Cached labels for a single permission mask like "Delete page"
*/
......@@ -76,18 +83,18 @@ class PermissionsViewHelper extends AbstractViewHelper
$mode = 'add';
}
$label = htmlspecialchars(static::$permissionLabels[$mask]);
$label = static::$permissionLabels[$mask];
$icon .= '<span style="cursor:pointer"'
. ' title="' . $label . '"'
. ' title="' . htmlspecialchars($label) . '"'
. ' data-toggle="tooltip"'
. ' data-page="' . $arguments['pageId'] . '"'
. ' data-permissions="' . $arguments['permission'] . '"'
. ' data-who="' . $arguments['scope'] . '"'
. ' data-bits="' . $mask . '"'
. ' data-mode="' . $mode . '"'
. ' class="t3-icon change-permission fa ' . $permissionClass . '"></span>';
. ' data-page="' . htmlspecialchars($arguments['pageId']) . '"'
. ' data-permissions="' . htmlspecialchars($arguments['permission']) . '"'
. ' data-who="' . htmlspecialchars($arguments['scope']) . '"'
. ' data-bits="' . htmlspecialchars($mask) . '"'
. ' data-mode="' . htmlspecialchars($mode) . '"'
. ' class="t3-icon change-permission fa ' . htmlspecialchars($permissionClass) . '"></span>';
}
return '<span id="' . $arguments['pageId'] . '_' . $arguments['scope'] . '">' . $icon . '</span>';
return '<span id="' . htmlspecialchars($arguments['pageId'] . '_' . $arguments['scope']) . '">' . $icon . '</span>';
}
}
......@@ -31,6 +31,13 @@ use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
*/
class RemoveUserViewHelper extends AbstractViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Render link with sprite icon to remove user
*
......
......@@ -27,6 +27,13 @@ use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
*/
class SpriteIconForRecordViewHelper extends AbstractBackendViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Displays spriteIcon for database table and object
*
......@@ -53,7 +60,7 @@ class SpriteIconForRecordViewHelper extends AbstractBackendViewHelper
* @param RenderingContextInterface $renderingContext
*
* @return string
* @throws Exception
* @throws \Exception
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
......
......@@ -28,6 +28,13 @@ use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
*/
class SwitchUserViewHelper extends AbstractViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Render link with sprite icon to change current backend user to target
*
......
==================================================================================
Deprecation: #75575 - TranslateViewHelper htmlEscape argument marked as deprecated
==================================================================================
Description
===========
The htmlEscape argument of the TranslateViewHelper has been marked as deprecated.
This ViewHelper now HTML escapes the translation by default. The argument value has no effect any more.
Impact
======
Usages of ``<f:translate>`` view helper with argument set to ``false`` will have the label HTML escaped anyway.
Usages of ``<f:translate>`` view helper with argument set to ``true`` will have the label HTML escaped like before unless the view helper is wrapped with a ``<f:format.raw>``
Affected Installations
======================
Installations with usages of ``<f:translate>`` in a context where HTML escaping is not desired (e.g. JavaScript).
Migration
=========
``<f:translate>`` needs to be wrapped by ``<f:format.raw>`` if the view helper result is needed in a different context than HTML
\ No newline at end of file
......@@ -29,6 +29,13 @@ use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
*/
class FormatsViewHelper extends AbstractViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Renders all format download links.
*
......@@ -80,7 +87,7 @@ class FormatsViewHelper extends AbstractViewHelper
$extension = substr($uri, strrpos($uri, '.') + 1);
if (strlen($extension) < 5) {
// This is direct link to a file
$output .= 'href="' . $uri . '" class="btn btn-default"';
$output .= 'href="' . htmlspecialchars($uri) . '" class="btn btn-default"';
$iconHtml = static::getIconForFileExtension($extension, $iconFactory);
} else {
$output .= 'href="#" onclick="top.TYPO3.Backend.ContentContainer.setUrl(' . GeneralUtility::quoteJSvalue($uri) . ')" class="btn btn-default"';
......
......@@ -25,6 +25,13 @@ use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
*/
class JsonEncodeViewHelper extends AbstractViewHelper
{
/**
* Rendered children is expected to be an array or object, which cannot be passed through htmlspecialchars.
*
* @var bool
*/
protected $escapeChildren = false;
/**
* Constructor
*
......
......@@ -28,6 +28,13 @@ use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
*/
class Typo3DependencyViewHelper extends AbstractViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Finds and returns the suitable TYPO3 versions of an extension
*
......
{namespace em=TYPO3\CMS\Extensionmanager\ViewHelpers}
<em:format.jsonEncode additionalAttributes="{
<f:format.raw><em:format.jsonEncode additionalAttributes="{
result: result,
extension: extension.extensionKey,
installationTypeLanguageKey: installationTypeLanguageKey,
......@@ -7,4 +7,4 @@
errorTitle: '{f:translate(key: \'downloadExtension.dependencies.errorTitle\')}',
errorMessage: '{f:render(partial: \'List/UnresolvedDependencies\', arguments: \'{_all}\')}',
skipDependencyUri: '{f:uri.action(action: \'installExtensionWithoutSystemDependencyCheck\', format: \'json\', arguments: \'{extension: extension}\')}'
}" />
\ No newline at end of file
}" /></f:format.raw>
\ No newline at end of file
......@@ -36,6 +36,13 @@ use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
*/
class BaseViewHelper extends AbstractViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Render the "Base" tag by outputting $request->getBaseUri()
*
......
......@@ -42,6 +42,13 @@ use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
*/
class CshViewHelper extends AbstractBackendViewHelper
{
/**
* As this ViewHelper renders HTML, the output must not be escaped.
*
* @var bool
*/
protected $escapeOutput = false;
/**
* Render context sensitive help (CSH) for the given table
*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment