[!!!][BUGFIX] Fix usage of issueCommand() and T3_THIS_LOCATION 58/39158/3
authorMarkus Klein <markus.klein@typo3.org>
Fri, 1 May 2015 14:47:55 +0000 (16:47 +0200)
committerHelmut Hummel <helmut.hummel@typo3.org>
Sat, 2 May 2015 17:33:23 +0000 (19:33 +0200)
Multiple usages of T3_THIS_LOCATION are removed as its usage
make only sense in JavaScript context.

issueCommand() takes care of properly quoting the URL when
using in JavaScript context.

Resolves: #66707
Releases: master
Change-Id: Ib0e89e9657fc83bd6514a2077013926f24434a37
Reviewed-on: http://review.typo3.org/39158
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Helmut Hummel <helmut.hummel@typo3.org>
Tested-by: Helmut Hummel <helmut.hummel@typo3.org>
12 files changed:
typo3/sysext/backend/Classes/Template/DocumentTemplate.php
typo3/sysext/backend/Classes/View/PageLayoutView.php
typo3/sysext/beuser/Classes/ViewHelpers/IssueCommandViewHelper.php
typo3/sysext/beuser/Classes/ViewHelpers/RemoveUserViewHelper.php
typo3/sysext/core/Classes/Utility/GeneralUtility.php
typo3/sysext/core/Documentation/Changelog/master/Breaking-66707-IssueCommandNowAddsQuotesWhenUsedInJSContext.rst [new file with mode: 0644]
typo3/sysext/filelist/Classes/FileList.php
typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php
typo3/sysext/sys_action/Classes/ActionTask.php
typo3/sysext/sys_note/Classes/ViewHelpers/DeleteLinkViewHelper.php
typo3/sysext/version/Classes/Controller/VersionModuleController.php
typo3/sysext/version/Classes/View/VersionView.php

