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