root/ext/pdo/pdo_sql_parser.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. scan
  2. free_param_name
  3. pdo_parse_params
  4. old_pdo_parse_params

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

/* [<][>][^][v][top][bottom][index][help] */