index c14b352..32d64e9 100644 (file)
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Backend\Template;
 
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Backend\Utility\IconUtility;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Html\HtmlParser;
 use TYPO3\CMS\Core\Page\PageRenderer;
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
@@ -540,14 +541,25 @@ function jumpToUrl(URL) {
         * See description of the API elsewhere.
         *
         * @param string $params is a set of GET params to send to tce_db.php. Example: "&cmd[tt_content][123][move]=456" or "&data[tt_content][123][hidden]=1&data[tt_content][123][title]=Hello%20World
-        * @param string $redirectUrl Redirect URL if any other that \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REQUEST_URI') is wished
+        * @param string|int $redirectUrl Redirect URL, default is to use GeneralUtility::getIndpEnv('REQUEST_URI'), -1 means to generate an URL for JavaScript using T3_THIS_LOCATION
         * @return string URL to tce_db.php + parameters (backpath is taken from $this->backPath)
         * @see \TYPO3\CMS\Backend\Utility\BackendUtility::editOnClick()
         */
        public function issueCommand($params, $redirectUrl = '') {
-               $redirectUrl = $redirectUrl ? $redirectUrl : GeneralUtility::getIndpEnv('REQUEST_URI');
-               $commandUrl = BackendUtility::getModuleUrl('tce_db') . '&' . $params . '&redirect=' . ($redirectUrl == -1 ? '\'+T3_THIS_LOCATION+\'' : rawurlencode($redirectUrl)) . '&vC=' . rawurlencode($GLOBALS['BE_USER']->veriCode()) . BackendUtility::getUrlToken('tceAction') . '&prErr=1&uPT=1';
-               return $commandUrl;
+               /** @var BackendUserAuthentication $beUser */
+               $beUser = $GLOBALS['BE_USER'];
+               $urlParameters = [
+                       'prErr' => 1,
+                       'uPT' => 1,
+                       'vC' => $beUser->veriCode()
+               ];
+               $url = BackendUtility::getModuleUrl('tce_db', $urlParameters) . $params . BackendUtility::getUrlToken('tceAction') . '&redirect=';
+               if ((int)$redirectUrl === -1) {
+                       $url = GeneralUtility::quoteJSvalue($url) . '+T3_THIS_LOCATION';
+               } else {
+                       $url .= rawurlencode($redirectUrl ?: GeneralUtility::getIndpEnv('REQUEST_URI'));
+               }
+               return $url;
        }
 
        /**
index fe5b4d1..c4aefd3 100644 (file)
@@ -1675,7 +1675,7 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
                        $params .= '&cmd[tt_content][' . $uidVal . '][localize]=' . $lP;
                }
                // Copy for language:
-               $onClick = 'window.location.href=' . GeneralUtility::quoteJSvalue($this->getPageLayoutController()->doc->issueCommand($params)) . '; return false;';
+               $onClick = 'window.location.href=' . $this->getPageLayoutController()->doc->issueCommand($params, -1) . '; return false;';
                $theNewButton = '<div class="t3-page-lang-copyce">' .
                        $this->getPageLayoutController()->doc->t3Button(
                                $onClick,
index 405bdc3..414037f 100644 (file)
@@ -15,6 +15,9 @@ namespace TYPO3\CMS\Beuser\ViewHelpers;
  */
 
 use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
 
 /**
  * Issue command ViewHelper, see TYPO3 Core Engine method issueCommand
@@ -22,7 +25,7 @@ use TYPO3\CMS\Backend\Utility\BackendUtility;
  * @author Felix Kopp <felix-source@phorax.com>
  * @internal
  */
-class IssueCommandViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
+class IssueCommandViewHelper extends AbstractViewHelper {
 
        /**
         * Returns a URL with a command to TYPO3 Core Engine (tce_db.php)
@@ -35,14 +38,15 @@ class IssueCommandViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractVi
         * @see \TYPO3\CMS\Backend\Template\DocumentTemplate::issueCommand()
         */
        public function render($parameters, $redirectUrl = '') {
-               $redirectUrl = $redirectUrl ?: \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REQUEST_URI');
-               $redirect = '&redirect=' . ($redirectUrl === '' ? '\' + T3_THIS_LOCATION + \'' : rawurlencode($redirectUrl));
+               /** @var BackendUserAuthentication $beUser */
+               $beUser = $GLOBALS['BE_USER'];
                $urlParameters = [
-                       'vC' => $GLOBALS['BE_USER']->veriCode(),
+                       'vC' => $beUser->veriCode(),
                        'prErr' => 1,
-                       'uPT' => 1
+                       'uPT' => 1,
+                       'redirect' => $redirectUrl ?: GeneralUtility::getIndpEnv('REQUEST_URI')
                ];
-               return htmlspecialchars(BackendUtility::getModuleUrl('tce_db', $urlParameters) . '&' . $parameters . $redirect  . BackendUtility::getUrlToken('tceAction'));
+               return htmlspecialchars(BackendUtility::getModuleUrl('tce_db', $urlParameters) . $parameters . BackendUtility::getUrlToken('tceAction'));
        }
 
 }
index 13dfd05..614bab8 100644 (file)
@@ -16,15 +16,18 @@ namespace TYPO3\CMS\Beuser\ViewHelpers;
 
 use TYPO3\CMS\Backend\Utility\IconUtility;
 use TYPO3\CMS\Beuser\Domain\Model\BackendUser;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
+
 /**
  * Displays 'Delete user' link with sprite icon to remove user
  *
  * @internal
  */
-class RemoveUserViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
+class RemoveUserViewHelper extends AbstractViewHelper {
 
        /**
         * Render link with sprite icon to remove user
@@ -33,23 +36,24 @@ class RemoveUserViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractView
         * @return string
         */
        public function render(BackendUser $backendUser) {
-               if ($backendUser->getUid() == $GLOBALS['BE_USER']->user['uid']) {
+               /** @var BackendUserAuthentication $beUser */
+               $beUser = $GLOBALS['BE_USER'];
+               if ($backendUser->getUid() === (int)$beUser->user['uid']) {
                        return '<span class="btn btn-default disabled">' . IconUtility::getSpriteIcon('empty-empty') . '</span>';
                }
 
-               $redirectUrl = GeneralUtility::getIndpEnv('REQUEST_URI');
-               $redirect = '&redirect=' . ($redirectUrl == '' ? '\' + T3_THIS_LOCATION + \'' : rawurlencode($redirectUrl));
                $urlParameters = [
                        'cmd[be_users][' . $backendUser->getUid() . '][delete]' => 1,
-                       'vC' => $GLOBALS['BE_USER']->veriCode(),
+                       'vC' => $beUser->veriCode(),
                        'prErr' => 1,
-                       'uPT' => 1
+                       'uPT' => 1,
+                       'redirect' => GeneralUtility::getIndpEnv('REQUEST_URI')
                ];
-               $url = BackendUtility::getModuleUrl('tce_db', $urlParameters) . $redirect . BackendUtility::getUrlToken('tceAction');
+               $url = BackendUtility::getModuleUrl('tce_db', $urlParameters) . BackendUtility::getUrlToken('tceAction');
 
-               return '<a class="btn btn-default" href="' . $url . '"  onclick="return confirm(' .
+               return '<a class="btn btn-default" href="' . htmlspecialchars($url) . '"  onclick="return confirm(' .
                        GeneralUtility::quoteJSvalue(LocalizationUtility::translate('confirm', 'beuser', array($backendUser->getUserName()))) .
-                       ')">' . IconUtility::getSpriteIcon(('actions-edit-delete')) . '</a>';
+                       ')">' . IconUtility::getSpriteIcon('actions-edit-delete') . '</a>';
        }
 
 }
index ad07671..8c1a1e9 100755 (executable)
@@ -3174,7 +3174,7 @@ Connection: close
                        }
                }
                $pString = self::implodeArrayForUrl('', $params);
