root/ext/pdo/pdo_sql_parser.c

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

DEFINITIONS

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

   1 /* Generated by re2c 0.13.5 */
   2 /*
   3   +----------------------------------------------------------------------+
   4   | PHP Version 5                                                        |
   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         int len;
 410         int bindno;
 411         int qlen;               /* quoted length of value */
 412         char *quoted;   /* quoted value */
 413         int freeq;
 414         struct placeholder *next;
 415 };
 416 
 417 PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, 
 418         char **outquery, int *outquery_len TSRMLS_DC)
 419 {
 420         Scanner s;
 421         char *ptr, *newbuffer;
 422         int t;
 423         int bindno = 0;
 424         int ret = 0;
 425         int newbuffer_len;
 426         HashTable *params;
 427         struct pdo_bound_param_data *param;
 428         int query_type = PDO_PLACEHOLDER_NONE;
 429         struct placeholder *placeholders = NULL, *placetail = NULL, *plc = NULL;
 430 
 431         ptr = *outquery;
 432         s.cur = inquery;
 433         s.end = inquery + inquery_len + 1;
 434 
 435         /* phase 1: look for args */
 436         while((t = scan(&s)) != PDO_PARSER_EOI) {
 437                 if (t == PDO_PARSER_BIND || t == PDO_PARSER_BIND_POS) {
 438                         if (t == PDO_PARSER_BIND) {
 439                                 int len = s.cur - s.tok;
 440                                 if ((inquery < (s.cur - len)) && isalnum(*(s.cur - len - 1))) {
 441                                         continue;
 442                                 }
 443                                 query_type |= PDO_PLACEHOLDER_NAMED;
 444                         } else {
 445                                 query_type |= PDO_PLACEHOLDER_POSITIONAL;
 446                         }
 447 
 448                         plc = emalloc(sizeof(*plc));
 449                         memset(plc, 0, sizeof(*plc));
 450                         plc->next = NULL;
 451                         plc->pos = s.tok;
 452                         plc->len = s.cur - s.tok;
 453                         plc->bindno = bindno++;
 454 
 455                         if (placetail) {
 456                                 placetail->next = plc;
 457                         } else {
 458                                 placeholders = plc;
 459                         }
 460                         placetail = plc;
 461                 }
 462         }
 463 
 464         if (bindno == 0) {
 465                 /* nothing to do; good! */
 466                 return 0;
 467         }
 468 
 469         /* did the query make sense to me? */
 470         if (query_type == (PDO_PLACEHOLDER_NAMED|PDO_PLACEHOLDER_POSITIONAL)) {
 471                 /* they mixed both types; punt */
 472                 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "mixed named and positional parameters" TSRMLS_CC);
 473                 ret = -1;
 474                 goto clean_up;
 475         }
 476 
 477         if (stmt->supports_placeholders == query_type && !stmt->named_rewrite_template) {
 478                 /* query matches native syntax */
 479                 ret = 0;
 480                 goto clean_up;
 481         }
 482 
 483         if (stmt->named_rewrite_template) {
 484                 /* magic/hack.
 485                  * We we pretend that the query was positional even if
 486                  * it was named so that we fall into the
 487                  * named rewrite case below.  Not too pretty,
 488                  * but it works. */
 489                 query_type = PDO_PLACEHOLDER_POSITIONAL;
 490         }
 491         
 492         params = stmt->bound_params;
 493         
 494         /* Do we have placeholders but no bound params */
 495         if (bindno && !params && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
 496                 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "no parameters were bound" TSRMLS_CC);
 497                 ret = -1;
 498                 goto clean_up;
 499         }
 500 
 501         if (params && bindno != zend_hash_num_elements(params) && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
 502                 /* extra bit of validation for instances when same params are bound more then once */
 503                 if (query_type != PDO_PLACEHOLDER_POSITIONAL && bindno > zend_hash_num_elements(params)) {
 504                         int ok = 1;
 505                         for (plc = placeholders; plc; plc = plc->next) {
 506                                 if (zend_hash_find(params, plc->pos, plc->len, (void**) &param) == FAILURE) {
 507                                         ok = 0;
 508                                         break;
 509                                 }
 510                         }
 511                         if (ok) {
 512                                 goto safe;
 513                         }
 514                 }
 515                 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "number of bound variables does not match number of tokens" TSRMLS_CC);
 516                 ret = -1;
 517                 goto clean_up;
 518         }
 519 safe:
 520         /* what are we going to do ? */
 521         if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
 522                 /* query generation */
 523 
 524                 newbuffer_len = inquery_len;
 525 
 526                 /* let's quote all the values */        
 527                 for (plc = placeholders; plc; plc = plc->next) {
 528                         if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
 529                                 ret = zend_hash_index_find(params, plc->bindno, (void**) &param);
 530                         } else {
 531                                 ret = zend_hash_find(params, plc->pos, plc->len, (void**) &param);
 532                         }
 533                         if (ret == FAILURE) {
 534                                 /* parameter was not defined */
 535                                 ret = -1;
 536                                 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined" TSRMLS_CC);
 537                                 goto clean_up;
 538                         }
 539                         if (stmt->dbh->methods->quoter) {
 540                                 if (param->param_type == PDO_PARAM_LOB && Z_TYPE_P(param->parameter) == IS_RESOURCE) {
 541                                         php_stream *stm;
 542 
 543                                         php_stream_from_zval_no_verify(stm, &param->parameter);
 544                                         if (stm) {
 545                                                 size_t len;
 546                                                 char *buf = NULL;
 547                                         
 548                                                 len = php_stream_copy_to_mem(stm, &buf, PHP_STREAM_COPY_ALL, 0);
 549                                                 if (!stmt->dbh->methods->quoter(stmt->dbh, buf, len, &plc->quoted, &plc->qlen,
 550                                                                 param->param_type TSRMLS_CC)) {
 551                                                         /* bork */
 552                                                         ret = -1;
 553                                                         strncpy(stmt->error_code, stmt->dbh->error_code, 6);
 554                                                         if (buf) {
 555                                                                 efree(buf);
 556                                                         }
 557                                                         goto clean_up;
 558                                                 }
 559                                                 if (buf) {
 560                                                         efree(buf);
 561                                                 }
 562                                         } else {
 563                                                 pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource" TSRMLS_CC);
 564                                                 ret = -1;
 565                                                 goto clean_up;
 566                                         }
 567                                         plc->freeq = 1;
 568                                 } else {
 569                                         zval tmp_param = *param->parameter;
 570                                         zval_copy_ctor(&tmp_param);
 571                                         switch (Z_TYPE(tmp_param)) {
 572                                                 case IS_NULL:
 573                                                         plc->quoted = "NULL";
 574                                                         plc->qlen = sizeof("NULL")-1;
 575                                                         plc->freeq = 0;
 576                                                         break;
 577 
 578                                                 case IS_BOOL:
 579                                                         convert_to_long(&tmp_param);
 580                                                         /* fall through */
 581                                                 case IS_LONG:
 582                                                 case IS_DOUBLE:
 583                                                         convert_to_string(&tmp_param);
 584                                                         plc->qlen = Z_STRLEN(tmp_param);
 585                                                         plc->quoted = estrdup(Z_STRVAL(tmp_param));
 586                                                         plc->freeq = 1;
 587                                                         break;
 588 
 589                                                 default:
 590                                                         convert_to_string(&tmp_param);
 591                                                         if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL(tmp_param),
 592                                                                         Z_STRLEN(tmp_param), &plc->quoted, &plc->qlen,
 593                                                                         param->param_type TSRMLS_CC)) {
 594                                                                 /* bork */
 595                                                                 ret = -1;
 596                                                                 strncpy(stmt->error_code, stmt->dbh->error_code, 6);
 597                                                                 goto clean_up;
 598                                                         }
 599                                                         plc->freeq = 1;
 600                                         }
 601                                         zval_dtor(&tmp_param);
 602                                 }
 603                         } else {
 604                                 plc->quoted = Z_STRVAL_P(param->parameter);
 605                                 plc->qlen = Z_STRLEN_P(param->parameter);
 606                         }
 607                         newbuffer_len += plc->qlen;
 608                 }
 609 
 610 rewrite:
 611                 /* allocate output buffer */
 612                 newbuffer = emalloc(newbuffer_len + 1);
 613                 *outquery = newbuffer;
 614 
 615                 /* and build the query */
 616                 plc = placeholders;
 617                 ptr = inquery;
 618 
 619                 do {
 620                         t = plc->pos - ptr;
 621                         if (t) {
 622                                 memcpy(newbuffer, ptr, t);
 623                                 newbuffer += t;
 624                         }
 625                         memcpy(newbuffer, plc->quoted, plc->qlen);
 626                         newbuffer += plc->qlen;
 627                         ptr = plc->pos + plc->len;
 628 
 629                         plc = plc->next;
 630                 } while (plc);
 631 
 632                 t = (inquery + inquery_len) - ptr;
 633                 if (t) {
 634                         memcpy(newbuffer, ptr, t);
 635                         newbuffer += t;
 636                 }
 637                 *newbuffer = '\0';
 638                 *outquery_len = newbuffer - *outquery;
 639 
 640                 ret = 1;
 641                 goto clean_up;
 642 
 643         } else if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
 644                 /* rewrite ? to :pdoX */
 645                 char *name, *idxbuf;
 646                 const char *tmpl = stmt->named_rewrite_template ? stmt->named_rewrite_template : ":pdo%d";
 647                 int bind_no = 1;
 648                 
 649                 newbuffer_len = inquery_len;
 650 
 651                 if (stmt->bound_param_map == NULL) {
 652                         ALLOC_HASHTABLE(stmt->bound_param_map);
 653                         zend_hash_init(stmt->bound_param_map, 13, NULL, NULL, 0);
 654                 }
 655 
 656                 for (plc = placeholders; plc; plc = plc->next) {
 657                         int skip_map = 0;
 658                         char *p;
 659                         name = estrndup(plc->pos, plc->len);
 660 
 661                         /* check if bound parameter is already available */
 662                         if (!strcmp(name, "?") || zend_hash_find(stmt->bound_param_map, name, plc->len + 1, (void**) &p) == FAILURE) {
 663                                 spprintf(&idxbuf, 0, tmpl, bind_no++);
 664                         } else {
 665                                 idxbuf = estrdup(p);
 666                                 skip_map = 1;
 667                         }
 668 
 669                         plc->quoted = idxbuf;
 670                         plc->qlen = strlen(plc->quoted);
 671                         plc->freeq = 1;
 672                         newbuffer_len += plc->qlen;
 673 
 674                         if (!skip_map && stmt->named_rewrite_template) {
 675                                 /* create a mapping */
 676                                 zend_hash_update(stmt->bound_param_map, name, plc->len + 1, idxbuf, plc->qlen + 1, NULL);
 677                         }
 678 
 679                         /* map number to name */
 680                         zend_hash_index_update(stmt->bound_param_map, plc->bindno, idxbuf, plc->qlen + 1, NULL);
 681                         
 682                         efree(name);
 683                 }
 684                                 
 685                 goto rewrite;
 686 
 687         } else {
 688                 /* rewrite :name to ? */
 689                 
 690                 newbuffer_len = inquery_len;
 691         
 692                 if (stmt->bound_param_map == NULL) {
 693                         ALLOC_HASHTABLE(stmt->bound_param_map);
 694                         zend_hash_init(stmt->bound_param_map, 13, NULL, NULL, 0);
 695                 }
 696                 
 697                 for (plc = placeholders; plc; plc = plc->next) {
 698                         char *name;
 699                         
 700                         name = estrndup(plc->pos, plc->len);
 701                         zend_hash_index_update(stmt->bound_param_map, plc->bindno, name, plc->len + 1, NULL);
 702                         efree(name);
 703                         plc->quoted = "?";
 704                         plc->qlen = 1;
 705                 }
 706 
 707                 goto rewrite;
 708         }
 709 
 710 clean_up:
 711 
 712         while (placeholders) {
 713                 plc = placeholders;
 714                 placeholders = plc->next;
 715 
 716                 if (plc->freeq) {
 717                         efree(plc->quoted);
 718                 }
 719 
 720                 efree(plc);
 721         }
 722 
 723         return ret;
 724 }
 725 
 726 #if 0
 727 int old_pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery, 
 728                 int *outquery_len TSRMLS_DC)
 729 {
 730         Scanner s;
 731         char *ptr;
 732         int t;
 733         int bindno = 0;
 734         int newbuffer_len;
 735         int padding;
 736         HashTable *params = stmt->bound_params;
 737         struct pdo_bound_param_data *param;
 738         /* allocate buffer for query with expanded binds, ptr is our writing pointer */
 739         newbuffer_len = inquery_len;
 740 
 741         /* calculate the possible padding factor due to quoting */
 742         if(stmt->dbh->max_escaped_char_length) {
 743                 padding = stmt->dbh->max_escaped_char_length;
 744         } else {
 745                 padding = 3;
 746         }
 747         if(params) {
 748                 zend_hash_internal_pointer_reset(params);
 749                 while (SUCCESS == zend_hash_get_current_data(params, (void**)&param)) {
 750                         if(param->parameter) {
 751                                 convert_to_string(param->parameter);
 752                                 /* accommodate a string that needs to be fully quoted
 753                    bind placeholders are at least 2 characters, so
 754                    the accommodate their own "'s
 755                 */
 756                                 newbuffer_len += padding * Z_STRLEN_P(param->parameter);
 757                         }
 758                         zend_hash_move_forward(params);
 759                 }
 760         }
 761         *outquery = (char *) emalloc(newbuffer_len + 1);
 762         *outquery_len = 0;
 763 
 764         ptr = *outquery;
 765         s.cur = inquery;
 766         while((t = scan(&s)) != PDO_PARSER_EOI) {
 767                 if(t == PDO_PARSER_TEXT) {
 768                         memcpy(ptr, s.tok, s.cur - s.tok);
 769                         ptr += (s.cur - s.tok);
 770                         *outquery_len += (s.cur - s.tok);
 771                 }
 772                 else if(t == PDO_PARSER_BIND) {
 773                         if(!params) { 
 774                                 /* error */
 775                                 efree(*outquery);
 776                                 *outquery = NULL;
 777                                 return (int) (s.cur - inquery);
 778                         }
 779                         /* lookup bind first via hash and then index */
 780                         /* stupid keys need to be null-terminated, even though we know their length */
 781                         if((SUCCESS == zend_hash_find(params, s.tok, s.cur-s.tok,(void **)&param))  
 782                             ||
 783                            (SUCCESS == zend_hash_index_find(params, bindno, (void **)&param))) 
 784                         {
 785                                 char *quotedstr;
 786                                 int quotedstrlen;
 787                                 /* restore the in-string key, doesn't need null-termination here */
 788                                 /* currently everything is a string here */
 789                                 
 790                                 /* quote the bind value if necessary */
 791                                 if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter), 
 792                                         Z_STRLEN_P(param->parameter), &quotedstr, &quotedstrlen TSRMLS_CC))
 793                                 {
 794                                         memcpy(ptr, quotedstr, quotedstrlen);
 795                                         ptr += quotedstrlen;
 796                                         *outquery_len += quotedstrlen;
 797                                         efree(quotedstr);
 798                                 } else {
 799                                         memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
 800                                         ptr += Z_STRLEN_P(param->parameter);
 801                                         *outquery_len += (Z_STRLEN_P(param->parameter));
 802                                 }
 803                         }
 804                         else {
 805                                 /* error and cleanup */
 806                                 efree(*outquery);
 807                                 *outquery = NULL;
 808                                 return (int) (s.cur - inquery);
 809                         }
 810                         bindno++;
 811                 }
 812                 else if(t == PDO_PARSER_BIND_POS) {
 813                         if(!params) { 
 814                                 /* error */
 815                                 efree(*outquery);
 816                                 *outquery = NULL;
 817                                 return (int) (s.cur - inquery);
 818                         }
 819                         /* lookup bind by index */
 820                         if(SUCCESS == zend_hash_index_find(params, bindno, (void **)&param)) 
 821                         {
 822                                 char *quotedstr;
 823                                 int quotedstrlen;
 824                                 /* currently everything is a string here */
 825                                 
 826                                 /* quote the bind value if necessary */
 827                                 if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter), 
 828                                         Z_STRLEN_P(param->parameter), &quotedstr, &quotedstrlen TSRMLS_CC))
 829                                 {
 830                                         memcpy(ptr, quotedstr, quotedstrlen);
 831                                         ptr += quotedstrlen;
 832                                         *outquery_len += quotedstrlen;
 833                                         efree(quotedstr);
 834                                 } else {
 835                                         memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
 836                                         ptr += Z_STRLEN_P(param->parameter);
 837                                         *outquery_len += (Z_STRLEN_P(param->parameter));
 838                                 }
 839                         }
 840                         else {
 841                                 /* error and cleanup */
 842                                 efree(*outquery);
 843                                 *outquery = NULL;
 844                                 return (int) (s.cur - inquery);
 845                         }
 846                         bindno++;
 847                 }
 848         }       
 849         *ptr = '\0';
 850         return 0;
 851 }
 852 #endif
 853 
 854 /*
 855  * Local variables:
 856  * tab-width: 4
 857  * c-basic-offset: 4
 858  * End:
 859  * vim600: noet sw=4 ts=4 fdm=marker ft=c
 860  * vim<600: noet sw=4 ts=4
 861  */

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