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: 92 107 86.0 %
Date: 2016-08-24 Functions: 0 0 -
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Wed, 24 Aug 2016 12:20:34 +0000 (32 hours ago)

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