-               return $pString ? $parts . '?' . preg_replace('/^&/', '', $pString) : $parts;
+               return $pString ? $parts . '?' . ltrim($pString, '&') : $parts;
        }
 
        /**
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-66707-IssueCommandNowAddsQuotesWhenUsedInJSContext.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-66707-IssueCommandNowAddsQuotesWhenUsedInJSContext.rst
new file mode 100644 (file)
index 0000000..ca34322
--- /dev/null
@@ -0,0 +1,27 @@
+=========================================================================
+Breaking: #66707 - issueCommand() now adds quotes when used in JS context
+=========================================================================
+
+Description
+===========
+
+Using ``\TYPO3\CMS\Backend\Template\DocumentTemplate::issueCommand()`` in JavaScript context (second parameter = -1),
+now ensures that the URL is properly escaped and quoted for being used in JavaScript code.
+
+
+Impact
+======
+
+Having additional quotes around the result of the call to ``issueCommand()`` will lead to JavaScript errors.
+
+
+Affected Installations
+======================
+
+Any installation using third party extensions, which use ``issueCommand()`` with second parameter set to -1.
+
+
+Migration
+=========
+
+Make sure that you do **not** specify any additional quotes around the result of the call to ``issueCommand()``.
index 1620215..93fe55f 100644 (file)
@@ -678,10 +678,14 @@ class FileList extends AbstractRecordList {
                                                                        $editOnClick = BackendUtility::editOnClick(GeneralUtility::implodeArrayForUrl('edit', $data), $GLOBALS['BACK_PATH'], $this->listUrl());
                                                                        $languageCode .= '<a href="#" class="btn btn-default" onclick="' . htmlspecialchars($editOnClick) . '">' . $flagButtonIcon . '</a>';
                                                                } else {
+                                                                       $parameters = [
+                                                                               'justLocalized' => 'sys_file_metadata:' . $metaDataRecord['uid'] . ':' . $languageId,
+                                                                               'returnUrl' => $this->listURL()
+                                                                       ];
+                                                                       $returnUrl = BackendUtility::getModuleUrl('record_edit', $parameters, $this->backPath) . BackendUtility::getUrlToken('editRecord');
                                                                        $href = $GLOBALS['SOBE']->doc->issueCommand(
                                                                                '&cmd[sys_file_metadata][' . $metaDataRecord['uid'] . '][localize]=' . $languageId,
-                                                                               $this->backPath . 'alt_doc.php?justLocalized=' . rawurlencode(('sys_file_metadata:' . $metaDataRecord['uid'] . ':' . $languageId)) .
-                                                                               '&returnUrl=' . rawurlencode($this->listURL()) . BackendUtility::getUrlToken('editRecord')
+                                                                               $returnUrl
                                                                        );
                                                                        $flagButtonIcon = IconUtility::getSpriteIcon(
                                                                                $flagIcon,
index 0e3d1a5..f65940c 100644 (file)
@@ -1278,7 +1278,7 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                                        // Up
                                        $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . $this->currentTable['prev'][$row['uid']];
                                        $moveUpAction = '<a class="btn btn-default" href="#" onclick="'
-                                               . htmlspecialchars('return jumpToUrl(\'' . $module->doc->issueCommand($params, -1) . '\');')
+                                               . htmlspecialchars('return jumpToUrl(' . $module->doc->issueCommand($params, -1) . ');')
                                                . '" title="' . $this->getLanguageService()->getLL('moveUp', TRUE) . '">'
                                                . IconUtility::getSpriteIcon('actions-move-up') . '</a>';
                                } else {
@@ -1290,7 +1290,7 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                                        // Down
                                        $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . $this->currentTable['next'][$row['uid']];
                                        $moveDownAction = '<a class="btn btn-default" href="#" onclick="'
-                                               . htmlspecialchars('return jumpToUrl(\'' . $module->doc->issueCommand($params, -1) . '\');')
+                                               . htmlspecialchars('return jumpToUrl(' . $module->doc->issueCommand($params, -1) . ');')
                                                . '" title="' . $this->getLanguageService()->getLL('moveDown', TRUE) . '">'
                                                . IconUtility::getSpriteIcon('actions-move-down') . '</a>';
                                } else {
@@ -1365,7 +1365,7 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                                if ($this->calcPerms & Permission::PAGE_NEW) {
                                        $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . -$this->id;
                                        $moveLeftAction = '<a class="btn btn-default" href="#" onclick="'
-                                               . htmlspecialchars('return jumpToUrl(\'' . $module->doc->issueCommand($params, -1) . '\');')
+                                               . htmlspecialchars('return jumpToUrl(' . $module->doc->issueCommand($params, -1) . ');')
                                                . '" title="' . $this->getLanguageService()->getLL('prevLevel', TRUE) . '">'
                                                . IconUtility::getSpriteIcon('actions-move-left') . '</a>';
                                        $this->addActionToCellGroup($cells, $moveLeftAction, 'moveLeft');
@@ -1376,7 +1376,7 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                                        if ($localCalcPerms & Permission::PAGE_NEW) {
                                                $params = '&cmd[' . $table . '][' . $row['uid'] . '][move]=' . $this->currentTable['prevUid'][$row['uid']];
                                                $moveRightAction = '<a class="btn btn-default" href="#" onclick="'
-                                                       . htmlspecialchars('return jumpToUrl(\'' . $module->doc->issueCommand($params, -1) . '\');')
+                                                       . htmlspecialchars('return jumpToUrl(' . $module->doc->issueCommand($params, -1) . ');')
                                                        . '" title="' . $this->getLanguageService()->getLL('nextLevel', TRUE) . '">'
                                                        . IconUtility::getSpriteIcon('actions-move-right') . '</a>';
                                        } else {
@@ -1590,8 +1590,10 @@ class DatabaseRecordList extends AbstractDatabaseRecordList {
                        foreach ($this->pageOverlays as $lUid_OnPage => $lsysRec) {
                                if (!isset($translations['translations'][$lUid_OnPage]) && $this->getBackendUserAuthentication()->checkLanguageAccess($lUid_OnPage)) {
                                        $url = substr($this->listURL(), strlen($this->backPath));
-                                       $href = $this->getModule()->doc->issueCommand('&cmd[' . $table . '][' . $row['uid'] . '][localize]='
-                                               . $lUid_OnPage, $url . '&justLocalized=' . rawurlencode($table . ':' . $row['uid'] . ':' . $lUid_OnPage));
+                                       $href = $this->getModule()->doc->issueCommand(
+                                               '&cmd[' . $table . '][' . $row['uid'] . '][localize]=' . $lUid_OnPage,
+                                               $url . '&justLocalized=' . rawurlencode($table . ':' . $row['uid'] . ':' . $lUid_OnPage)
+                                       );
                                        $language = BackendUtility::getRecord('sys_language', $lUid_OnPage, 'title');
                                        if ($this->languageIconTitles[$lUid_OnPage]['flagIcon']) {
                                                $lC = IconUtility::getSpriteIcon($this->languageIconTitles[$lUid_OnPage]['flagIcon']);
index f131d8f..739e039 100644 (file)
@@ -838,7 +838,7 @@ class ActionTask implements \TYPO3\CMS\Taskcenter\TaskInterface {
 
                                        return list ? list : idList;
                                }
-                               T3_THIS_LOCATION = "' . rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI')) . '";
+                               T3_THIS_LOCATION = ' . GeneralUtility::quoteJSvalue(rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI'))) . ';
 
                                if (top.fsMod) top.fsMod.recentIds["web"] = ' . (int)$this->id . ';
                        ');
index fdf0b76..baaa3e1 100644 (file)
@@ -15,13 +15,15 @@ namespace TYPO3\CMS\SysNote\ViewHelpers;
  */
 
 use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
 
 /**
  * ViewHelper to create a link to delete a note
  *
  * @internal
  */
