From d16625b80305244ae53de992c332a15e56871dbd Mon Sep 17 00:00:00 2001 From: George Schlossnagle Date: Thu, 20 May 2004 17:56:09 +0000 Subject: [PATCH] Support ? as a bind in emulated prepares Throw informative error when pdo_parse_param fails --- ext/pdo/pdo_sql_parser.re | 49 ++++++++++++++++++++++++++++++++++----- ext/pdo/pdo_stmt.c | 6 +++-- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re index 654d41dc49..87427131b2 100644 --- a/ext/pdo/pdo_sql_parser.re +++ b/ext/pdo/pdo_sql_parser.re @@ -23,7 +23,8 @@ #define PDO_PARSER_TEXT 1 #define PDO_PARSER_BIND 2 -#define PDO_PARSER_EOI 3 +#define PDO_PARSER_BIND_POS 3 +#define PDO_PARSER_EOI 4 #define RET(i) {s->cur = cursor; return i; } @@ -44,7 +45,8 @@ static int scan(Scanner *s) s->tok = cursor; /*!re2c BINDCHR = [:][a-zA-Z0-9_]+; - SPECIALS = [:"]; + QUESTION = [?]; + SPECIALS = [:?"]; ESC = [\\]["]; EOF = [\000]; ANYNOEOF = [\001-\377]; @@ -53,6 +55,7 @@ static int scan(Scanner *s) /*!re2c (["] (ESC|ANYNOEOF\[\\"])* ["]) { RET(PDO_PARSER_TEXT); } BINDCHR { RET(PDO_PARSER_BIND); } + QUESTION { RET(PDO_PARSER_BIND_POS); } SPECIALS { RET(PDO_PARSER_TEXT); } (ANYNOEOF\SPECIALS)+ { RET(PDO_PARSER_TEXT); } EOF { RET(PDO_PARSER_EOI); } @@ -111,7 +114,7 @@ int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **ou if(!params) { /* error */ efree(*outquery); - return 0; + return (int) (s.cur - inquery); } /* lookup bind first via hash and then index */ /* stupid keys need to be null-terminated, even though we know their length */ @@ -144,13 +147,47 @@ int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **ou else { /* error and cleanup */ efree(*outquery); - return 0; + return (int) (s.cur - inquery); } bindno++; - } + } + else if(t == PDO_PARSER_BIND_POS) { + if(!params) { + /* error */ + efree(*outquery); + return (int) (s.cur - inquery); + } + /* lookup bind by index */ + if(SUCCESS == zend_hash_index_find(params, bindno, (void **)¶m)) + { + char *quotedstr; + int quotedstrlen; + /* currently everything is a string here */ + + /* quote the bind value if necessary */ + if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter), + Z_STRLEN_P(param->parameter), "edstr, "edstrlen TSRMLS_CC)) + { + memcpy(ptr, quotedstr, quotedstrlen); + ptr += quotedstrlen; + *outquery_len += quotedstrlen; + efree(quotedstr); + } else { + memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter)); + ptr += Z_STRLEN_P(param->parameter); + *outquery_len += (Z_STRLEN_P(param->parameter)); + } + } + else { + /* error and cleanup */ + efree(*outquery); + return (int) (s.cur - inquery); + } + bindno++; + } } *ptr = '\0'; - return 1; + return 0; } /* diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index dce3736695..b6aefbfc41 100755 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -278,13 +278,15 @@ static PHP_METHOD(PDOStatement, execute) } if (stmt->dbh->emulate_prepare) { + int error_pos; /* handle the emulated parameter binding, * stmt->active_query_string holds the query with binds expanded and * quoted. */ - if(pdo_parse_params(stmt, stmt->query_string, stmt->query_stringlen, - &stmt->active_query_string, &stmt->active_query_stringlen) == 0) { + if((error_pos = pdo_parse_params(stmt, stmt->query_string, stmt->query_stringlen, + &stmt->active_query_string, &stmt->active_query_stringlen)) != 0) { // parse error in handling the query + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error emulating placeholder binding in query at %.*s....", error_pos, stmt->query_string); RETURN_FALSE; } } else if (!dispatch_param_event(stmt, PDO_PARAM_EVT_EXEC_PRE TSRMLS_CC)) { -- 2.40.0