From a62a4c74756bf38af88650313fc03f5957b5274e Mon Sep 17 00:00:00 2001
From: Susanne Moog <susanne.moog@typo3.org>
Date: Thu, 31 May 2018 21:23:45 +0200
Subject: [PATCH] [BUGFIX] Fix inSet implementation for sqlite

For SQLite inSet was implemented with a "like" substitution
which had various bugs. That implementation has
now been substituted with an "instr" implementation.

Resolves: #85131
Releases: master
Change-Id: Id4e8f7132800c991e49d4033d2b01f474b6aae3b
Reviewed-on: https://review.typo3.org/57107
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: TYPO3com <no-reply@typo3.com>
---
 .../Query/Expression/ExpressionBuilder.php    | 34 +++++++++++++------
 .../Expression/ExpressionBuilderTest.php      | 10 +++---
 2 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/typo3/sysext/core/Classes/Database/Query/Expression/ExpressionBuilder.php b/typo3/sysext/core/Classes/Database/Query/Expression/ExpressionBuilder.php
index 4d58337f4607..b2c177d5e6d2 100644
--- a/typo3/sysext/core/Classes/Database/Query/Expression/ExpressionBuilder.php
+++ b/typo3/sysext/core/Classes/Database/Query/Expression/ExpressionBuilder.php
@@ -347,18 +347,32 @@ class ExpressionBuilder
                         1476029421
                     );
                 }
-
-                return $this->comparison(
-                    implode('||', [
-                        $this->literal(','),
-                        $this->connection->quoteIdentifier($fieldName),
-                        $this->literal(','),
-                    ]),
-                    'LIKE',
-                    $this->literal(
-                        '%,' . $this->unquoteLiteral($value) . ',%'
+                $comparison = sprintf(
+                    'instr(%s, %s)',
+                    implode(
+                        '||',
+                        [
+                            $this->literal(','),
+                            $this->connection->quoteIdentifier($fieldName),
+                            $this->literal(','),
+                        ]
+                    ),
+                    $isColumn ?
+                        implode(
+                            '||',
+                            [
+                                $this->literal(','),
+                                // do not explicitly quote value as it is expected to be
+                                // quoted by the caller
+                                'cast(' . $value . ' as text)',
+                                $this->literal(','),
+                            ]
+                        )
+                        : $this->literal(
+                        ',' . $this->unquoteLiteral($value) . ','
                     )
                 );
+                return $comparison;
                 break;
             default:
                 return sprintf(
diff --git a/typo3/sysext/core/Tests/Unit/Database/Query/Expression/ExpressionBuilderTest.php b/typo3/sysext/core/Tests/Unit/Database/Query/Expression/ExpressionBuilderTest.php
index fddd900535ae..10ff586dad25 100644
--- a/typo3/sysext/core/Tests/Unit/Database/Query/Expression/ExpressionBuilderTest.php
+++ b/typo3/sysext/core/Tests/Unit/Database/Query/Expression/ExpressionBuilderTest.php
@@ -321,7 +321,7 @@ class ExpressionBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCa
         $databasePlatform->getStringLiteralQuoteCharacter()->willReturn("'");
 
         $this->connectionProphet->quote(',', Argument::cetera())->shouldBeCalled()->willReturn("','");
-        $this->connectionProphet->quote('%,1,%', Argument::cetera())->shouldBeCalled()->willReturn("'%,1,%'");
+        $this->connectionProphet->quote(',1,', Argument::cetera())->shouldBeCalled()->willReturn("'%,1,%'");
         $this->connectionProphet->quoteIdentifier(Argument::cetera())->will(function ($args) {
             return '"' . $args[0] . '"';
         });
@@ -330,7 +330,7 @@ class ExpressionBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCa
 
         $result = $this->subject->inSet('aField', "'1'");
 
-        $this->assertSame('\',\'||"aField"||\',\' LIKE \'%,1,%\'', $result);
+        $this->assertSame('instr(\',\'||"aField"||\',\', \'%,1,%\')', $result);
     }
 
     /**
@@ -343,8 +343,8 @@ class ExpressionBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCa
         $databasePlatform->getStringLiteralQuoteCharacter()->willReturn("'");
 
         $this->connectionProphet->quote(',', Argument::cetera())->shouldBeCalled()->willReturn("','");
-        $this->connectionProphet->quote('%,\'Some\'Value,%', Argument::cetera())->shouldBeCalled()
-            ->willReturn("'%,''Some''Value,%'");
+        $this->connectionProphet->quote(',\'Some\'Value,', Argument::cetera())->shouldBeCalled()
+            ->willReturn("',''Some''Value,'");
         $this->connectionProphet->quoteIdentifier(Argument::cetera())->will(function ($args) {
             return '"' . $args[0] . '"';
         });
@@ -353,7 +353,7 @@ class ExpressionBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCa
 
         $result = $this->subject->inSet('aField', "'''Some''Value'");
 
-        $this->assertSame('\',\'||"aField"||\',\' LIKE \'%,\'\'Some\'\'Value,%\'', $result);
+        $this->assertSame('instr(\',\'||"aField"||\',\', \',\'\'Some\'\'Value,\')', $result);
     }
 
     /**
-- 
GitLab