-class DeleteLinkViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
+class DeleteLinkViewHelper extends AbstractViewHelper {
 
        /**
         * Create link to delete a note
@@ -30,9 +32,11 @@ class DeleteLinkViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractView
         * @return string link
         */
        public function render($id) {
-               $redirectUrl = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REQUEST_URI');
-               $urlParameters = ['cmd[sys_note][' . $id . '][delete]' => 1];
-               $url = BackendUtility::getModuleUrl('tce_db', $urlParameters) . '&redirect=' . ($redirectUrl == '' ? '\' + T3_THIS_LOCATION + \'' : rawurlencode($redirectUrl)) . BackendUtility::getUrlToken('tceAction');
+               $urlParameters = [
+                       'cmd[sys_note][' . $id . '][delete]' => 1,
+                       'redirect' => GeneralUtility::getIndpEnv('REQUEST_URI')
+               ];
+               $url = BackendUtility::getModuleUrl('tce_db', $urlParameters) . BackendUtility::getUrlToken('tceAction');
                return htmlspecialchars($url);
        }
 
index 0dfdf33..4038899 100644 (file)
@@ -350,7 +350,7 @@ class VersionModuleController extends \TYPO3\CMS\Backend\Module\BaseScriptClass
                        $content .= '
                                <tr class="' . ($row['uid'] != $this->uid ? 'bgColor4' : 'bgColor2 tableheader') . '">
                                        <td>' . ($row['uid'] != $this->uid ?
-                                               '<a href="' . $this->doc->issueCommand(('&cmd[' . $this->table . '][' . $this->uid . '][version][swapWith]=' . $row['uid'] . '&cmd[' . $this->table . '][' . $this->uid . '][version][action]=swap')) . '" title="' . $GLOBALS['LANG']->getLL('swapWithCurrent', TRUE) . '">' . IconUtility::getSpriteIcon('actions-version-swap-version') . '</a>' :
+                                               '<a href="' . $this->doc->issueCommand('&cmd[' . $this->table . '][' . $this->uid . '][version][swapWith]=' . $row['uid'] . '&cmd[' . $this->table . '][' . $this->uid . '][version][action]=swap') . '" title="' . $GLOBALS['LANG']->getLL('swapWithCurrent', TRUE) . '">' . IconUtility::getSpriteIcon('actions-version-swap-version') . '</a>' :
                                                        IconUtility::getSpriteIcon('status-status-current', array('title' => $GLOBALS['LANG']->getLL('currentOnlineVersion', TRUE)))) . '</td>
                                        <td nowrap="nowrap">' . $adminLinks . '</td>
                                        <td nowrap="nowrap">' . BackendUtility::getRecordTitle($this->table, $row, TRUE) . '</td>
