Skip to content

Commit f33136c

Browse files
authored
Prevent false-positives in placeholder validation (#752)
* Prevent false-positives in placeholder validation * fix
1 parent 813afaa commit f33136c

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

src/QueryReflection/PlaceholderValidation.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public function checkQuery(Expr $queryExpr, Scope $scope, array $parameters): it
2020

2121
$queryStrings = [];
2222
$namedPlaceholders = false;
23-
foreach ($queryReflection->resolveQueryStrings($queryExpr, $scope) as $queryString) {
23+
foreach ($queryReflection->resolveQueryStrings($queryExpr, $scope, false) as $queryString) {
2424
$queryStrings[] = $queryString;
2525

2626
if ($queryReflection->containsNamedPlaceholders($queryString, $parameters)) {

src/QueryReflection/QueryReflection.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ public function resolvePreparedQueryString(Expr $queryExpr, Type $parameterTypes
268268
*
269269
* @throws UnresolvableQueryException
270270
*/
271-
public function resolveQueryStrings(Expr $queryExpr, Scope $scope): iterable
271+
public function resolveQueryStrings(Expr $queryExpr, Scope $scope, bool $resolveNonConstantQueries = true): iterable
272272
{
273273
$type = $scope->getType($queryExpr);
274274

@@ -287,7 +287,12 @@ public function resolveQueryStrings(Expr $queryExpr, Scope $scope): iterable
287287

288288
// query simulation might lead in a invalid query, skip those
289289
$error = $this->validateQueryString($normalizedQuery);
290-
if ($error === null) {
290+
if (
291+
$error === null
292+
// late abort the query, so we allow the query simulation/validation to throw
293+
// UnresolvableQueryException
294+
&& $resolveNonConstantQueries
295+
) {
291296
yield $normalizedQuery;
292297
}
293298
}

tests/rules/data/syntax-error-in-prepared-statement.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,4 +361,25 @@ public function bug458(Connection $conn)
361361
$table = $this->returnsUnion();
362362
$conn->executeQuery('SELECT * FROM ' . $table . ' LIMIT 1');
363363
}
364+
365+
/**
366+
* @param array<int> $ids
367+
*/
368+
protected function conditionalUnnamedPlaceholder(Connection $connection, array $ids, int $adaid): void
369+
{
370+
$values = [];
371+
$query = 'SELECT email, adaid FROM ada';
372+
373+
$query .= ' AND adaid IN (' . someCall($ids) . ')';
374+
$values = array_merge($values, $ids);
375+
376+
if (rand(0, 1) === 1) {
377+
$query .= ' AND email = ?';
378+
$values[] = '[email protected]';
379+
}
380+
381+
$query .= ' ORDER BY adaid';
382+
383+
$connection->preparedQuery($query, $values);
384+
}
364385
}

0 commit comments

Comments
 (0)