From be5cae20b145ef20a1071ee7eab310cc05707970 Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Thu, 27 Aug 2026 12:54:27 +0530 Subject: [PATCH 1/2] fix: improve query validation for nested JSON objects --- src/Database/Query.php | 8 +++++++- tests/unit/QueryTest.php | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/Database/Query.php b/src/Database/Query.php index d19b84259a..147c463ad0 100644 --- a/src/Database/Query.php +++ b/src/Database/Query.php @@ -393,7 +393,13 @@ public static function parseQuery(array $query): self if (\in_array($method, self::LOGICAL_TYPES)) { foreach ($values as $index => $value) { - $values[$index] = self::parseQuery($value); + if (\is_string($value)) { + $values[$index] = self::parse($value); + } elseif (\is_array($value)) { + $values[$index] = self::parseQuery($value); + } else { + throw new QueryException('Invalid nested query. Must be an array or string, got ' . \gettype($value)); + } } } diff --git a/tests/unit/QueryTest.php b/tests/unit/QueryTest.php index 0f1f697264..30c1bcdbd9 100644 --- a/tests/unit/QueryTest.php +++ b/tests/unit/QueryTest.php @@ -395,6 +395,40 @@ public function testParse(): void $this->assertEquals([], $query->getValues()); } + public function testParseNestedStringValues(): void + { + // Some clients serialize the children of a logical query as JSON strings + // rather than nested objects. Parsing must handle that without a TypeError. + $json = \json_encode([ + 'method' => Query::TYPE_OR, + 'values' => [ + Query::equal('actors', ['Brad Pitt'])->toString(), + Query::equal('actors', ['Johnny Depp'])->toString(), + ], + ]); + + $query = Query::parse($json); + + /** @var array $queries */ + $queries = $query->getValues(); + $this->assertEquals(Query::TYPE_OR, $query->getMethod()); + $this->assertCount(2, $queries); + $this->assertEquals(Query::TYPE_EQUAL, $queries[0]->getMethod()); + $this->assertEquals('actors', $queries[0]->getAttribute()); + $this->assertEquals(['Brad Pitt'], $queries[0]->getValues()); + $this->assertEquals(Query::TYPE_EQUAL, $queries[1]->getMethod()); + $this->assertEquals(['Johnny Depp'], $queries[1]->getValues()); + + // A nested value that is neither an array nor a string is a clean + // QueryException, never an uncaught TypeError. + try { + Query::parse(\json_encode(['method' => Query::TYPE_OR, 'values' => [123]])); + $this->fail('Failed to throw exception'); + } catch (QueryException $e) { + $this->assertEquals('Invalid nested query. Must be an array or string, got integer', $e->getMessage()); + } + } + public function testIsMethod(): void { $this->assertTrue(Query::isMethod('equal')); From cd2493a98c5610a2d4b08d27b1321872bac03106 Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Thu, 27 Aug 2026 13:00:07 +0530 Subject: [PATCH 2/2] fix: enhance query parsing for JSON strings to prevent TypeErrors --- tests/unit/QueryTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/QueryTest.php b/tests/unit/QueryTest.php index 30c1bcdbd9..7d1414c0fb 100644 --- a/tests/unit/QueryTest.php +++ b/tests/unit/QueryTest.php @@ -399,7 +399,7 @@ public function testParseNestedStringValues(): void { // Some clients serialize the children of a logical query as JSON strings // rather than nested objects. Parsing must handle that without a TypeError. - $json = \json_encode([ + $json = (string) \json_encode([ 'method' => Query::TYPE_OR, 'values' => [ Query::equal('actors', ['Brad Pitt'])->toString(), @@ -422,7 +422,7 @@ public function testParseNestedStringValues(): void // A nested value that is neither an array nor a string is a clean // QueryException, never an uncaught TypeError. try { - Query::parse(\json_encode(['method' => Query::TYPE_OR, 'values' => [123]])); + Query::parse((string) \json_encode(['method' => Query::TYPE_OR, 'values' => [123]])); $this->fail('Failed to throw exception'); } catch (QueryException $e) { $this->assertEquals('Invalid nested query. Must be an array or string, got integer', $e->getMessage());