]> granicus.if.org Git - php/commitdiff
Support ? as a bind in emulated prepares
authorGeorge Schlossnagle <gschlossnagle@php.net>
Thu, 20 May 2004 17:56:09 +0000 (17:56 +0000)
committerGeorge Schlossnagle <gschlossnagle@php.net>
Thu, 20 May 2004 17:56:09 +0000 (17:56 +0000)
Throw informative error when pdo_parse_param fails

ext/pdo/pdo_sql_parser.re
ext/pdo/pdo_stmt.c

index 654d41dc49d4dd434822999942e5ebf9a551d426..87427131b2b7aaca1dc5e2d0643a0b8ada92c587 100644 (file)
@@ -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 **)&param)) 
+                       {
+                               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), &quotedstr, &quotedstrlen 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;
 }
 
 /*
index dce37366958b46637f080d159bc130bf971338c4..b6aefbfc41fd748c0b44063026cb1772fb7ce285 100755 (executable)
@@ -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)) {