Skip to content

Commit 16a26d4

Browse files
committed
Escaped question marks inside dollar quoted strings
Allow "??" in dollar quoted strings for backwards compatibility, as it was a viable workaround to insert question marks without them being parsed as placeholders. Add a deprecation notice to tell that the escape is no longer necessary within dollar quotes and that its usage is deprecated. Ref bug #14244
1 parent bf3aa65 commit 16a26d4

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

ext/pdo/pdo_sql_parser.re

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, zend_string *inquery, zend_string
9090
/* Matching closing quote found, end custom quoting */
9191
custom_quote.pos = NULL;
9292
custom_quote.len = 0;
93+
} else if (t == PDO_PARSER_ESCAPED_QUESTION) {
94+
/* An escaped question mark has been used inside a dollar quoted string, most likely as a workaround
95+
* as a single "?" would have been parsed as placeholder, due to the lack of support for dollar quoted
96+
* strings. For now, we emit a deprecation notice, but still process it */
97+
php_error_docref(NULL, E_DEPRECATED, "Escaping question marks inside dollar quoted strings is not required anymore and is deprecated");
98+
99+
goto placeholder;
93100
}
94101

95102
continue;
@@ -119,6 +126,7 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, zend_string *inquery, zend_string
119126
query_type |= PDO_PLACEHOLDER_POSITIONAL;
120127
}
121128

129+
placeholder:
122130
plc = emalloc(sizeof(*plc));
123131
memset(plc, 0, sizeof(*plc));
124132
plc->next = NULL;

ext/pdo_pgsql/tests/bug_14244.phpt

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
--TEST--
2+
PDO PgSQL Bug #14244 (Postgres sees parameters in a dollar-delimited string)
3+
--EXTENSIONS--
4+
pdo
5+
pdo_pgsql
6+
--SKIPIF--
7+
<?php
8+
require __DIR__ . '/config.inc';
9+
require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
10+
PDOTest::skip();
11+
?>
12+
--FILE--
13+
<?php
14+
echo "Test\n";
15+
16+
require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
17+
$pdo = PDOTest::test_factory(__DIR__ . '/common.phpt');
18+
$pdo->setAttribute (\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
19+
$pdo->setAttribute (\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC);
20+
21+
echo "Already working (see bug64953.phpt):\n";
22+
23+
$st = $pdo->prepare("SELECT '?' question");
24+
$st->execute();
25+
var_dump($st->fetch());
26+
27+
echo "Inside a dollar-quoted string:\n";
28+
29+
$st = $pdo->prepare("SELECT \$\$?\$\$ question");
30+
$st->execute();
31+
var_dump($st->fetch());
32+
33+
?>
34+
Done
35+
--EXPECT--
36+
Test
37+
Already working (see bug64953.phpt):
38+
array(1) {
39+
["question"]=>
40+
string(1) "?"
41+
}
42+
Inside a dollar-quoted string:
43+
array(1) {
44+
["question"]=>
45+
string(1) "?"
46+
}
47+
Done

ext/pdo_pgsql/tests/pdo_pgsql_parser.phpt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ UNION ALL
2525
SELECT U&'d\0061t\+000061? ' || ? AS b /* :name */
2626
UNION ALL
2727
SELECT $__$Is this a $$dollar$$ 'escaping'? $__$ || ? AS b -- ?
28+
UNION ALL
29+
SELECT $$Escaped question mark here?? $$ || ? AS b -- ?
2830
EOF;
2931

3032
$stmt = $db->prepare($query);
31-
$stmt->execute(['World', 'World', 'base', 'Yes']);
33+
$stmt->execute(['World', 'World', 'base', 'Yes', 'Yes']);
3234

3335
while ($row = $stmt->fetchColumn()) {
3436
var_dump($row);
@@ -56,10 +58,12 @@ try {
5658
}
5759

5860
?>
59-
--EXPECT--
61+
--EXPECTF--
62+
Deprecated: PDO::prepare(): Escaping question marks inside dollar quoted strings is not required anymore and is deprecated in %s on line %d
6063
string(14) "He'll'o? World"
6164
string(14) "He'll'o?\World"
6265
string(10) "data? base"
6366
string(36) "Is this a $$dollar$$ 'escaping'? Yes"
67+
string(31) "Escaped question mark here? Yes"
6468
bool(true)
6569
bool(true)

0 commit comments

Comments
 (0)