@@ -474,7 +474,7 @@ class VersionModuleController extends \TYPO3\CMS\Backend\Module\BaseScriptClass
                // Edit link:
                $adminLink = '<a href="#" onclick="' . htmlspecialchars(BackendUtility::editOnClick('&edit[' . $table . '][' . $row['uid'] . ']=edit')) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:cm.edit', TRUE) . '">' . IconUtility::getSpriteIcon('actions-document-open') . '</a>';
                // Delete link:
-               $adminLink .= '<a href="' . htmlspecialchars($this->doc->issueCommand(('&cmd[' . $table . '][' . $row['uid'] . '][delete]=1'))) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:cm.delete', TRUE) . '">' . IconUtility::getSpriteIcon('actions-edit-delete') . '</a>';
+               $adminLink .= '<a href="' . htmlspecialchars($this->doc->issueCommand('&cmd[' . $table . '][' . $row['uid'] . '][delete]=1')) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:cm.delete', TRUE) . '">' . IconUtility::getSpriteIcon('actions-edit-delete') . '</a>';
                if ($table === 'pages') {
                        // If another page module was specified, replace the default Page module with the new one
                        $newPageModule = trim($GLOBALS['BE_USER']->getTSConfigVal('options.overridePageModule'));
index d5be92a..0f46d29 100644 (file)
@@ -13,6 +13,7 @@ namespace TYPO3\CMS\Version\View;
  *
  * The TYPO3 project - inspiring people to share!
  */
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * Contains some parts for staging, versioning and workspaces
@@ -52,7 +53,7 @@ class VersionView {
                                        } else {
                                                $label = $vRow['t3ver_label'] . ' (' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xlf:versionId', TRUE) . ' ' . $vRow['t3ver_id'] . ($vRow['t3ver_wsid'] != 0 ? ' ' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xlf:workspaceId', TRUE) . ' ' . $vRow['t3ver_wsid'] : '') . ')';
                                        }
