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

LTP GCOV extension - code coverage report
Current view: directory - var/php_gcov/PHP_HEAD/lcov_data/ext/pdo - pdo_sql_parser.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 83
Code covered: 81.9 % Executed lines: 68
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:46 +0000 (34 hours ago)

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