Annotation of embedaddon/php/ext/pdo/pdo_sql_parser.c, revision 1.1
1.1 ! misho 1: /* Generated by re2c 0.13.5 on Sat Jun 4 18:42:25 2011 */
! 2: /*
! 3: +----------------------------------------------------------------------+
! 4: | PHP Version 5 |
! 5: +----------------------------------------------------------------------+
! 6: | Copyright (c) 1997-2012 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: pdo_sql_parser.c 321634 2012-01-01 13:15:04Z felipe $ */
! 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 cursor
! 37: #define YYMARKER s->ptr
! 38: #define YYFILL(n)
! 39:
! 40: typedef struct Scanner {
! 41: char *ptr, *cur, *tok;
! 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 yy13;
! 60: case '"': goto yy2;
! 61: case '\'': goto yy4;
! 62: case '-': goto yy10;
! 63: case '/': goto yy8;
! 64: case ':': goto yy5;
! 65: case '?': goto yy6;
! 66: default: goto yy11;
! 67: }
! 68: yy2:
! 69: yyaccept = 0;
! 70: yych = *(YYMARKER = ++YYCURSOR);
! 71: if (yych >= 0x01) goto yy43;
! 72: yy3:
! 73: { SKIP_ONE(PDO_PARSER_TEXT); }
! 74: yy4:
! 75: yyaccept = 0;
! 76: yych = *(YYMARKER = ++YYCURSOR);
! 77: if (yych <= 0x00) goto yy3;
! 78: goto yy37;
! 79: yy5:
! 80: yych = *++YYCURSOR;
! 81: 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: case 'z': goto yy33;
! 145: case ':':
! 146: case '?': goto yy30;
! 147: default: goto yy3;
! 148: }
! 149: yy6:
! 150: ++YYCURSOR;
! 151: switch ((yych = *YYCURSOR)) {
! 152: case ':':
! 153: case '?': goto yy30;
! 154: default: goto yy7;
! 155: }
! 156: yy7:
! 157: { RET(PDO_PARSER_BIND_POS); }
! 158: yy8:
! 159: ++YYCURSOR;
! 160: switch ((yych = *YYCURSOR)) {
! 161: case '*': goto yy20;
! 162: default: goto yy12;
! 163: }
! 164: yy9:
! 165: { RET(PDO_PARSER_TEXT); }
! 166: yy10:
! 167: yych = *++YYCURSOR;
! 168: switch (yych) {
! 169: case '-': goto yy15;
! 170: default: goto yy12;
! 171: }
! 172: yy11:
! 173: ++YYCURSOR;
! 174: if (YYLIMIT <= YYCURSOR) YYFILL(1);
! 175: yych = *YYCURSOR;
! 176: yy12:
! 177: switch (yych) {
! 178: case 0x00:
! 179: case '"':
! 180: case '\'':
! 181: case ':':
! 182: case '?': goto yy9;
! 183: default: goto yy11;
! 184: }
! 185: yy13:
! 186: ++YYCURSOR;
! 187: { RET(PDO_PARSER_EOI); }
! 188: yy15:
! 189: ++YYCURSOR;
! 190: if (YYLIMIT <= YYCURSOR) YYFILL(1);
! 191: yych = *YYCURSOR;
! 192: switch (yych) {
! 193: case 0x00:
! 194: case '"':
! 195: case '\'':
! 196: case ':':
! 197: case '?': goto yy18;
! 198: case '\n':
! 199: case '\r': goto yy11;
! 200: default: goto yy15;
! 201: }
! 202: yy17:
! 203: { RET(PDO_PARSER_TEXT); }
! 204: yy18:
! 205: ++YYCURSOR;
! 206: if (YYLIMIT <= YYCURSOR) YYFILL(1);
! 207: yych = *YYCURSOR;
! 208: switch (yych) {
! 209: case '\n':
! 210: case '\r': goto yy17;
! 211: default: goto yy18;
! 212: }
! 213: yy20:
! 214: yyaccept = 1;
! 215: YYMARKER = ++YYCURSOR;
! 216: if (YYLIMIT <= YYCURSOR) YYFILL(1);
! 217: yych = *YYCURSOR;
! 218: switch (yych) {
! 219: case 0x00:
! 220: case '"':
! 221: case '\'':
! 222: case ':':
! 223: case '?': goto yy22;
! 224: case '*': goto yy24;
! 225: default: goto yy20;
! 226: }
! 227: yy22:
! 228: ++YYCURSOR;
! 229: if (YYLIMIT <= YYCURSOR) YYFILL(1);
! 230: yych = *YYCURSOR;
! 231: switch (yych) {
! 232: case '*': goto yy27;
! 233: default: goto yy22;
! 234: }
! 235: yy24:
! 236: yyaccept = 1;
! 237: YYMARKER = ++YYCURSOR;
! 238: if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
! 239: yych = *YYCURSOR;
! 240: switch (yych) {
! 241: case 0x00:
! 242: case '"':
! 243: case '\'':
! 244: case ':':
! 245: case '?': goto yy22;
! 246: case '*': goto yy24;
! 247: case '/': goto yy26;
! 248: default: goto yy20;
! 249: }
! 250: yy26:
! 251: yych = *++YYCURSOR;
! 252: switch (yych) {
! 253: case 0x00:
! 254: case '"':
! 255: case '\'':
! 256: case ':':
! 257: case '?': goto yy17;
! 258: default: goto yy11;
! 259: }
! 260: yy27:
! 261: ++YYCURSOR;
! 262: if (YYLIMIT <= YYCURSOR) YYFILL(1);
! 263: yych = *YYCURSOR;
! 264: switch (yych) {
! 265: case '*': goto yy27;
! 266: case '/': goto yy29;
! 267: default: goto yy22;
! 268: }
! 269: yy29:
! 270: yych = *++YYCURSOR;
! 271: goto yy17;
! 272: yy30:
! 273: ++YYCURSOR;
! 274: if (YYLIMIT <= YYCURSOR) YYFILL(1);
! 275: yych = *YYCURSOR;
! 276: switch (yych) {
! 277: case ':':
! 278: case '?': goto yy30;
! 279: default: goto yy32;
! 280: }
! 281: yy32:
! 282: { RET(PDO_PARSER_TEXT); }
! 283: yy33:
! 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 yy33;
! 351: default: goto yy35;
! 352: }
! 353: yy35:
! 354: { RET(PDO_PARSER_BIND); }
! 355: yy36:
! 356: ++YYCURSOR;
! 357: if (YYLIMIT <= YYCURSOR) YYFILL(1);
! 358: yych = *YYCURSOR;
! 359: yy37:
! 360: switch (yych) {
! 361: case 0x00: goto yy38;
! 362: case '\'': goto yy40;
! 363: case '\\': goto yy39;
! 364: default: goto yy36;
! 365: }
! 366: yy38:
! 367: YYCURSOR = YYMARKER;
! 368: switch (yyaccept) {
! 369: case 0: goto yy3;
! 370: case 1: goto yy9;
! 371: }
! 372: yy39:
! 373: ++YYCURSOR;
! 374: if (YYLIMIT <= YYCURSOR) YYFILL(1);
! 375: yych = *YYCURSOR;
! 376: if (yych <= 0x00) goto yy38;
! 377: goto yy36;
! 378: yy40:
! 379: ++YYCURSOR;
! 380: { RET(PDO_PARSER_TEXT); }
! 381: yy42:
! 382: ++YYCURSOR;
! 383: if (YYLIMIT <= YYCURSOR) YYFILL(1);
! 384: yych = *YYCURSOR;
! 385: yy43:
! 386: switch (yych) {
! 387: case 0x00: goto yy38;
! 388: case '"': goto yy45;
! 389: case '\\': goto yy44;
! 390: default: goto yy42;
! 391: }
! 392: yy44:
! 393: ++YYCURSOR;
! 394: if (YYLIMIT <= YYCURSOR) YYFILL(1);
! 395: yych = *YYCURSOR;
! 396: if (yych <= 0x00) goto yy38;
! 397: goto yy42;
! 398: yy45:
! 399: ++YYCURSOR;
! 400: { RET(PDO_PARSER_TEXT); }
! 401: }
! 402:
! 403: }
! 404:
! 405: struct placeholder {
! 406: char *pos;
! 407: int len;
! 408: int bindno;
! 409: int qlen; /* quoted length of value */
! 410: char *quoted; /* quoted value */
! 411: int freeq;
! 412: struct placeholder *next;
! 413: };
! 414:
! 415: PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
! 416: char **outquery, int *outquery_len TSRMLS_DC)
! 417: {
! 418: Scanner s;
! 419: char *ptr, *newbuffer;
! 420: int t;
! 421: int bindno = 0;
! 422: int ret = 0;
! 423: int newbuffer_len;
! 424: HashTable *params;
! 425: struct pdo_bound_param_data *param;
! 426: int query_type = PDO_PLACEHOLDER_NONE;
! 427: struct placeholder *placeholders = NULL, *placetail = NULL, *plc = NULL;
! 428:
! 429: ptr = *outquery;
! 430: s.cur = inquery;
! 431:
! 432: /* phase 1: look for args */
! 433: while((t = scan(&s)) != PDO_PARSER_EOI) {
! 434: if (t == PDO_PARSER_BIND || t == PDO_PARSER_BIND_POS) {
! 435: if (t == PDO_PARSER_BIND) {
! 436: int len = s.cur - s.tok;
! 437: if ((inquery < (s.cur - len)) && isalnum(*(s.cur - len - 1))) {
! 438: continue;
! 439: }
! 440: query_type |= PDO_PLACEHOLDER_NAMED;
! 441: } else {
! 442: query_type |= PDO_PLACEHOLDER_POSITIONAL;
! 443: }
! 444:
! 445: plc = emalloc(sizeof(*plc));
! 446: memset(plc, 0, sizeof(*plc));
! 447: plc->next = NULL;
! 448: plc->pos = s.tok;
! 449: plc->len = s.cur - s.tok;
! 450: plc->bindno = bindno++;
! 451:
! 452: if (placetail) {
! 453: placetail->next = plc;
! 454: } else {
! 455: placeholders = plc;
! 456: }
! 457: placetail = plc;
! 458: }
! 459: }
! 460:
! 461: if (bindno == 0) {
! 462: /* nothing to do; good! */
! 463: return 0;
! 464: }
! 465:
! 466: /* did the query make sense to me? */
! 467: if (query_type == (PDO_PLACEHOLDER_NAMED|PDO_PLACEHOLDER_POSITIONAL)) {
! 468: /* they mixed both types; punt */
! 469: pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "mixed named and positional parameters" TSRMLS_CC);
! 470: ret = -1;
! 471: goto clean_up;
! 472: }
! 473:
! 474: if (stmt->supports_placeholders == query_type && !stmt->named_rewrite_template) {
! 475: /* query matches native syntax */
! 476: ret = 0;
! 477: goto clean_up;
! 478: }
! 479:
! 480: if (stmt->named_rewrite_template) {
! 481: /* magic/hack.
! 482: * We we pretend that the query was positional even if
! 483: * it was named so that we fall into the
! 484: * named rewrite case below. Not too pretty,
! 485: * but it works. */
! 486: query_type = PDO_PLACEHOLDER_POSITIONAL;
! 487: }
! 488:
! 489: params = stmt->bound_params;
! 490:
! 491: /* Do we have placeholders but no bound params */
! 492: if (bindno && !params && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
! 493: pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "no parameters were bound" TSRMLS_CC);
! 494: ret = -1;
! 495: goto clean_up;
! 496: }
! 497:
! 498: if (params && bindno != zend_hash_num_elements(params) && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
! 499: /* extra bit of validation for instances when same params are bound more then once */
! 500: if (query_type != PDO_PLACEHOLDER_POSITIONAL && bindno > zend_hash_num_elements(params)) {
! 501: int ok = 1;
! 502: for (plc = placeholders; plc; plc = plc->next) {
! 503: if (zend_hash_find(params, plc->pos, plc->len, (void**) ¶m) == FAILURE) {
! 504: ok = 0;
! 505: break;
! 506: }
! 507: }
! 508: if (ok) {
! 509: goto safe;
! 510: }
! 511: }
! 512: pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "number of bound variables does not match number of tokens" TSRMLS_CC);
! 513: ret = -1;
! 514: goto clean_up;
! 515: }
! 516: safe:
! 517: /* what are we going to do ? */
! 518: if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
! 519: /* query generation */
! 520:
! 521: newbuffer_len = inquery_len;
! 522:
! 523: /* let's quote all the values */
! 524: for (plc = placeholders; plc; plc = plc->next) {
! 525: if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
! 526: ret = zend_hash_index_find(params, plc->bindno, (void**) ¶m);
! 527: } else {
! 528: ret = zend_hash_find(params, plc->pos, plc->len, (void**) ¶m);
! 529: }
! 530: if (ret == FAILURE) {
! 531: /* parameter was not defined */
! 532: ret = -1;
! 533: pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined" TSRMLS_CC);
! 534: goto clean_up;
! 535: }
! 536: if (stmt->dbh->methods->quoter) {
! 537: if (param->param_type == PDO_PARAM_LOB && Z_TYPE_P(param->parameter) == IS_RESOURCE) {
! 538: php_stream *stm;
! 539:
! 540: php_stream_from_zval_no_verify(stm, ¶m->parameter);
! 541: if (stm) {
! 542: size_t len;
! 543: char *buf = NULL;
! 544:
! 545: len = php_stream_copy_to_mem(stm, &buf, PHP_STREAM_COPY_ALL, 0);
! 546: if (!stmt->dbh->methods->quoter(stmt->dbh, buf, len, &plc->quoted, &plc->qlen,
! 547: param->param_type TSRMLS_CC)) {
! 548: /* bork */
! 549: ret = -1;
! 550: strcpy(stmt->error_code, stmt->dbh->error_code);
! 551: if (buf) {
! 552: efree(buf);
! 553: }
! 554: goto clean_up;
! 555: }
! 556: if (buf) {
! 557: efree(buf);
! 558: }
! 559: } else {
! 560: pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource" TSRMLS_CC);
! 561: ret = -1;
! 562: goto clean_up;
! 563: }
! 564: plc->freeq = 1;
! 565: } else {
! 566: switch (Z_TYPE_P(param->parameter)) {
! 567: case IS_NULL:
! 568: plc->quoted = "NULL";
! 569: plc->qlen = sizeof("NULL")-1;
! 570: plc->freeq = 0;
! 571: break;
! 572:
! 573: case IS_LONG:
! 574: case IS_DOUBLE:
! 575: convert_to_string(param->parameter);
! 576: plc->qlen = Z_STRLEN_P(param->parameter);
! 577: plc->quoted = Z_STRVAL_P(param->parameter);
! 578: plc->freeq = 0;
! 579: break;
! 580:
! 581: case IS_BOOL:
! 582: convert_to_long(param->parameter);
! 583: default:
! 584: convert_to_string(param->parameter);
! 585: if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
! 586: Z_STRLEN_P(param->parameter), &plc->quoted, &plc->qlen,
! 587: param->param_type TSRMLS_CC)) {
! 588: /* bork */
! 589: ret = -1;
! 590: strcpy(stmt->error_code, stmt->dbh->error_code);
! 591: goto clean_up;
! 592: }
! 593: plc->freeq = 1;
! 594: }
! 595: }
! 596: } else {
! 597: plc->quoted = Z_STRVAL_P(param->parameter);
! 598: plc->qlen = Z_STRLEN_P(param->parameter);
! 599: }
! 600: newbuffer_len += plc->qlen;
! 601: }
! 602:
! 603: rewrite:
! 604: /* allocate output buffer */
! 605: newbuffer = emalloc(newbuffer_len + 1);
! 606: *outquery = newbuffer;
! 607:
! 608: /* and build the query */
! 609: plc = placeholders;
! 610: ptr = inquery;
! 611:
! 612: do {
! 613: t = plc->pos - ptr;
! 614: if (t) {
! 615: memcpy(newbuffer, ptr, t);
! 616: newbuffer += t;
! 617: }
! 618: memcpy(newbuffer, plc->quoted, plc->qlen);
! 619: newbuffer += plc->qlen;
! 620: ptr = plc->pos + plc->len;
! 621:
! 622: plc = plc->next;
! 623: } while (plc);
! 624:
! 625: t = (inquery + inquery_len) - ptr;
! 626: if (t) {
! 627: memcpy(newbuffer, ptr, t);
! 628: newbuffer += t;
! 629: }
! 630: *newbuffer = '\0';
! 631: *outquery_len = newbuffer - *outquery;
! 632:
! 633: ret = 1;
! 634: goto clean_up;
! 635:
! 636: } else if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
! 637: /* rewrite ? to :pdoX */
! 638: char *name, *idxbuf;
! 639: const char *tmpl = stmt->named_rewrite_template ? stmt->named_rewrite_template : ":pdo%d";
! 640: int bind_no = 1;
! 641:
! 642: newbuffer_len = inquery_len;
! 643:
! 644: if (stmt->bound_param_map == NULL) {
! 645: ALLOC_HASHTABLE(stmt->bound_param_map);
! 646: zend_hash_init(stmt->bound_param_map, 13, NULL, NULL, 0);
! 647: }
! 648:
! 649: for (plc = placeholders; plc; plc = plc->next) {
! 650: int skip_map = 0;
! 651: char *p;
! 652: name = estrndup(plc->pos, plc->len);
! 653:
! 654: /* check if bound parameter is already available */
! 655: if (!strcmp(name, "?") || zend_hash_find(stmt->bound_param_map, name, plc->len + 1, (void**) &p) == FAILURE) {
! 656: spprintf(&idxbuf, 0, tmpl, bind_no++);
! 657: } else {
! 658: idxbuf = estrdup(p);
! 659: skip_map = 1;
! 660: }
! 661:
! 662: plc->quoted = idxbuf;
! 663: plc->qlen = strlen(plc->quoted);
! 664: plc->freeq = 1;
! 665: newbuffer_len += plc->qlen;
! 666:
! 667: if (!skip_map && stmt->named_rewrite_template) {
! 668: /* create a mapping */
! 669: zend_hash_update(stmt->bound_param_map, name, plc->len + 1, idxbuf, plc->qlen + 1, NULL);
! 670: }
! 671:
! 672: /* map number to name */
! 673: zend_hash_index_update(stmt->bound_param_map, plc->bindno, idxbuf, plc->qlen + 1, NULL);
! 674:
! 675: efree(name);
! 676: }
! 677:
! 678: goto rewrite;
! 679:
! 680: } else {
! 681: /* rewrite :name to ? */
! 682:
! 683: newbuffer_len = inquery_len;
! 684:
! 685: if (stmt->bound_param_map == NULL) {
! 686: ALLOC_HASHTABLE(stmt->bound_param_map);
! 687: zend_hash_init(stmt->bound_param_map, 13, NULL, NULL, 0);
! 688: }
! 689:
! 690: for (plc = placeholders; plc; plc = plc->next) {
! 691: char *name;
! 692:
! 693: name = estrndup(plc->pos, plc->len);
! 694: zend_hash_index_update(stmt->bound_param_map, plc->bindno, name, plc->len + 1, NULL);
! 695: efree(name);
! 696: plc->quoted = "?";
! 697: plc->qlen = 1;
! 698: }
! 699:
! 700: goto rewrite;
! 701: }
! 702:
! 703: clean_up:
! 704:
! 705: while (placeholders) {
! 706: plc = placeholders;
! 707: placeholders = plc->next;
! 708:
! 709: if (plc->freeq) {
! 710: efree(plc->quoted);
! 711: }
! 712:
! 713: efree(plc);
! 714: }
! 715:
! 716: return ret;
! 717: }
! 718:
! 719: #if 0
! 720: int old_pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery,
! 721: int *outquery_len TSRMLS_DC)
! 722: {
! 723: Scanner s;
! 724: char *ptr;
! 725: int t;
! 726: int bindno = 0;
! 727: int newbuffer_len;
! 728: int padding;
! 729: HashTable *params = stmt->bound_params;
! 730: struct pdo_bound_param_data *param;
! 731: /* allocate buffer for query with expanded binds, ptr is our writing pointer */
! 732: newbuffer_len = inquery_len;
! 733:
! 734: /* calculate the possible padding factor due to quoting */
! 735: if(stmt->dbh->max_escaped_char_length) {
! 736: padding = stmt->dbh->max_escaped_char_length;
! 737: } else {
! 738: padding = 3;
! 739: }
! 740: if(params) {
! 741: zend_hash_internal_pointer_reset(params);
! 742: while (SUCCESS == zend_hash_get_current_data(params, (void**)¶m)) {
! 743: if(param->parameter) {
! 744: convert_to_string(param->parameter);
! 745: /* accomodate a string that needs to be fully quoted
! 746: bind placeholders are at least 2 characters, so
! 747: the accomodate their own "'s
! 748: */
! 749: newbuffer_len += padding * Z_STRLEN_P(param->parameter);
! 750: }
! 751: zend_hash_move_forward(params);
! 752: }
! 753: }
! 754: *outquery = (char *) emalloc(newbuffer_len + 1);
! 755: *outquery_len = 0;
! 756:
! 757: ptr = *outquery;
! 758: s.cur = inquery;
! 759: while((t = scan(&s)) != PDO_PARSER_EOI) {
! 760: if(t == PDO_PARSER_TEXT) {
! 761: memcpy(ptr, s.tok, s.cur - s.tok);
! 762: ptr += (s.cur - s.tok);
! 763: *outquery_len += (s.cur - s.tok);
! 764: }
! 765: else if(t == PDO_PARSER_BIND) {
! 766: if(!params) {
! 767: /* error */
! 768: efree(*outquery);
! 769: *outquery = NULL;
! 770: return (int) (s.cur - inquery);
! 771: }
! 772: /* lookup bind first via hash and then index */
! 773: /* stupid keys need to be null-terminated, even though we know their length */
! 774: if((SUCCESS == zend_hash_find(params, s.tok, s.cur-s.tok,(void **)¶m))
! 775: ||
! 776: (SUCCESS == zend_hash_index_find(params, bindno, (void **)¶m)))
! 777: {
! 778: char *quotedstr;
! 779: int quotedstrlen;
! 780: /* restore the in-string key, doesn't need null-termination here */
! 781: /* currently everything is a string here */
! 782:
! 783: /* quote the bind value if necessary */
! 784: if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
! 785: Z_STRLEN_P(param->parameter), "edstr, "edstrlen TSRMLS_CC))
! 786: {
! 787: memcpy(ptr, quotedstr, quotedstrlen);
! 788: ptr += quotedstrlen;
! 789: *outquery_len += quotedstrlen;
! 790: efree(quotedstr);
! 791: } else {
! 792: memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
! 793: ptr += Z_STRLEN_P(param->parameter);
! 794: *outquery_len += (Z_STRLEN_P(param->parameter));
! 795: }
! 796: }
! 797: else {
! 798: /* error and cleanup */
! 799: efree(*outquery);
! 800: *outquery = NULL;
! 801: return (int) (s.cur - inquery);
! 802: }
! 803: bindno++;
! 804: }
! 805: else if(t == PDO_PARSER_BIND_POS) {
! 806: if(!params) {
! 807: /* error */
! 808: efree(*outquery);
! 809: *outquery = NULL;
! 810: return (int) (s.cur - inquery);
! 811: }
! 812: /* lookup bind by index */
! 813: if(SUCCESS == zend_hash_index_find(params, bindno, (void **)¶m))
! 814: {
! 815: char *quotedstr;
! 816: int quotedstrlen;
! 817: /* currently everything is a string here */
! 818:
! 819: /* quote the bind value if necessary */
! 820: if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
! 821: Z_STRLEN_P(param->parameter), "edstr, "edstrlen TSRMLS_CC))
! 822: {
! 823: memcpy(ptr, quotedstr, quotedstrlen);
! 824: ptr += quotedstrlen;
! 825: *outquery_len += quotedstrlen;
! 826: efree(quotedstr);
! 827: } else {
! 828: memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
! 829: ptr += Z_STRLEN_P(param->parameter);
! 830: *outquery_len += (Z_STRLEN_P(param->parameter));
! 831: }
! 832: }
! 833: else {
! 834: /* error and cleanup */
! 835: efree(*outquery);
! 836: *outquery = NULL;
! 837: return (int) (s.cur - inquery);
! 838: }
! 839: bindno++;
! 840: }
! 841: }
! 842: *ptr = '\0';
! 843: return 0;
! 844: }
! 845: #endif
! 846:
! 847: /*
! 848: * Local variables:
! 849: * tab-width: 4
! 850: * c-basic-offset: 4
! 851: * End:
! 852: * vim600: noet sw=4 ts=4 fdm=marker ft=c
! 853: * vim<600: noet sw=4 ts=4
! 854: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>