-                                       $opt[] = '<option value="' . htmlspecialchars(\TYPO3\CMS\Core\Utility\GeneralUtility::linkThisScript(array('id' => $vRow['uid']))) . '"' . ($id == $vRow['uid'] ? ' selected="selected"' : '') . '>' . htmlspecialchars($label) . '</option>';
+                                       $opt[] = '<option value="' . htmlspecialchars(GeneralUtility::linkThisScript(array('id' => $vRow['uid']))) . '"' . ($id == $vRow['uid'] ? ' selected="selected"' : '') . '>' . htmlspecialchars($label) . '</option>';
                                }
                                // Add management link:
                                $management = '<input type="button" value="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:ver.mgm', TRUE) . '" onclick="window.location.href=\'' . htmlspecialchars($GLOBALS['BACK_PATH'] . \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleUrl('web_txversionM1', array('table' => 'pages', 'uid' => $onlineId))) . '\';" />';
@@ -60,9 +61,13 @@ class VersionView {
                                $onChange = 'window.location.href=this.options[this.selectedIndex].value;';
                                // Controls:
                                if ($id == $onlineId) {
-                                       $controls .= '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/blinkarrow_left.gif', 'width="5" height="9"') . ' class="absmiddle" alt="" /> <strong>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:ver.online', TRUE) . '</strong>';
+                                       $controls = '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/blinkarrow_left.gif', 'width="5" height="9"') . ' class="absmiddle" alt="" /> <strong>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:ver.online', TRUE) . '</strong>';
                                } elseif (!$noAction) {
-                                       $controls .= '<a href="' . $GLOBALS['TBE_TEMPLATE']->issueCommand(('&cmd[pages][' . $onlineId . '][version][swapWith]=' . $id . '&cmd[pages][' . $onlineId . '][version][action]=swap'), \TYPO3\CMS\Core\Utility\GeneralUtility::linkThisScript(array('id' => $onlineId))) . '" class="text-nowrap">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-version-swap-version', array(
+                                       $href = $GLOBALS['TBE_TEMPLATE']->issueCommand(
+                                               '&cmd[pages][' . $onlineId . '][version][swapWith]=' . $id . '&cmd[pages][' . $onlineId . '][version][action]=swap',
+                                               GeneralUtility::linkThisScript(array('id' => $onlineId))
+                                       );
+                                       $controls = '<a href="' . htmlspecialchars($href) . '" class="text-nowrap">' . \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-version-swap-version', array(
                                                'title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:ver.swapPage', TRUE),
                                                'style' => 'margin-left:5px;vertical-align:bottom;'
                                        )) . '<strong>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:ver.swap', TRUE) . '</strong></a>';