Commit 5d758762 authored by Nicole Cordes's avatar Nicole Cordes Committed by Markus Klein
Browse files

[BUGFIX] Correct record title escaping

This patch removes default record title escaping in resolved DataProvider
data and adds proper escaping where html output is generated.

Resolves: #76399
Resolves: #76668
Resolves: #76900
Releases: master, 7.6
Change-Id: I03cf41c5200e920088116d1a67a2e342e46142d3
Reviewed-on: https://review.typo3.org/48779

Tested-by: default avatarBamboo TYPO3com <info@typo3.com>
Tested-by: default avatarSusanne Moog <typo3@susannemoog.de>
Reviewed-by: Andreas Fernandez's avatarAndreas Fernandez <typo3@scripting-base.de>
Reviewed-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: default avatarMichael Oehlhof <typo3@oehlhof.de>
Reviewed-by: default avatarFrederic Gaus <frederic.gaus@flagbit.de>
Tested-by: default avatarFrederic Gaus <frederic.gaus@flagbit.de>
Reviewed-by: Markus Klein's avatarMarkus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein's avatarMarkus Klein <markus.klein@typo3.org>
parent f30aa7f5
......@@ -305,7 +305,9 @@ class InlineRecordContainer extends AbstractContainer
$objectId = $domObjectId . '-' . $foreignTable . '-' . $rec['uid'];
$recordTitle = $data['recordTitle'];
if (empty($recordTitle)) {
if (!empty($recordTitle)) {
$recordTitle = BackendUtility::getRecordTitlePrep($recordTitle);
} else {
$recordTitle = '<em>[' . htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.no_title')) . ']</em>';
}
......
......@@ -63,7 +63,7 @@ class SelectCheckBoxElement extends AbstractFormElement
$currentGroup++;
$groups[$currentGroup]['header'] = array(
'icon' => $selIcon,
'title' => htmlspecialchars($p[0])
'title' => $p[0]
);
} else {
// Check if some help text is available
......@@ -103,7 +103,7 @@ class SelectCheckBoxElement extends AbstractFormElement
'disabled' => false,
'class' => '',
'icon' => FormEngineUtility::getIconHtml(!empty($p[2]) ? $p[2] : 'empty-empty'),
'title' => htmlspecialchars($p[0], ENT_COMPAT, 'UTF-8', false),
'title' => $p[0],
'help' => $help
);
$c++;
......@@ -121,7 +121,7 @@ class SelectCheckBoxElement extends AbstractFormElement
$html[] = '<div class="panel-heading">';
$html[] = '<a data-toggle="collapse" href="#' . $groupId . '" aria-expanded="false" aria-controls="' . $groupId . '">';
$html[] = $group['header']['icon'];
$html[] = $group['header']['title'];
$html[] = htmlspecialchars($group['header']['title']);
$html[] = '</a>';
$html[] = '</div>';
}
......@@ -145,7 +145,7 @@ class SelectCheckBoxElement extends AbstractFormElement
$tableRows[] = '<label class="label-block" for="' . $item['id'] . '">' . $item['icon'] . '</label>';
$tableRows[] = '</td>';
$tableRows[] = '<td class="col-title">';
$tableRows[] = '<label class="label-block" for="' . $item['id'] . '">' . $item['title'] . '</label>';
$tableRows[] = '<label class="label-block" for="' . $item['id'] . '">' . htmlspecialchars($item['title'], ENT_COMPAT, 'UTF-8', false) . '</label>';
$tableRows[] = '</td>';
$tableRows[] = '<td class="text-right">' . $item['help'] . '</td>';
$tableRows[] = '</tr>';
......
......@@ -104,7 +104,7 @@ class SelectMultipleSideBySideElement extends AbstractFormElement
$disabledAttr = ' disabled="disabled"';
$classAttr = ' class="hidden"';
}
$opt[] = '<option value="' . htmlspecialchars($p[1]) . '" title="' . $p[0] . '"' . $classAttr . $disabledAttr . '>' . $p[0] . '</option>';
$opt[] = '<option value="' . htmlspecialchars($p[1]) . '" title="' . htmlspecialchars($p[0]) . '"' . $classAttr . $disabledAttr . '>' . htmlspecialchars($p[0]) . '</option>';
}
// Put together the selector box:
$selector_itemListStyle = isset($config['itemListStyle'])
......
......@@ -106,7 +106,6 @@ class SelectSingleElement extends AbstractFormElement
);
} else {
// IS ITEM
$title = htmlspecialchars($item['0'], ENT_COMPAT, 'UTF-8', false);
$icon = !empty($item[2]) ? FormEngineUtility::getIconHtml($item[2], $title, $title) : '';
$selected = $selectedValue === (string)$item[1];
......@@ -115,7 +114,7 @@ class SelectSingleElement extends AbstractFormElement
}
$selectItemGroups[$selectItemGroupCount]['items'][] = array(
'title' => $title,
'title' => $item[0],
'value' => $item[1],
'icon' => $icon,
'selected' => $selected,
......@@ -125,7 +124,7 @@ class SelectSingleElement extends AbstractFormElement
// ICON
if ($icon) {
$selectIcons[] = array(
'title' => $title,
'title' => $item[0],
'icon' => $icon,
'index' => $selectItemCounter,
);
......@@ -155,7 +154,7 @@ class SelectSingleElement extends AbstractFormElement
foreach ($selectItemGroup['items'] as $item) {
$options .= '<option value="' . htmlspecialchars($item['value']) . '" data-icon="' .
htmlspecialchars($item['icon']) . '"'
. ($item['selected'] ? ' selected="selected"' : '') . '>' . $item['title'] . '</option>';
. ($item['selected'] ? ' selected="selected"' : '') . '>' . htmlspecialchars($item['title'], ENT_COMPAT, 'UTF-8', false) . '</option>';
}
$hasIcons = !empty($item['icon']);
}
......@@ -216,7 +215,7 @@ class SelectSingleElement extends AbstractFormElement
$html[] = '<td>';
if (is_array($selectIcon)) {
$html[] = '<a href="#" title="' . $selectIcon['title'] . '" data-select-index="' . $selectIcon['index'] . '">';
$html[] = '<a href="#" title="' . htmlspecialchars($selectIcon['title'], ENT_COMPAT, 'UTF-8', false) . '" data-select-index="' . htmlspecialchars($selectIcon['index']) . '">';
$html[] = $selectIcon['icon'];
$html[] = '</a>';
}
......
......@@ -483,7 +483,7 @@ abstract class AbstractItemProvider
}
// Add the item
$items[] = [
$labelPrefix . htmlspecialchars(BackendUtility::getRecordTitle($foreignTable, $foreignRow)),
$labelPrefix . BackendUtility::getRecordTitle($foreignTable, $foreignRow),
$foreignRow['uid'],
$icon
];
......
......@@ -69,10 +69,7 @@ class TcaRecordTitle implements FormDataProviderInterface
$fieldName = $result['isOnSymmetricSide']
? $result['inlineParentConfig']['symmetric_label']
: $result['inlineParentConfig']['foreign_label'];
// @todo: this is a mixup here. problem is the prep method cuts the string, but also hsc's the thing.
// @todo: this is uncool for the userfuncs, so it is applied only here. however, the OuterWrapContainer
// @todo: also prep()'s the title created by the else patch below ... find a better separation and clean this up!
$result['recordTitle'] = BackendUtility::getRecordTitlePrep($this->getRecordTitleForField($fieldName, $result));
$result['recordTitle'] = $this->getRecordTitleForField($fieldName, $result);
} elseif (isset($result['processedTca']['ctrl']['label_userFunc'])) {
// userFunc takes precedence over everything else
$parameters = [
......@@ -127,7 +124,7 @@ class TcaRecordTitle implements FormDataProviderInterface
}
}
$result['recordTitle'] = htmlspecialchars(implode(', ', $titles));
$result['recordTitle'] = implode(', ', $titles);
return $result;
}
......
......@@ -272,13 +272,6 @@ class TcaRecordTitleTest extends UnitTestCase
'aValue',
'aValue',
],
'html is escaped' => [
[
'type' => 'input',
],
'<foo>',
'&lt;foo&gt;',
],
'date input' => [
[
'type' => 'input',
......
Supports Markdown
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