PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - lcov_data/ext/pdo - pdo_sql_parser.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 88 132 66.7 %
Date: 2014-04-18 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Generated by re2c 0.13.5 on Thu Apr 19 12:42:11 2012 */
       2             : #line 1 "ext/pdo/pdo_sql_parser.re"
       3             : /*
       4             :   +----------------------------------------------------------------------+
       5             :   | PHP Version 5                                                        |
       6             :   +----------------------------------------------------------------------+
       7             :   | Copyright (c) 1997-2013 The PHP Group                                |
       8             :   +----------------------------------------------------------------------+
       9             :   | This source file is subject to version 3.01 of the PHP license,      |
      10             :   | that is bundled with this package in the file LICENSE, and is        |
      11             :   | available through the world-wide-web at the following url:           |
      12             :   | http://www.php.net/license/3_01.txt                                  |
      13             :   | If you did not receive a copy of the PHP license and are unable to   |
      14             :   | obtain it through the world-wide-web, please send a note to          |
      15             :   | license@php.net so we can mail you a copy immediately.               |
      16             :   +----------------------------------------------------------------------+
      17             :   | Author: George Schlossnagle <george@omniti.com>                      |
      18             :   +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : /* $Id$ */
      22             : 
      23             : #include "php.h"
      24             : #include "php_pdo_driver.h"
      25             : #include "php_pdo_int.h"
      26             : 
      27             : #define PDO_PARSER_TEXT 1
      28             : #define PDO_PARSER_BIND 2
      29             : #define PDO_PARSER_BIND_POS 3
      30             : #define PDO_PARSER_EOI 4
      31             : 
      32             : #define RET(i) {s->cur = cursor; return i; }
      33             : #define SKIP_ONE(i) {s->cur = s->tok + 1; return i; }
      34             : 
      35             : #define YYCTYPE         unsigned char
      36             : #define YYCURSOR        cursor
      37             : #define YYLIMIT         s->end
      38             : #define YYMARKER        s->ptr
      39             : #define YYFILL(n)               { RET(PDO_PARSER_EOI); }
      40             : 
      41             : typedef struct Scanner {
      42             :         char    *ptr, *cur, *tok, *end;
      43             : } Scanner;
      44             : 
      45             : static int scan(Scanner *s) 
      46             : {
      47             :         char *cursor = s->cur;
      48             : 
      49             :         s->tok = cursor;
      50             :         #line 55 "ext/pdo/pdo_sql_parser.re"
      51             : 
      52             : 
      53             :         
      54             : #line 55 "ext/pdo/pdo_sql_parser.c"
      55             : {
      56             :         YYCTYPE yych;
      57        6833 :         unsigned int yyaccept = 0;
      58             : 
      59        6833 :         if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
      60        4712 :         yych = *YYCURSOR;
      61        4712 :         switch (yych) {
      62           1 :         case 0x00:      goto yy2;
      63          11 :         case '"':  goto yy3;
      64         203 :         case '\'':      goto yy5;
      65           2 :         case '-':       goto yy11;
      66           7 :         case '/':       goto yy9;
      67         488 :         case ':':       goto yy6;
      68         883 :         case '?':       goto yy7;
      69        3117 :         default:        goto yy12;
      70             :         }
      71             : yy2:
      72          12 :         YYCURSOR = YYMARKER;
      73          12 :         switch (yyaccept) {
      74          12 :         case 0:         goto yy4;
      75           0 :         case 1:         goto yy10;
      76             :         }
      77             : yy3:
      78          11 :         yyaccept = 0;
      79          11 :         yych = *(YYMARKER = ++YYCURSOR);
      80          11 :         if (yych >= 0x01) goto yy41;
      81             : yy4:
      82             : #line 63 "ext/pdo/pdo_sql_parser.re"
      83             :         { SKIP_ONE(PDO_PARSER_TEXT); }
      84             : #line 85 "ext/pdo/pdo_sql_parser.c"
      85             : yy5:
      86         203 :         yyaccept = 0;
      87         203 :         yych = *(YYMARKER = ++YYCURSOR);
      88         203 :         if (yych <= 0x00) goto yy4;
      89         203 :         goto yy36;
      90             : yy6:
      91         488 :         yych = *++YYCURSOR;
      92         488 :         switch (yych) {
      93             :         case '0':
      94             :         case '1':
      95             :         case '2':
      96             :         case '3':
      97             :         case '4':
      98             :         case '5':
      99             :         case '6':
     100             :         case '7':
     101             :         case '8':
     102             :         case '9':
     103             :         case 'A':
     104             :         case 'B':
     105             :         case 'C':
     106             :         case 'D':
     107             :         case 'E':
     108             :         case 'F':
     109             :         case 'G':
     110             :         case 'H':
     111             :         case 'I':
     112             :         case 'J':
     113             :         case 'K':
     114             :         case 'L':
     115             :         case 'M':
     116             :         case 'N':
     117             :         case 'O':
     118             :         case 'P':
     119             :         case 'Q':
     120             :         case 'R':
     121             :         case 'S':
     122             :         case 'T':
     123             :         case 'U':
     124             :         case 'V':
     125             :         case 'W':
     126             :         case 'X':
     127             :         case 'Y':
     128             :         case 'Z':
     129             :         case '_':
     130             :         case 'a':
     131             :         case 'b':
     132             :         case 'c':
     133             :         case 'd':
     134             :         case 'e':
     135             :         case 'f':
     136             :         case 'g':
     137             :         case 'h':
     138             :         case 'i':
     139             :         case 'j':
     140             :         case 'k':
     141             :         case 'l':
     142             :         case 'm':
     143             :         case 'n':
     144             :         case 'o':
     145             :         case 'p':
     146             :         case 'q':
     147             :         case 'r':
     148             :         case 's':
     149             :         case 't':
     150             :         case 'u':
     151             :         case 'v':
     152             :         case 'w':
     153             :         case 'x':
     154             :         case 'y':
     155         488 :         case 'z':       goto yy32;
     156             :         case ':':
     157           0 :         case '?':       goto yy29;
     158           0 :         default:        goto yy4;
     159             :         }
     160             : yy7:
     161         883 :         ++YYCURSOR;
     162         883 :         switch ((yych = *YYCURSOR)) {
     163             :         case ':':
     164           0 :         case '?':       goto yy29;
     165             :         default:        goto yy8;
     166             :         }
     167             : yy8:
     168             : #line 62 "ext/pdo/pdo_sql_parser.re"
     169             :         { RET(PDO_PARSER_BIND_POS); }
     170             : #line 171 "ext/pdo/pdo_sql_parser.c"
     171             : yy9:
     172           7 :         ++YYCURSOR;
     173           7 :         switch ((yych = *YYCURSOR)) {
     174           7 :         case '*':       goto yy19;
     175           0 :         default:        goto yy13;
     176             :         }
     177             : yy10:
     178             : #line 65 "ext/pdo/pdo_sql_parser.re"
     179             :         { RET(PDO_PARSER_TEXT); }
     180             : #line 181 "ext/pdo/pdo_sql_parser.c"
     181             : yy11:
     182           2 :         yych = *++YYCURSOR;
     183           2 :         switch (yych) {
     184           0 :         case '-':       goto yy14;
     185           2 :         default:        goto yy13;
     186             :         }
     187             : yy12:
     188       77341 :         ++YYCURSOR;
     189       77341 :         if (YYLIMIT <= YYCURSOR) YYFILL(1);
     190       77341 :         yych = *YYCURSOR;
     191             : yy13:
     192       77343 :         switch (yych) {
     193             :         case 0x00:
     194             :         case '"':
     195             :         case '\'':
     196             :         case ':':
     197        3119 :         case '?':       goto yy10;
     198       74224 :         default:        goto yy12;
     199             :         }
     200             : yy14:
     201           0 :         ++YYCURSOR;
     202           0 :         if (YYLIMIT <= YYCURSOR) YYFILL(1);
     203           0 :         yych = *YYCURSOR;
     204           0 :         switch (yych) {
     205             :         case 0x00:
     206             :         case '"':
     207             :         case '\'':
     208             :         case ':':
     209           0 :         case '?':       goto yy17;
     210             :         case '\n':
     211           0 :         case '\r':      goto yy12;
     212           0 :         default:        goto yy14;
     213             :         }
     214             : yy16:
     215             : #line 64 "ext/pdo/pdo_sql_parser.re"
     216             :         { RET(PDO_PARSER_TEXT); }
     217             : #line 218 "ext/pdo/pdo_sql_parser.c"
     218             : yy17:
     219           0 :         ++YYCURSOR;
     220           0 :         if (YYLIMIT <= YYCURSOR) YYFILL(1);
     221           0 :         yych = *YYCURSOR;
     222           0 :         switch (yych) {
     223             :         case '\n':
     224           0 :         case '\r':      goto yy16;
     225           0 :         default:        goto yy17;
     226             :         }
     227             : yy19:
     228          11 :         yyaccept = 1;
     229          11 :         YYMARKER = ++YYCURSOR;
     230          11 :         if (YYLIMIT <= YYCURSOR) YYFILL(1);
     231          11 :         yych = *YYCURSOR;
     232          11 :         switch (yych) {
     233             :         case 0x00:
     234             :         case '"':
     235             :         case '\'':
     236             :         case ':':
     237           7 :         case '?':       goto yy21;
     238           0 :         case '*':       goto yy23;
     239           4 :         default:        goto yy19;
     240             :         }
     241             : yy21:
     242          21 :         ++YYCURSOR;
     243          21 :         if (YYLIMIT <= YYCURSOR) YYFILL(1);
     244          21 :         yych = *YYCURSOR;
     245          21 :         switch (yych) {
     246          11 :         case '*':       goto yy26;
     247          10 :         default:        goto yy21;
     248             :         }
     249             : yy23:
     250           0 :         yyaccept = 1;
     251           0 :         YYMARKER = ++YYCURSOR;
     252           0 :         if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
     253           0 :         yych = *YYCURSOR;
     254           0 :         switch (yych) {
     255             :         case 0x00:
     256             :         case '"':
     257             :         case '\'':
     258             :         case ':':
     259           0 :         case '?':       goto yy21;
     260           0 :         case '*':       goto yy23;
     261           0 :         case '/':       goto yy25;
     262           0 :         default:        goto yy19;
     263             :         }
     264             : yy25:
     265           0 :         yych = *++YYCURSOR;
     266           0 :         switch (yych) {
     267             :         case 0x00:
     268             :         case '"':
     269             :         case '\'':
     270             :         case ':':
     271           0 :         case '?':       goto yy16;
     272           0 :         default:        goto yy12;
     273             :         }
     274             : yy26:
     275          26 :         ++YYCURSOR;
     276          26 :         if (YYLIMIT <= YYCURSOR) YYFILL(1);
     277          26 :         yych = *YYCURSOR;
     278          26 :         switch (yych) {
     279          15 :         case '*':       goto yy26;
     280           7 :         case '/':       goto yy28;
     281           4 :         default:        goto yy21;
     282             :         }
     283             : yy28:
     284           7 :         yych = *++YYCURSOR;
     285           7 :         goto yy16;
     286             : yy29:
     287           0 :         ++YYCURSOR;
     288           0 :         if (YYLIMIT <= YYCURSOR) YYFILL(1);
     289           0 :         yych = *YYCURSOR;
     290           0 :         switch (yych) {
     291             :         case ':':
     292           0 :         case '?':       goto yy29;
     293             :         default:        goto yy31;
     294             :         }
     295             : yy31:
     296             : #line 60 "ext/pdo/pdo_sql_parser.re"
     297             :         { RET(PDO_PARSER_TEXT); }
     298             : #line 299 "ext/pdo/pdo_sql_parser.c"
     299             : yy32:
     300        3643 :         ++YYCURSOR;
     301        3643 :         if (YYLIMIT <= YYCURSOR) YYFILL(1);
     302        3643 :         yych = *YYCURSOR;
     303        3643 :         switch (yych) {
     304             :         case '0':
     305             :         case '1':
     306             :         case '2':
     307             :         case '3':
     308             :         case '4':
     309             :         case '5':
     310             :         case '6':
     311             :         case '7':
     312             :         case '8':
     313             :         case '9':
     314             :         case 'A':
     315             :         case 'B':
     316             :         case 'C':
     317             :         case 'D':
     318             :         case 'E':
     319             :         case 'F':
     320             :         case 'G':
     321             :         case 'H':
     322             :         case 'I':
     323             :         case 'J':
     324             :         case 'K':
     325             :         case 'L':
     326             :         case 'M':
     327             :         case 'N':
     328             :         case 'O':
     329             :         case 'P':
     330             :         case 'Q':
     331             :         case 'R':
     332             :         case 'S':
     333             :         case 'T':
     334             :         case 'U':
     335             :         case 'V':
     336             :         case 'W':
     337             :         case 'X':
     338             :         case 'Y':
     339             :         case 'Z':
     340             :         case '_':
     341             :         case 'a':
     342             :         case 'b':
     343             :         case 'c':
     344             :         case 'd':
     345             :         case 'e':
     346             :         case 'f':
     347             :         case 'g':
     348             :         case 'h':
     349             :         case 'i':
     350             :         case 'j':
     351             :         case 'k':
     352             :         case 'l':
     353             :         case 'm':
     354             :         case 'n':
     355             :         case 'o':
     356             :         case 'p':
     357             :         case 'q':
     358             :         case 'r':
     359             :         case 's':
     360             :         case 't':
     361             :         case 'u':
     362             :         case 'v':
     363             :         case 'w':
     364             :         case 'x':
     365             :         case 'y':
     366        3155 :         case 'z':       goto yy32;
     367             :         default:        goto yy34;
     368             :         }
     369             : yy34:
     370             : #line 61 "ext/pdo/pdo_sql_parser.re"
     371             :         { RET(PDO_PARSER_BIND); }
     372             : #line 373 "ext/pdo/pdo_sql_parser.c"
     373             : yy35:
     374         873 :         ++YYCURSOR;
     375         873 :         if (YYLIMIT <= YYCURSOR) YYFILL(1);
     376         873 :         yych = *YYCURSOR;
     377             : yy36:
     378        1076 :         switch (yych) {
     379           8 :         case 0x00:      goto yy2;
     380         195 :         case '\'':      goto yy38;
     381          27 :         case '\\':      goto yy37;
     382         846 :         default:        goto yy35;
     383             :         }
     384             : yy37:
     385          27 :         ++YYCURSOR;
     386          27 :         if (YYLIMIT <= YYCURSOR) YYFILL(1);
     387          27 :         yych = *YYCURSOR;
     388          27 :         if (yych <= 0x00) goto yy2;
     389          27 :         goto yy35;
     390             : yy38:
     391         195 :         ++YYCURSOR;
     392             : #line 59 "ext/pdo/pdo_sql_parser.re"
     393             :         { RET(PDO_PARSER_TEXT); }
     394             : #line 395 "ext/pdo/pdo_sql_parser.c"
     395             : yy40:
     396          62 :         ++YYCURSOR;
     397          62 :         if (YYLIMIT <= YYCURSOR) YYFILL(1);
     398          62 :         yych = *YYCURSOR;
     399             : yy41:
     400          73 :         switch (yych) {
     401           3 :         case 0x00:      goto yy2;
     402           8 :         case '"':  goto yy43;
     403           0 :         case '\\':      goto yy42;
     404          62 :         default:        goto yy40;
     405             :         }
     406             : yy42:
     407           0 :         ++YYCURSOR;
     408           0 :         if (YYLIMIT <= YYCURSOR) YYFILL(1);
     409           0 :         yych = *YYCURSOR;
     410           0 :         if (yych <= 0x00) goto yy2;
     411           0 :         goto yy40;
     412             : yy43:
     413           8 :         ++YYCURSOR;
     414             : #line 58 "ext/pdo/pdo_sql_parser.re"
     415             :         { RET(PDO_PARSER_TEXT); }
     416             : #line 417 "ext/pdo/pdo_sql_parser.c"
     417             : }
     418             : #line 66 "ext/pdo/pdo_sql_parser.re"
     419             :         
     420             : }
     421             : 
     422             : struct placeholder {
     423             :         char *pos;
     424             :         int len;
     425             :         int bindno;
     426             :         int qlen;               /* quoted length of value */
     427             :         char *quoted;   /* quoted value */
     428             :         int freeq;
     429             :         struct placeholder *next;
     430             : };
     431             : 
     432             : PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, 
     433             :         char **outquery, int *outquery_len TSRMLS_DC)
     434             : {
     435             :         Scanner s;
     436             :         char *ptr, *newbuffer;
     437             :         int t;
     438             :         int bindno = 0;
     439             :         int ret = 0;
     440             :         int newbuffer_len;
     441             :         HashTable *params;
     442             :         struct pdo_bound_param_data *param;
     443             :         int query_type = PDO_PLACEHOLDER_NONE;
     444             :         struct placeholder *placeholders = NULL, *placetail = NULL, *plc = NULL;
     445             : 
     446             :         ptr = *outquery;
     447             :         s.cur = inquery;
     448             :         s.end = inquery + inquery_len + 1;
     449             : 
     450             :         /* phase 1: look for args */
     451             :         while((t = scan(&s)) != PDO_PARSER_EOI) {
     452             :                 if (t == PDO_PARSER_BIND || t == PDO_PARSER_BIND_POS) {
     453             :                         if (t == PDO_PARSER_BIND) {
     454             :                                 int len = s.cur - s.tok;
     455             :                                 if ((inquery < (s.cur - len)) && isalnum(*(s.cur - len - 1))) {
     456             :                                         continue;
     457             :                                 }
     458             :                                 query_type |= PDO_PLACEHOLDER_NAMED;
     459             :                         } else {
     460             :                                 query_type |= PDO_PLACEHOLDER_POSITIONAL;
     461             :                         }
     462             : 
     463             :                         plc = emalloc(sizeof(*plc));
     464             :                         memset(plc, 0, sizeof(*plc));
     465             :                         plc->next = NULL;
     466             :                         plc->pos = s.tok;
     467             :                         plc->len = s.cur - s.tok;
     468             :                         plc->bindno = bindno++;
     469             : 
     470             :                         if (placetail) {
     471             :                                 placetail->next = plc;
     472             :                         } else {
     473             :                                 placeholders = plc;
     474             :                         }
     475             :                         placetail = plc;
     476             :                 }
     477             :         }
     478             : 
     479             :         if (bindno == 0) {
     480             :                 /* nothing to do; good! */
     481             :                 return 0;
     482             :         }
     483             : 
     484             :         /* did the query make sense to me? */
     485             :         if (query_type == (PDO_PLACEHOLDER_NAMED|PDO_PLACEHOLDER_POSITIONAL)) {
     486             :                 /* they mixed both types; punt */
     487             :                 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "mixed named and positional parameters" TSRMLS_CC);
     488             :                 ret = -1;
     489             :                 goto clean_up;
     490             :         }
     491             : 
     492             :         if (stmt->supports_placeholders == query_type && !stmt->named_rewrite_template) {
     493             :                 /* query matches native syntax */
     494             :                 ret = 0;
     495             :                 goto clean_up;
     496             :         }
     497             : 
     498             :         if (stmt->named_rewrite_template) {
     499             :                 /* magic/hack.
     500             :                  * We we pretend that the query was positional even if
     501             :                  * it was named so that we fall into the
     502             :                  * named rewrite case below.  Not too pretty,
     503             :                  * but it works. */
     504             :                 query_type = PDO_PLACEHOLDER_POSITIONAL;
     505             :         }
     506             :         
     507             :         params = stmt->bound_params;
     508             :         
     509             :         /* Do we have placeholders but no bound params */
     510             :         if (bindno && !params && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
     511             :                 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "no parameters were bound" TSRMLS_CC);
     512             :                 ret = -1;
     513             :                 goto clean_up;
     514             :         }
     515             : 
     516             :         if (params && bindno != zend_hash_num_elements(params) && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
     517             :                 /* extra bit of validation for instances when same params are bound more then once */
     518             :                 if (query_type != PDO_PLACEHOLDER_POSITIONAL && bindno > zend_hash_num_elements(params)) {
     519             :                         int ok = 1;
     520             :                         for (plc = placeholders; plc; plc = plc->next) {
     521             :                                 if (zend_hash_find(params, plc->pos, plc->len, (void**) &param) == FAILURE) {
     522             :                                         ok = 0;
     523             :                                         break;
     524             :                                 }
     525             :                         }
     526             :                         if (ok) {
     527             :                                 goto safe;
     528             :                         }
     529             :                 }
     530             :                 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "number of bound variables does not match number of tokens" TSRMLS_CC);
     531             :                 ret = -1;
     532             :                 goto clean_up;
     533             :         }
     534             : safe:
     535             :         /* what are we going to do ? */
     536             :         if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
     537             :                 /* query generation */
     538             : 
     539             :                 newbuffer_len = inquery_len;
     540             : 
     541             :                 /* let's quote all the values */        
     542             :                 for (plc = placeholders; plc; plc = plc->next) {
     543             :                         if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
     544             :                                 ret = zend_hash_index_find(params, plc->bindno, (void**) &param);
     545             :                         } else {
     546             :                                 ret = zend_hash_find(params, plc->pos, plc->len, (void**) &param);
     547             :                         }
     548             :                         if (ret == FAILURE) {
     549             :                                 /* parameter was not defined */
     550             :                                 ret = -1;
     551             :                                 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined" TSRMLS_CC);
     552             :                                 goto clean_up;
     553             :                         }
     554             :                         if (stmt->dbh->methods->quoter) {
     555             :                                 if (param->param_type == PDO_PARAM_LOB && Z_TYPE_P(param->parameter) == IS_RESOURCE) {
     556             :                                         php_stream *stm;
     557             : 
     558             :                                         php_stream_from_zval_no_verify(stm, &param->parameter);
     559             :                                         if (stm) {
     560             :                                                 size_t len;
     561             :                                                 char *buf = NULL;
     562             :                                         
     563             :                                                 len = php_stream_copy_to_mem(stm, &buf, PHP_STREAM_COPY_ALL, 0);
     564             :                                                 if (!stmt->dbh->methods->quoter(stmt->dbh, buf, len, &plc->quoted, &plc->qlen,
     565             :                                                                 param->param_type TSRMLS_CC)) {
     566             :                                                         /* bork */
     567             :                                                         ret = -1;
     568             :                                                         strncpy(stmt->error_code, stmt->dbh->error_code, 6);
     569             :                                                         if (buf) {
     570             :                                                                 efree(buf);
     571             :                                                         }
     572             :                                                         goto clean_up;
     573             :                                                 }
     574             :                                                 if (buf) {
     575             :                                                         efree(buf);
     576             :                                                 }
     577             :                                         } else {
     578             :                                                 pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource" TSRMLS_CC);
     579             :                                                 ret = -1;
     580             :                                                 goto clean_up;
     581             :                                         }
     582             :                                         plc->freeq = 1;
     583             :                                 } else {
     584             :                                         switch (Z_TYPE_P(param->parameter)) {
     585             :                                                 case IS_NULL:
     586             :                                                         plc->quoted = "NULL";
     587             :                                                         plc->qlen = sizeof("NULL")-1;
     588             :                                                         plc->freeq = 0;
     589             :                                                         break;
     590             : 
     591             :                                                 case IS_BOOL:
     592             :                                                         convert_to_long(param->parameter);
     593             : 
     594             :                                                 case IS_LONG:
     595             :                                                 case IS_DOUBLE:
     596             :                                                         convert_to_string(param->parameter);
     597             :                                                         plc->qlen = Z_STRLEN_P(param->parameter);
     598             :                                                         plc->quoted = Z_STRVAL_P(param->parameter);
     599             :                                                         plc->freeq = 0;
     600             :                                                         break;
     601             : 
     602             :                                                 default:
     603             :                                                         convert_to_string(param->parameter);
     604             :                                                         if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
     605             :                                                                         Z_STRLEN_P(param->parameter), &plc->quoted, &plc->qlen,
     606             :                                                                         param->param_type TSRMLS_CC)) {
     607             :                                                                 /* bork */
     608             :                                                                 ret = -1;
     609             :                                                                 strncpy(stmt->error_code, stmt->dbh->error_code, 6);
     610             :                                                                 goto clean_up;
     611             :                                                         }
     612             :                                                         plc->freeq = 1;
     613             :                                         }
     614             :                                 }
     615             :                         } else {
     616             :                                 plc->quoted = Z_STRVAL_P(param->parameter);
     617             :                                 plc->qlen = Z_STRLEN_P(param->parameter);
     618             :                         }
     619             :                         newbuffer_len += plc->qlen;
     620             :                 }
     621             : 
     622             : rewrite:
     623             :                 /* allocate output buffer */
     624             :                 newbuffer = emalloc(newbuffer_len + 1);
     625             :                 *outquery = newbuffer;
     626             : 
     627             :                 /* and build the query */
     628             :                 plc = placeholders;
     629             :                 ptr = inquery;
     630             : 
     631             :                 do {
     632             :                         t = plc->pos - ptr;
     633             :                         if (t) {
     634             :                                 memcpy(newbuffer, ptr, t);
     635             :                                 newbuffer += t;
     636             :                         }
     637             :                         memcpy(newbuffer, plc->quoted, plc->qlen);
     638             :                         newbuffer += plc->qlen;
     639             :                         ptr = plc->pos + plc->len;
     640             : 
     641             :                         plc = plc->next;
     642             :                 } while (plc);
     643             : 
     644             :                 t = (inquery + inquery_len) - ptr;
     645             :                 if (t) {
     646             :                         memcpy(newbuffer, ptr, t);
     647             :                         newbuffer += t;
     648             :                 }
     649             :                 *newbuffer = '\0';
     650             :                 *outquery_len = newbuffer - *outquery;
     651             : 
     652             :                 ret = 1;
     653             :                 goto clean_up;
     654             : 
     655             :         } else if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
     656             :                 /* rewrite ? to :pdoX */
     657             :                 char *name, *idxbuf;
     658             :                 const char *tmpl = stmt->named_rewrite_template ? stmt->named_rewrite_template : ":pdo%d";
     659             :                 int bind_no = 1;
     660             :                 
     661             :                 newbuffer_len = inquery_len;
     662             : 
     663             :                 if (stmt->bound_param_map == NULL) {
     664             :                         ALLOC_HASHTABLE(stmt->bound_param_map);
     665             :                         zend_hash_init(stmt->bound_param_map, 13, NULL, NULL, 0);
     666             :                 }
     667             : 
     668             :                 for (plc = placeholders; plc; plc = plc->next) {
     669             :                         int skip_map = 0;
     670             :                         char *p;
     671             :                         name = estrndup(plc->pos, plc->len);
     672             : 
     673             :                         /* check if bound parameter is already available */
     674             :                         if (!strcmp(name, "?") || zend_hash_find(stmt->bound_param_map, name, plc->len + 1, (void**) &p) == FAILURE) {
     675             :                                 spprintf(&idxbuf, 0, tmpl, bind_no++);
     676             :                         } else {
     677             :                                 idxbuf = estrdup(p);
     678             :                                 skip_map = 1;
     679             :                         }
     680             : 
     681             :                         plc->quoted = idxbuf;
     682             :                         plc->qlen = strlen(plc->quoted);
     683             :                         plc->freeq = 1;
     684             :                         newbuffer_len += plc->qlen;
     685             : 
     686             :                         if (!skip_map && stmt->named_rewrite_template) {
     687             :                                 /* create a mapping */
     688             :                                 zend_hash_update(stmt->bound_param_map, name, plc->len + 1, idxbuf, plc->qlen + 1, NULL);
     689             :                         }
     690             : 
     691             :                         /* map number to name */
     692             :                         zend_hash_index_update(stmt->bound_param_map, plc->bindno, idxbuf, plc->qlen + 1, NULL);
     693             :                         
     694             :                         efree(name);
     695             :                 }
     696             :                                 
     697             :                 goto rewrite;
     698             : 
     699             :         } else {
     700             :                 /* rewrite :name to ? */
     701             :                 
     702             :                 newbuffer_len = inquery_len;
     703             :         
     704             :                 if (stmt->bound_param_map == NULL) {
     705             :                         ALLOC_HASHTABLE(stmt->bound_param_map);
     706             :                         zend_hash_init(stmt->bound_param_map, 13, NULL, NULL, 0);
     707             :                 }
     708             :                 
     709             :                 for (plc = placeholders; plc; plc = plc->next) {
     710             :                         char *name;
     711             :                         
     712             :                         name = estrndup(plc->pos, plc->len);
     713             :                         zend_hash_index_update(stmt->bound_param_map, plc->bindno, name, plc->len + 1, NULL);
     714             :                         efree(name);
     715             :                         plc->quoted = "?";
     716             :                         plc->qlen = 1;
     717             :                 }
     718             : 
     719             :                 goto rewrite;
     720             :         }
     721             : 
     722             : clean_up:
     723             : 
     724             :         while (placeholders) {
     725             :                 plc = placeholders;
     726             :                 placeholders = plc->next;
     727             : 
     728             :                 if (plc->freeq) {
     729             :                         efree(plc->quoted);
     730             :                 }
     731             : 
     732             :                 efree(plc);
     733             :         }
     734             : 
     735             :         return ret;
     736             : }
     737             : 
     738             : #if 0
     739             : int old_pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery, 
     740             :                 int *outquery_len TSRMLS_DC)
     741             : {
     742             :         Scanner s;
     743             :         char *ptr;
     744             :         int t;
     745             :         int bindno = 0;
     746             :         int newbuffer_len;
     747             :         int padding;
     748             :         HashTable *params = stmt->bound_params;
     749             :         struct pdo_bound_param_data *param;
     750             :         /* allocate buffer for query with expanded binds, ptr is our writing pointer */
     751             :         newbuffer_len = inquery_len;
     752             : 
     753             :         /* calculate the possible padding factor due to quoting */
     754             :         if(stmt->dbh->max_escaped_char_length) {
     755             :                 padding = stmt->dbh->max_escaped_char_length;
     756             :         } else {
     757             :                 padding = 3;
     758             :         }
     759             :         if(params) {
     760             :                 zend_hash_internal_pointer_reset(params);
     761             :                 while (SUCCESS == zend_hash_get_current_data(params, (void**)&param)) {
     762             :                         if(param->parameter) {
     763             :                                 convert_to_string(param->parameter);
     764             :                                 /* accomodate a string that needs to be fully quoted
     765             :                    bind placeholders are at least 2 characters, so
     766             :                    the accomodate their own "'s
     767             :                 */
     768             :                                 newbuffer_len += padding * Z_STRLEN_P(param->parameter);
     769             :                         }
     770             :                         zend_hash_move_forward(params);
     771             :                 }
     772             :         }
     773             :         *outquery = (char *) emalloc(newbuffer_len + 1);
     774             :         *outquery_len = 0;
     775             : 
     776             :         ptr = *outquery;
     777             :         s.cur = inquery;
     778             :         while((t = scan(&s)) != PDO_PARSER_EOI) {
     779             :                 if(t == PDO_PARSER_TEXT) {
     780             :                         memcpy(ptr, s.tok, s.cur - s.tok);
     781             :                         ptr += (s.cur - s.tok);
     782             :                         *outquery_len += (s.cur - s.tok);
     783             :                 }
     784             :                 else if(t == PDO_PARSER_BIND) {
     785             :                         if(!params) { 
     786             :                                 /* error */
     787             :                                 efree(*outquery);
     788             :                                 *outquery = NULL;
     789             :                                 return (int) (s.cur - inquery);
     790             :                         }
     791             :                         /* lookup bind first via hash and then index */
     792             :                         /* stupid keys need to be null-terminated, even though we know their length */
     793             :                         if((SUCCESS == zend_hash_find(params, s.tok, s.cur-s.tok,(void **)&param))  
     794             :                             ||
     795             :                            (SUCCESS == zend_hash_index_find(params, bindno, (void **)&param))) 
     796             :                         {
     797             :                                 char *quotedstr;
     798             :                                 int quotedstrlen;
     799             :                                 /* restore the in-string key, doesn't need null-termination here */
     800             :                                 /* currently everything is a string here */
     801             :                                 
     802             :                                 /* quote the bind value if necessary */
     803             :                                 if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter), 
     804             :                                         Z_STRLEN_P(param->parameter), &quotedstr, &quotedstrlen TSRMLS_CC))
     805             :                                 {
     806             :                                         memcpy(ptr, quotedstr, quotedstrlen);
     807             :                                         ptr += quotedstrlen;
     808             :                                         *outquery_len += quotedstrlen;
     809             :                                         efree(quotedstr);
     810             :                                 } else {
     811             :                                         memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
     812             :                                         ptr += Z_STRLEN_P(param->parameter);
     813             :                                         *outquery_len += (Z_STRLEN_P(param->parameter));
     814             :                                 }
     815             :                         }
     816             :                         else {
     817             :                                 /* error and cleanup */
     818             :                                 efree(*outquery);
     819             :                                 *outquery = NULL;
     820             :                                 return (int) (s.cur - inquery);
     821             :                         }
     822             :                         bindno++;
     823             :                 }
     824             :                 else if(t == PDO_PARSER_BIND_POS) {
     825             :                         if(!params) { 
     826             :                                 /* error */
     827             :                                 efree(*outquery);
     828             :                                 *outquery = NULL;
     829             :                                 return (int) (s.cur - inquery);
     830             :                         }
     831             :                         /* lookup bind by index */
     832             :                         if(SUCCESS == zend_hash_index_find(params, bindno, (void **)&param)) 
     833             :                         {
     834             :                                 char *quotedstr;
     835             :                                 int quotedstrlen;
     836             :                                 /* currently everything is a string here */
     837             :                                 
     838             :                                 /* quote the bind value if necessary */
     839             :                                 if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter), 
     840             :                                         Z_STRLEN_P(param->parameter), &quotedstr, &quotedstrlen TSRMLS_CC))
     841             :                                 {
     842             :                                         memcpy(ptr, quotedstr, quotedstrlen);
     843             :                                         ptr += quotedstrlen;
     844             :                                         *outquery_len += quotedstrlen;
     845             :                                         efree(quotedstr);
     846             :                                 } else {
     847             :                                         memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
     848             :                                         ptr += Z_STRLEN_P(param->parameter);
     849             :                                         *outquery_len += (Z_STRLEN_P(param->parameter));
     850             :                                 }
     851             :                         }
     852             :                         else {
     853             :                                 /* error and cleanup */
     854             :                                 efree(*outquery);
     855             :                                 *outquery = NULL;
     856             :                                 return (int) (s.cur - inquery);
     857             :                         }
     858             :                         bindno++;
     859             :                 }
     860             :         }       
     861             :         *ptr = '\0';
     862             :         return 0;
     863             : }
     864             : #endif
     865             : 
     866             : /*
     867             :  * Local variables:
     868             :  * tab-width: 4
     869             :  * c-basic-offset: 4
     870             :  * End:
     871             :  * vim600: noet sw=4 ts=4 fdm=marker ft=c
     872             :  * vim<600: noet sw=4 ts=4
     873             :  */

Generated by: LCOV version 1.10

Generated at Fri, 18 Apr 2014 07:01:40 +0000 (6 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.