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