From 1b78aef426a8f413ddd70854eb3fd5fbc95ef675 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Johannes=20Schl=C3=BCter?= Date: Thu, 19 Apr 2012 12:46:02 +0200 Subject: [PATCH] Fix bug #61755 parsing bug can lead to access violations --- NEWS | 5 +++- ext/pdo/pdo_sql_parser.re | 9 +++---- ext/pdo_mysql/tests/bug_61755.phpt | 41 ++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 ext/pdo_mysql/tests/bug_61755.phpt diff --git a/NEWS b/NEWS index 0cabd9748d..5fe7245b19 100644 --- a/NEWS +++ b/NEWS @@ -6,7 +6,10 @@ PHP NEWS . Fixed bug #61537 (json_encode() incorrectly truncates/discards information). (Adam) -?? ??? 2012, PHP 5.3.11 +- PDO: + . Fixed bug #61755 (A parsing bug in the prepared statements can lead to + access violations). (Johannes) + - Iconv extension: . Fixed a bug that iconv extension fails to link to the correct library when another extension makes use of a library that links to the iconv diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re index 8becef9b63..88f94001f9 100644 --- a/ext/pdo/pdo_sql_parser.re +++ b/ext/pdo/pdo_sql_parser.re @@ -32,12 +32,12 @@ #define YYCTYPE unsigned char #define YYCURSOR cursor -#define YYLIMIT cursor +#define YYLIMIT s->end #define YYMARKER s->ptr -#define YYFILL(n) +#define YYFILL(n) { RET(PDO_PARSER_EOI); } typedef struct Scanner { - char *ptr, *cur, *tok; + char *ptr, *cur, *tok, *end; } Scanner; static int scan(Scanner *s) @@ -51,7 +51,6 @@ static int scan(Scanner *s) COMMENTS = ("/*"([^*]+|[*]+[^/*])*[*]*"*/"|"--"[^\r\n]*); SPECIALS = [:?"']; MULTICHAR = [:?]; - EOF = [\000]; ANYNOEOF = [\001-\377]; */ @@ -64,7 +63,6 @@ static int scan(Scanner *s) SPECIALS { SKIP_ONE(PDO_PARSER_TEXT); } COMMENTS { RET(PDO_PARSER_TEXT); } (ANYNOEOF\SPECIALS)+ { RET(PDO_PARSER_TEXT); } - EOF { RET(PDO_PARSER_EOI); } */ } @@ -94,6 +92,7 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, ptr = *outquery; s.cur = inquery; + s.end = inquery + inquery_len + 1; /* phase 1: look for args */ while((t = scan(&s)) != PDO_PARSER_EOI) { diff --git a/ext/pdo_mysql/tests/bug_61755.phpt b/ext/pdo_mysql/tests/bug_61755.phpt new file mode 100644 index 0000000000..1d2b96805a --- /dev/null +++ b/ext/pdo_mysql/tests/bug_61755.phpt @@ -0,0 +1,41 @@ +--TEST-- +Bug #61755 (A parsing bug in the prepared statements can lead to access violations) +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +echo "NULL-Byte before first placeholder:\n"; +$s = $db->prepare("SELECT \"a\0b\", ?"); +$s->bindValue(1,"c"); +$s->execute(); +$r = $s->fetch(); +echo "Length of item 0: ".strlen($r[0]).", Value of item 1: ".$r[1]."\n"; + +echo "\nOpen comment:\n"; +try { + $s = $db->prepare("SELECT /*"); + $s->execute(); +} catch (Exception $e) { + echo "Error code: ".$e->getCode()."\n"; +} + +echo "\ndone!\n"; +?> +--EXPECTF-- +NULL-Byte before first placeholder: +Length of item 0: 3, Value of item 1: c + +Open comment: +Error code: 42000 + +done! -- 2.40.0