Skip to content

Commit 9e1e009

Browse files
committed
Merge branch 'PHP-5.5' of https://git.php.net/repository/php-src into PHP-5.5
* 'PHP-5.5' of https://git.php.net/repository/php-src: Fix bug #64953 (Postgres prepared statement positional parameter casting)
2 parents 433225a + 7f3e7eb commit 9e1e009

File tree

3 files changed

+106
-30
lines changed

3 files changed

+106
-30
lines changed

ext/pdo/pdo_sql_parser.c

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static int scan(Scanner *s)
7777
yy3:
7878
yyaccept = 0;
7979
yych = *(YYMARKER = ++YYCURSOR);
80-
if (yych >= 0x01) goto yy41;
80+
if (yych >= 0x01) goto yy43;
8181
yy4:
8282
#line 63 "ext/pdo/pdo_sql_parser.re"
8383
{ SKIP_ONE(PDO_PARSER_TEXT); }
@@ -86,7 +86,7 @@ static int scan(Scanner *s)
8686
yyaccept = 0;
8787
yych = *(YYMARKER = ++YYCURSOR);
8888
if (yych <= 0x00) goto yy4;
89-
goto yy36;
89+
goto yy38;
9090
yy6:
9191
yych = *++YYCURSOR;
9292
switch (yych) {
@@ -153,21 +153,19 @@ static int scan(Scanner *s)
153153
case 'x':
154154
case 'y':
155155
case 'z': goto yy32;
156-
case ':':
157-
case '?': goto yy29;
156+
case ':': goto yy35;
158157
default: goto yy4;
159158
}
160159
yy7:
161160
++YYCURSOR;
162161
switch ((yych = *YYCURSOR)) {
163-
case ':':
164162
case '?': goto yy29;
165163
default: goto yy8;
166164
}
167165
yy8:
168166
#line 62 "ext/pdo/pdo_sql_parser.re"
169167
{ RET(PDO_PARSER_BIND_POS); }
170-
#line 171 "ext/pdo/pdo_sql_parser.c"
168+
#line 169 "ext/pdo/pdo_sql_parser.c"
171169
yy9:
172170
++YYCURSOR;
173171
switch ((yych = *YYCURSOR)) {
@@ -177,7 +175,7 @@ static int scan(Scanner *s)
177175
yy10:
178176
#line 65 "ext/pdo/pdo_sql_parser.re"
179177
{ RET(PDO_PARSER_TEXT); }
180-
#line 181 "ext/pdo/pdo_sql_parser.c"
178+
#line 179 "ext/pdo/pdo_sql_parser.c"
181179
yy11:
182180
yych = *++YYCURSOR;
183181
switch (yych) {
@@ -214,7 +212,7 @@ static int scan(Scanner *s)
214212
yy16:
215213
#line 64 "ext/pdo/pdo_sql_parser.re"
216214
{ RET(PDO_PARSER_TEXT); }
217-
#line 218 "ext/pdo/pdo_sql_parser.c"
215+
#line 216 "ext/pdo/pdo_sql_parser.c"
218216
yy17:
219217
++YYCURSOR;
220218
if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -288,14 +286,13 @@ static int scan(Scanner *s)
288286
if (YYLIMIT <= YYCURSOR) YYFILL(1);
289287
yych = *YYCURSOR;
290288
switch (yych) {
291-
case ':':
292289
case '?': goto yy29;
293290
default: goto yy31;
294291
}
295292
yy31:
296293
#line 60 "ext/pdo/pdo_sql_parser.re"
297294
{ RET(PDO_PARSER_TEXT); }
298-
#line 299 "ext/pdo/pdo_sql_parser.c"
295+
#line 296 "ext/pdo/pdo_sql_parser.c"
299296
yy32:
300297
++YYCURSOR;
301298
if (YYLIMIT <= YYCURSOR) YYFILL(1);
@@ -369,51 +366,59 @@ static int scan(Scanner *s)
369366
yy34:
370367
#line 61 "ext/pdo/pdo_sql_parser.re"
371368
{ RET(PDO_PARSER_BIND); }
372-
#line 373 "ext/pdo/pdo_sql_parser.c"
369+
#line 370 "ext/pdo/pdo_sql_parser.c"
373370
yy35:
374371
++YYCURSOR;
375372
if (YYLIMIT <= YYCURSOR) YYFILL(1);
376373
yych = *YYCURSOR;
377-
yy36:
378374
switch (yych) {
379-
case 0x00: goto yy2;
380-
case '\'': goto yy38;
381-
case '\\': goto yy37;
382-
default: goto yy35;
375+
case ':': goto yy35;
376+
default: goto yy31;
383377
}
384378
yy37:
385379
++YYCURSOR;
386380
if (YYLIMIT <= YYCURSOR) YYFILL(1);
387381
yych = *YYCURSOR;
388-
if (yych <= 0x00) goto yy2;
389-
goto yy35;
390382
yy38:
383+
switch (yych) {
384+
case 0x00: goto yy2;
385+
case '\'': goto yy40;
386+
case '\\': goto yy39;
387+
default: goto yy37;
388+
}
389+
yy39:
390+
++YYCURSOR;
391+
if (YYLIMIT <= YYCURSOR) YYFILL(1);
392+
yych = *YYCURSOR;
393+
if (yych <= 0x00) goto yy2;
394+
goto yy37;
395+
yy40:
391396
++YYCURSOR;
392397
#line 59 "ext/pdo/pdo_sql_parser.re"
393398
{ RET(PDO_PARSER_TEXT); }
394-
#line 395 "ext/pdo/pdo_sql_parser.c"
395-
yy40:
399+
#line 400 "ext/pdo/pdo_sql_parser.c"
400+
yy42:
396401
++YYCURSOR;
397402
if (YYLIMIT <= YYCURSOR) YYFILL(1);
398403
yych = *YYCURSOR;
399-
yy41:
404+
yy43:
400405
switch (yych) {
401406
case 0x00: goto yy2;
402-
case '"': goto yy43;
403-
case '\\': goto yy42;
404-
default: goto yy40;
407+
case '"': goto yy45;
408+
case '\\': goto yy44;
409+
default: goto yy42;
405410
}
406-
yy42:
411+
yy44:
407412
++YYCURSOR;
408413
if (YYLIMIT <= YYCURSOR) YYFILL(1);
409414
yych = *YYCURSOR;
410415
if (yych <= 0x00) goto yy2;
411-
goto yy40;
412-
yy43:
416+
goto yy42;
417+
yy45:
413418
++YYCURSOR;
414419
#line 58 "ext/pdo/pdo_sql_parser.re"
415420
{ RET(PDO_PARSER_TEXT); }
416-
#line 417 "ext/pdo/pdo_sql_parser.c"
421+
#line 422 "ext/pdo/pdo_sql_parser.c"
417422
}
418423
#line 66 "ext/pdo/pdo_sql_parser.re"
419424

ext/pdo/pdo_sql_parser.re

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ static int scan(Scanner *s)
5050
QUESTION = [?];
5151
COMMENTS = ("/*"([^*]+|[*]+[^/*])*[*]*"*/"|"--"[^\r\n]*);
5252
SPECIALS = [:?"'];
53-
MULTICHAR = [:?];
53+
MULTICHAR = ([:]{2,}|[?]{2,});
5454
ANYNOEOF = [\001-\377];
5555
*/
5656

5757
/*!re2c
5858
(["](([\\]ANYNOEOF)|ANYNOEOF\["\\])*["]) { RET(PDO_PARSER_TEXT); }
5959
(['](([\\]ANYNOEOF)|ANYNOEOF\['\\])*[']) { RET(PDO_PARSER_TEXT); }
60-
MULTICHAR{2,} { RET(PDO_PARSER_TEXT); }
60+
MULTICHAR { RET(PDO_PARSER_TEXT); }
6161
BINDCHR { RET(PDO_PARSER_BIND); }
6262
QUESTION { RET(PDO_PARSER_BIND_POS); }
6363
SPECIALS { SKIP_ONE(PDO_PARSER_TEXT); }

ext/pdo_pgsql/tests/bug64953.phpt

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
--TEST--
2+
PDO PgSQL Bug #64953 (Postgres prepared statement positional parameter casting)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
6+
require dirname(__FILE__) . '/config.inc';
7+
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
8+
PDOTest::skip();
9+
?>
10+
--FILE--
11+
<?php
12+
echo "Test\n";
13+
14+
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
15+
$pdo = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
16+
$pdo->setAttribute (\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
17+
18+
echo "Taken from the bug report:\n";
19+
20+
$st = $pdo->prepare('SELECT ?::char as i');
21+
$st->bindValue(1, '1');
22+
$st->execute();
23+
var_dump($st->fetch()); // return false
24+
25+
26+
$st = $pdo->prepare('SELECT (?)::char as i');
27+
$st->bindValue(1, '1');
28+
$st->execute();
29+
var_dump($st->fetch()); // return array(1) { ["i"]=> string(1) "1" }
30+
31+
echo "Something more nasty:\n";
32+
33+
$st = $pdo->prepare("SELECT :int::int as i");
34+
$st->execute(array(":int" => 123));
35+
var_dump($st->fetch());
36+
37+
$st = $pdo->prepare("SELECT '''?'''::text as \":text\"");
38+
$st->execute();
39+
var_dump($st->fetch());
40+
41+
?>
42+
Done
43+
--EXPECT--
44+
Test
45+
Taken from the bug report:
46+
array(2) {
47+
["i"]=>
48+
string(1) "1"
49+
[0]=>
50+
string(1) "1"
51+
}
52+
array(2) {
53+
["i"]=>
54+
string(1) "1"
55+
[0]=>
56+
string(1) "1"
57+
}
58+
Something more nasty:
59+
array(2) {
60+
["i"]=>
61+
string(3) "123"
62+
[0]=>
63+
string(3) "123"
64+
}
65+
array(2) {
66+
[":text"]=>
67+
string(3) "'?'"
68+
[0]=>
69+
string(3) "'?'"
70+
}
71+
Done

0 commit comments

Comments
 (0)