felipe Fri Oct 10 12:08:07 2008 UTC
Added files:
/php-src/ext/pdo_mysql/tests bug41125.phpt
Modified files:
/php-src/ext/pdo pdo_sql_parser.c pdo_sql_parser.re
Log:
- Fixed bug #44251 (Question mark and an escaped singel quote lead to an
exception)
- Fixed bug #41125 (PDO mysql + quote() + prepare() can result in seg fault)
Patch by: tsteiner at nerdclub dot net
http://cvs.php.net/viewvc.cgi/php-src/ext/pdo/pdo_sql_parser.c?r1=1.57&r2=1.58&diff_format=u
Index: php-src/ext/pdo/pdo_sql_parser.c
diff -u php-src/ext/pdo/pdo_sql_parser.c:1.57
php-src/ext/pdo/pdo_sql_parser.c:1.58
--- php-src/ext/pdo/pdo_sql_parser.c:1.57 Mon Dec 31 07:12:12 2007
+++ php-src/ext/pdo/pdo_sql_parser.c Fri Oct 10 12:08:07 2008
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.11.0 on Mon Nov 26 16:10:00 2007 */
+/* Generated by re2c 0.13.5 on Fri Oct 10 09:03:17 2008 */
#line 1 "ext/pdo/pdo_sql_parser.re"
/*
+----------------------------------------------------------------------+
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pdo_sql_parser.c,v 1.57 2007/12/31 07:12:12 sebastian Exp $ */
+/* $Id: pdo_sql_parser.c,v 1.58 2008/10/10 12:08:07 felipe Exp $ */
#include "php.h"
#include "php_pdo_driver.h"
@@ -47,7 +47,7 @@
char *cursor = s->cur;
s->tok = cursor;
- #line 54 "ext/pdo/pdo_sql_parser.re"
+ #line 55 "ext/pdo/pdo_sql_parser.re"
@@ -55,9 +55,9 @@
{
YYCTYPE yych;
- if((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+ if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
- switch(yych) {
+ switch (yych) {
case 0x00: goto yy11;
case '"': goto yy2;
case '\'': goto yy4;
@@ -66,34 +66,19 @@
default: goto yy8;
}
yy2:
- yych = *++YYCURSOR;
- switch(yych) {
- case '"': goto yy26;
- case '\'':
- case ':':
- case '?': goto yy28;
- default: goto yy30;
- }
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych >= 0x01) goto yy26;
yy3:
-#line 62 "ext/pdo/pdo_sql_parser.re"
+#line 63 "ext/pdo/pdo_sql_parser.re"
{ SKIP_ONE(PDO_PARSER_TEXT); }
-#line 81 "ext/pdo/pdo_sql_parser.c"
+#line 75 "ext/pdo/pdo_sql_parser.c"
yy4:
- yych = *++YYCURSOR;
- switch(yych) {
- case '"':
- case ':':
- case '?': goto yy19;
- case '\'': goto yy21;
- default: goto yy23;
- }
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych <= 0x00) goto yy3;
+ goto yy20;
yy5:
yych = *++YYCURSOR;
- switch(yych) {
- case '"':
- case '\'':
- case ':':
- case '?': goto yy13;
+ switch (yych) {
case '0':
case '1':
case '2':
@@ -157,26 +142,26 @@
case 'x':
case 'y':
case 'z': goto yy16;
+ case ':':
+ case '?': goto yy13;
default: goto yy3;
}
yy6:
++YYCURSOR;
- switch((yych = *YYCURSOR)) {
- case '"':
- case '\'':
+ switch ((yych = *YYCURSOR)) {
case ':':
case '?': goto yy13;
default: goto yy7;
}
yy7:
-#line 61 "ext/pdo/pdo_sql_parser.re"
+#line 62 "ext/pdo/pdo_sql_parser.re"
{ RET(PDO_PARSER_BIND_POS); }
-#line 175 "ext/pdo/pdo_sql_parser.c"
+#line 160 "ext/pdo/pdo_sql_parser.c"
yy8:
++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- switch(yych) {
+ switch (yych) {
case 0x00:
case '"':
case '\'':
@@ -185,34 +170,32 @@
default: goto yy8;
}
yy10:
-#line 63 "ext/pdo/pdo_sql_parser.re"
+#line 64 "ext/pdo/pdo_sql_parser.re"
{ RET(PDO_PARSER_TEXT); }
-#line 191 "ext/pdo/pdo_sql_parser.c"
+#line 176 "ext/pdo/pdo_sql_parser.c"
yy11:
++YYCURSOR;
-#line 64 "ext/pdo/pdo_sql_parser.re"
+#line 65 "ext/pdo/pdo_sql_parser.re"
{ RET(PDO_PARSER_EOI); }
-#line 196 "ext/pdo/pdo_sql_parser.c"
+#line 181 "ext/pdo/pdo_sql_parser.c"
yy13:
++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- switch(yych) {
- case '"':
- case '\'':
+ switch (yych) {
case ':':
case '?': goto yy13;
default: goto yy15;
}
yy15:
-#line 59 "ext/pdo/pdo_sql_parser.re"
+#line 60 "ext/pdo/pdo_sql_parser.re"
{ RET(PDO_PARSER_TEXT); }
-#line 211 "ext/pdo/pdo_sql_parser.c"
+#line 194 "ext/pdo/pdo_sql_parser.c"
yy16:
++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- switch(yych) {
+ switch (yych) {
case '0':
case '1':
case '2':
@@ -279,80 +262,58 @@
default: goto yy18;
}
yy18:
-#line 60 "ext/pdo/pdo_sql_parser.re"
+#line 61 "ext/pdo/pdo_sql_parser.re"
{ RET(PDO_PARSER_BIND); }
-#line 285 "ext/pdo/pdo_sql_parser.c"
+#line 268 "ext/pdo/pdo_sql_parser.c"
yy19:
- if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ ++YYCURSOR;
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- switch(yych) {
- case '"':
- case ':':
- case '?': goto yy19;
- case '\'': goto yy21;
- default: goto yy23;
+yy20:
+ switch (yych) {
+ case 0x00: goto yy21;
+ case '\'': goto yy23;
+ case '\\': goto yy22;
+ default: goto yy19;
}
yy21:
- ++YYCURSOR;
- switch((yych = *YYCURSOR)) {
- case '"':
- case '\'':
- case ':':
- case '?': goto yy13;
- default: goto yy22;
- }
+ YYCURSOR = YYMARKER;
+ goto yy3;
yy22:
-#line 58 "ext/pdo/pdo_sql_parser.re"
- { RET(PDO_PARSER_TEXT); }
-#line 308 "ext/pdo/pdo_sql_parser.c"
-yy23:
++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- switch(yych) {
- case '\'': goto yy25;
- default: goto yy23;
- }
-yy25:
- yych = *++YYCURSOR;
- goto yy22;
-yy26:
+ if (yych <= 0x00) goto yy21;
+ goto yy19;
+yy23:
++YYCURSOR;
- switch((yych = *YYCURSOR)) {
- case '"':
- case '\'':
- case ':':
- case '?': goto yy13;
- default: goto yy27;
- }
-yy27:
-#line 57 "ext/pdo/pdo_sql_parser.re"
+#line 59 "ext/pdo/pdo_sql_parser.re"
{ RET(PDO_PARSER_TEXT); }
-#line 332 "ext/pdo/pdo_sql_parser.c"
-yy28:
- if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
- yych = *YYCURSOR;
- switch(yych) {
- case '"': goto yy26;
- case '\'':
- case ':':
- case '?': goto yy28;
- default: goto yy30;
- }
-yy30:
+#line 293 "ext/pdo/pdo_sql_parser.c"
+yy25:
++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- switch(yych) {
- case '"': goto yy32;
- default: goto yy30;
+yy26:
+ switch (yych) {
+ case 0x00: goto yy21;
+ case '"': goto yy28;
+ case '\\': goto yy27;
+ default: goto yy25;
}
-yy32:
+yy27:
++YYCURSOR;
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- goto yy27;
+ if (yych <= 0x00) goto yy21;
+ goto yy25;
+yy28:
+ ++YYCURSOR;
+#line 58 "ext/pdo/pdo_sql_parser.re"
+ { RET(PDO_PARSER_TEXT); }
+#line 315 "ext/pdo/pdo_sql_parser.c"
}
-#line 65 "ext/pdo/pdo_sql_parser.re"
+#line 66 "ext/pdo/pdo_sql_parser.re"
}
@@ -496,7 +457,7 @@
size_t len;
char *buf = NULL;
- len =
php_stream_copy_to_mem(stm, &buf, PHP_STREAM_COPY_ALL, 0);
+ len =
php_stream_copy_to_mem(stm, (void *)&buf, PHP_STREAM_COPY_ALL, 0);
if
(!stmt->dbh->methods->quoter(stmt->dbh, buf, len, &plc->quoted, &plc->qlen,
param->param_type TSRMLS_CC)) {
/* bork */
http://cvs.php.net/viewvc.cgi/php-src/ext/pdo/pdo_sql_parser.re?r1=1.44&r2=1.45&diff_format=u
Index: php-src/ext/pdo/pdo_sql_parser.re
diff -u php-src/ext/pdo/pdo_sql_parser.re:1.44
php-src/ext/pdo/pdo_sql_parser.re:1.45
--- php-src/ext/pdo/pdo_sql_parser.re:1.44 Sat Mar 22 20:37:08 2008
+++ php-src/ext/pdo/pdo_sql_parser.re Fri Oct 10 12:08:07 2008
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pdo_sql_parser.re,v 1.44 2008/03/22 20:37:08 felipe Exp $ */
+/* $Id: pdo_sql_parser.re,v 1.45 2008/10/10 12:08:07 felipe Exp $ */
#include "php.h"
#include "php_pdo_driver.h"
@@ -49,14 +49,15 @@
BINDCHR = [:][a-zA-Z0-9_]+;
QUESTION = [?];
SPECIALS = [:?"'];
- EOF = [\000];
+ MULTICHAR = [:?];
+ EOF = [\000];
ANYNOEOF = [\001-\377];
*/
/*!re2c
- (["] ([^"])* ["]) { RET(PDO_PARSER_TEXT); }
- (['] ([^'])* [']) { RET(PDO_PARSER_TEXT); }
- SPECIALS{2,}
{ RET(PDO_PARSER_TEXT); }
+ (["](([\\]ANYNOEOF)|ANYNOEOF\["\\])*["]) {
RET(PDO_PARSER_TEXT); }
+ (['](([\\]ANYNOEOF)|ANYNOEOF\['\\])*[']) {
RET(PDO_PARSER_TEXT); }
+ MULTICHAR{2,}
{ RET(PDO_PARSER_TEXT); }
BINDCHR
{ RET(PDO_PARSER_BIND); }
QUESTION
{ RET(PDO_PARSER_BIND_POS); }
SPECIALS
{ SKIP_ONE(PDO_PARSER_TEXT); }
http://cvs.php.net/viewvc.cgi/php-src/ext/pdo_mysql/tests/bug41125.phpt?view=markup&rev=1.1
Index: php-src/ext/pdo_mysql/tests/bug41125.phpt
+++ php-src/ext/pdo_mysql/tests/bug41125.phpt
--TEST--
Bug #41125 (PDO mysql + quote() + prepare() can result in seg fault)
--SKIPIF--
<?php
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
MySQLPDOTest::skip();
?>
--FILE--
<?php
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
$search = "o'";
$sql = "SELECT 1 FROM DUAL WHERE 'o''riley' LIKE " . $db->quote('%' . $search .
'%');
$stmt = $db->prepare($sql);
$stmt->execute();
print implode(' - ', (($r = @$stmt->fetch(PDO::FETCH_NUM)) ? $r : array()))
."\n";
print implode(' - ', $stmt->errorinfo()) ."\n";
print "-------------------------------------------------------\n";
$queries = array(
"SELECT 1 FROM DUAL WHERE 1 = '?\'\''",
"SELECT 'a\\'0' FROM DUAL WHERE 1 = ?",
"SELECT 'a', 'b\'' FROM DUAL WHERE '''' LIKE '\\'' AND ?",
"SELECT 'foo?bar', '', '''' FROM DUAL WHERE ?"
);
foreach ($queries as $k => $query) {
$stmt = $db->prepare($query);
$stmt->execute(array(1));
printf("[%d] Query: [[%s]]\n", $k + 1, $query);
print implode(' - ', (($r = @$stmt->fetch(PDO::FETCH_NUM)) ? $r :
array())) ."\n";
print implode(' - ', $stmt->errorinfo()) ."\n";
print "--------\n";
}
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
$sql = "SELECT upper(:id) FROM DUAL WHERE '1'";
$stmt = $db->prepare($sql);
$id = 'o\'\0';
$stmt->bindParam(':id', $id);
$stmt->execute();
printf("Query: [[%s]]\n", $sql);
print implode(' - ', (($r = @$stmt->fetch(PDO::FETCH_NUM)) ? $r : array()))
."\n";
print implode(' - ', $stmt->errorinfo()) ."\n";
print "-------------------------------------------------------\n";
$queries = array(
"SELECT 1, 'foo' FROM DUAL WHERE 1 = :id AND '\\0' IS NULL AND 2 <>
:id",
"SELECT 1 FROM DUAL WHERE 1 = :id AND '' AND 2 <> :id",
"SELECT 1 FROM DUAL WHERE 1 = :id AND '\'\'' = '''' AND 2 <> :id",
"SELECT 1 FROM DUAL WHERE 1 = :id AND '\'' = '''' AND 2 <> :id",
"SELECT 'a', 'b\'' FROM DUAL WHERE '''' LIKE '\\'' AND 1",
"SELECT 'a''', '\'b\'' FROM DUAL WHERE '''' LIKE '\\'' AND 1",
"SELECT UPPER(:id) FROM DUAL WHERE '1'",
"SELECT 1 FROM DUAL WHERE '\''",
"SELECT 1 FROM DUAL WHERE :id AND '\\0' OR :id",
"SELECT 1 FROM DUAL WHERE 'a\\f\\n\\0' AND 1 >= :id",
"SELECT 1 FROM DUAL WHERE '\'' = ''''",
"SELECT '\\n' '1 FROM DUAL WHERE '''' and :id'",
"SELECT 1 'FROM DUAL WHERE :id AND '''' = '''' OR 1 = 1 AND ':id",
);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1);
$id = 1;
foreach ($queries as $k => $query) {
$stmt = $db->prepare($query);
$stmt->bindParam(':id', $id);
$stmt->execute();
printf("[%d] Query: [[%s]]\n", $k + 1, $query);
print implode(' - ', (($r = @$stmt->fetch(PDO::FETCH_NUM)) ? $r :
array())) ."\n";
print implode(' - ', $stmt->errorinfo()) ."\n";
print "--------\n";
}
?>
--EXPECT--
1
00000
-------------------------------------------------------
[1] Query: [[SELECT 1 FROM DUAL WHERE 1 = '?\'\'']]
00000
--------
[2] Query: [[SELECT 'a\'0' FROM DUAL WHERE 1 = ?]]
a'0
00000
--------
[3] Query: [[SELECT 'a', 'b\'' FROM DUAL WHERE '''' LIKE '\'' AND ?]]
a - b'
00000
--------
[4] Query: [[SELECT 'foo?bar', '', '''' FROM DUAL WHERE ?]]
foo?bar - - '
00000
--------
Query: [[SELECT upper(:id) FROM DUAL WHERE '1']]
O'\0
00000
-------------------------------------------------------
[1] Query: [[SELECT 1, 'foo' FROM DUAL WHERE 1 = :id AND '\0' IS NULL AND 2 <>
:id]]
00000
--------
[2] Query: [[SELECT 1 FROM DUAL WHERE 1 = :id AND '' AND 2 <> :id]]
00000
--------
[3] Query: [[SELECT 1 FROM DUAL WHERE 1 = :id AND '\'\'' = '''' AND 2 <> :id]]
00000
--------
[4] Query: [[SELECT 1 FROM DUAL WHERE 1 = :id AND '\'' = '''' AND 2 <> :id]]
1
00000
--------
[5] Query: [[SELECT 'a', 'b\'' FROM DUAL WHERE '''' LIKE '\'' AND 1]]
a - b'
00000
--------
[6] Query: [[SELECT 'a''', '\'b\'' FROM DUAL WHERE '''' LIKE '\'' AND 1]]
a' - 'b'
00000
--------
[7] Query: [[SELECT UPPER(:id) FROM DUAL WHERE '1']]
1
00000
--------
[8] Query: [[SELECT 1 FROM DUAL WHERE '\'']]
00000
--------
[9] Query: [[SELECT 1 FROM DUAL WHERE :id AND '\0' OR :id]]
1
00000
--------
[10] Query: [[SELECT 1 FROM DUAL WHERE 'a\f\n\0' AND 1 >= :id]]
00000
--------
[11] Query: [[SELECT 1 FROM DUAL WHERE '\'' = '''']]
1
00000
--------
[12] Query: [[SELECT '\n' '1 FROM DUAL WHERE '''' and :id']]
1 FROM DUAL WHERE '' and :id
00000
--------
[13] Query: [[SELECT 1 'FROM DUAL WHERE :id AND '''' = '''' OR 1 = 1 AND ':id]]
1
00000
--------
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php