From b8fd708139764c29421e4f305e455ce5643cd024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Cobucci?= Date: Fri, 24 Nov 2017 02:22:38 +0100 Subject: [PATCH] Fix parameter name comparison in QueryBuilder#setParameter() with different types --- lib/Doctrine/ORM/QueryBuilder.php | 30 +++----- tests/Doctrine/Tests/ORM/QueryBuilderTest.php | 77 +++++++++++++++++++ 2 files changed, 86 insertions(+), 21 deletions(-) diff --git a/lib/Doctrine/ORM/QueryBuilder.php b/lib/Doctrine/ORM/QueryBuilder.php index 976be4ddf..4081890dd 100644 --- a/lib/Doctrine/ORM/QueryBuilder.php +++ b/lib/Doctrine/ORM/QueryBuilder.php @@ -532,26 +532,15 @@ class QueryBuilder */ public function setParameter($key, $value, $type = null) { - $filteredParameters = $this->parameters->filter( - function ($parameter) use ($key) - { - /* @var Query\Parameter $parameter */ - // Must not be identical because of string to integer conversion - return ($key == $parameter->getName()); - } - ); + $existingParameter = $this->getParameter($key); - if (count($filteredParameters)) { - /* @var Query\Parameter $parameter */ - $parameter = $filteredParameters->first(); - $parameter->setValue($value, $type); + if ($existingParameter !== null) { + $existingParameter->setValue($value, $type); return $this; } - $parameter = new Query\Parameter($key, $value, $type); - - $this->parameters->add($parameter); + $this->parameters->add(new Query\Parameter($key, $value, $type)); return $this; } @@ -614,15 +603,14 @@ class QueryBuilder public function getParameter($key) { $filteredParameters = $this->parameters->filter( - function ($parameter) use ($key) - { - /* @var Query\Parameter $parameter */ - // Must not be identical because of string to integer conversion - return ($key == $parameter->getName()); + function (Query\Parameter $parameter) use ($key) : bool { + $parameterName = $parameter->getName(); + + return $key === $parameterName || (string) $key === (string) $parameterName; } ); - return count($filteredParameters) ? $filteredParameters->first() : null; + return ! $filteredParameters->isEmpty() ? $filteredParameters->first() : null; } /** diff --git a/tests/Doctrine/Tests/ORM/QueryBuilderTest.php b/tests/Doctrine/Tests/ORM/QueryBuilderTest.php index 7da2c663c..1cf8ab164 100644 --- a/tests/Doctrine/Tests/ORM/QueryBuilderTest.php +++ b/tests/Doctrine/Tests/ORM/QueryBuilderTest.php @@ -1158,4 +1158,81 @@ class QueryBuilderTest extends OrmTestCase $this->assertEquals(['u', 'g'], $aliases); } + + /** + * @group 6699 + */ + public function testGetParameterTypeJuggling() : void + { + $builder = $this->_em->createQueryBuilder() + ->select('u') + ->from(CmsUser::class, 'u') + ->where('u.id = ?0'); + + $builder->setParameter(0, 0); + + self::assertCount(1, $builder->getParameters()); + self::assertSame(0, $builder->getParameter(0)->getValue()); + self::assertSame(0, $builder->getParameter('0')->getValue()); + } + + /** + * @group 6699 + */ + public function testSetParameterWithNameZeroIsNotOverridden() : void + { + $builder = $this->_em->createQueryBuilder() + ->select('u') + ->from(CmsUser::class, 'u') + ->where('u.id != ?0') + ->andWhere('u.username = :name'); + + $builder->setParameter(0, 0); + $builder->setParameter('name', 'Doctrine'); + + self::assertCount(2, $builder->getParameters()); + self::assertSame(0, $builder->getParameter('0')->getValue()); + self::assertSame('Doctrine', $builder->getParameter('name')->getValue()); + } + + /** + * @group 6699 + */ + public function testSetParameterWithNameZeroDoesNotOverrideAnotherParameter() : void + { + $builder = $this->_em->createQueryBuilder() + ->select('u') + ->from(CmsUser::class, 'u') + ->where('u.id != ?0') + ->andWhere('u.username = :name'); + + $builder->setParameter('name', 'Doctrine'); + $builder->setParameter(0, 0); + + self::assertCount(2, $builder->getParameters()); + self::assertSame(0, $builder->getParameter(0)->getValue()); + self::assertSame('Doctrine', $builder->getParameter('name')->getValue()); + } + + /** + * @group 6699 + */ + public function testSetParameterWithTypeJugglingWorks() : void + { + $builder = $this->_em->createQueryBuilder() + ->select('u') + ->from(CmsUser::class, 'u') + ->where('u.id != ?0') + ->andWhere('u.username = :name'); + + $builder->setParameter('0', 1); + $builder->setParameter('name', 'Doctrine'); + $builder->setParameter(0, 2); + $builder->setParameter('0', 3); + + self::assertCount(2, $builder->getParameters()); + self::assertSame(3, $builder->getParameter(0)->getValue()); + self::assertSame(3, $builder->getParameter('0')->getValue()); + self::assertSame('Doctrine', $builder->getParameter('name')->getValue()); + } }