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: 94 138 68.1 %
Date: 2014-07-15 Functions: 0 0 -
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Tue, 15 Jul 2014 20:53:35 +0000 (7 days ago)

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