Skip to content
Snippets Groups Projects
Commit 56c20415 authored by Markus Klein's avatar Markus Klein Committed by Philipp Gampe
Browse files

[BUGFIX] Extbase: Do not mangle SQL query when constraint value is empty

The query parser now throws an exception if the given value for an
IN or CONTAINS expression is invalid, instead of silently converting
it to a "1<>1" condition.
This helps developers when searching for broken queries and prevents
running queries with invalid/useless constraints.

Resolves: #79388
Releases: master
Change-Id: I9868325810ec11c72c994a0106a9e27141d95f3a
Reviewed-on: https://review.typo3.org/51360


Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: default avatarJohannes Kasberger <johannes.kasberger@reelworx.at>
Tested-by: default avatarJohannes Kasberger <johannes.kasberger@reelworx.at>
Reviewed-by: default avatarWouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: default avatarPhilipp Gampe <philipp.gampe@typo3.org>
Tested-by: default avatarPhilipp Gampe <philipp.gampe@typo3.org>
parent 7adb722a
Branches
Tags
No related merge requests found
......@@ -15,6 +15,7 @@ namespace TYPO3\CMS\Extbase\Persistence\Generic\Storage;
*/
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;
use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
......@@ -23,6 +24,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\Generic\Exception\InconsistentQuerySettingsException;
use TYPO3\CMS\Extbase\Persistence\Generic\Exception\InvalidRelationConfigurationException;
use TYPO3\CMS\Extbase\Persistence\Generic\Exception\MissingColumnMapException;
use TYPO3\CMS\Extbase\Persistence\Generic\Exception\RepositoryException;
use TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedOrderException;
use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap;
use TYPO3\CMS\Extbase\Persistence\Generic\Qom;
......@@ -291,15 +293,16 @@ class Typo3DbQueryParser
*
* @param Qom\ComparisonInterface $comparison The comparison to parse
* @param Qom\SourceInterface $source The source
* @throws \RuntimeException
* @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\RepositoryException
* @return string
* @throws \RuntimeException
* @throws RepositoryException
* @throws Exception\BadConstraintException
*/
protected function parseComparison(Qom\ComparisonInterface $comparison, Qom\SourceInterface $source)
{
if ($comparison->getOperator() === QueryInterface::OPERATOR_CONTAINS) {
if ($comparison->getOperand2() === null) {
return '1<>1';
throw new Exception\BadConstraintException('The value for the CONTAINS operator must not be null.', 1484828468);
} else {
$value = $this->dataMapper->getPlainValue($comparison->getOperand2());
if (!$source instanceof Qom\SelectorInterface) {
......@@ -368,7 +371,7 @@ class Typo3DbQueryParser
);
}
} else {
throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\RepositoryException('Unsupported or non-existing property name "' . $propertyName . '" used in relation matching.', 1327065745);
throw new RepositoryException('Unsupported or non-existing property name "' . $propertyName . '" used in relation matching.', 1327065745);
}
}
} else {
......@@ -383,6 +386,7 @@ class Typo3DbQueryParser
* @param Qom\SourceInterface $source The source
* @return string
* @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception
* @thorws Exception\BadConstraintException
*/
protected function parseDynamicOperand(Qom\ComparisonInterface $comparison, Qom\SourceInterface $source)
{
......@@ -401,11 +405,10 @@ class Typo3DbQueryParser
$plainValues[] = $plainValue;
}
}
if ($hasValue) {
$expr = $exprBuilder->comparison($fieldName, 'IN', '(' . implode(', ', $plainValues) . ')');
} else {
$expr = '1<>1';
if (!$hasValue) {
throw new Exception\BadConstraintException('The IN operator needs a non-empty value list to compare against. The given value list is empty.', 1484828466);
}
$expr = $exprBuilder->comparison($fieldName, 'IN', '(' . implode(', ', $plainValues) . ')');
break;
case QueryInterface::OPERATOR_EQUAL_TO:
if ($value === null) {
......@@ -873,7 +876,7 @@ class Typo3DbQueryParser
*
* @param string &$className The name of the parent class, will be set to the child class after processing.
* @param string &$tableName The name of the parent table, will be set to the table alias that is used in the union statement.
* @param array &$propertyPath The remaining property path, will be cut of by one part during the process.
* @param string &$propertyPath The remaining property path, will be cut of by one part during the process.
* @param string $fullPropertyPath The full path the the current property, will be used to make table names unique.
* @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception
* @throws InvalidRelationConfigurationException
......@@ -982,6 +985,7 @@ class Typo3DbQueryParser
protected function replaceTableNameWithAlias($statement, $tableName, $tableAlias)
{
if ($tableAlias !== $tableName) {
/** @var Connection $connection */
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($tableName);
$quotedTableName = $connection->quoteIdentifier($tableName);
$quotedTableAlias = $connection->quoteIdentifier($tableAlias);
......
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