1: /* Generated by re2c 0.13.5 on Tue Aug 20 18:02:48 2013 */
2: /*
3: +----------------------------------------------------------------------+
4: | PHP Version 5 |
5: +----------------------------------------------------------------------+
6: | Copyright (c) 1997-2013 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,v 1.1.1.4 2013/10/14 08:02:24 misho Exp $ */
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**) ¶m) == 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**) ¶m);
530: } else {
531: ret = zend_hash_find(params, plc->pos, plc->len, (void**) ¶m);
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, ¶m->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: switch (Z_TYPE_P(param->parameter)) {
570: case IS_NULL:
571: plc->quoted = "NULL";
572: plc->qlen = sizeof("NULL")-1;
573: plc->freeq = 0;
574: break;
575:
576: case IS_BOOL:
577: convert_to_long(param->parameter);
578:
579: case IS_LONG:
580: case IS_DOUBLE:
581: convert_to_string(param->parameter);
582: plc->qlen = Z_STRLEN_P(param->parameter);
583: plc->quoted = Z_STRVAL_P(param->parameter);
584: plc->freeq = 0;
585: break;
586:
587: default:
588: convert_to_string(param->parameter);
589: if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
590: Z_STRLEN_P(param->parameter), &plc->quoted, &plc->qlen,
591: param->param_type TSRMLS_CC)) {
592: /* bork */
593: ret = -1;
594: strncpy(stmt->error_code, stmt->dbh->error_code, 6);
595: goto clean_up;
596: }
597: plc->freeq = 1;
598: }
599: }
600: } else {
601: plc->quoted = Z_STRVAL_P(param->parameter);
602: plc->qlen = Z_STRLEN_P(param->parameter);
603: }
604: newbuffer_len += plc->qlen;
605: }
606:
607: rewrite:
608: /* allocate output buffer */
609: newbuffer = emalloc(newbuffer_len + 1);
610: *outquery = newbuffer;
611:
612: /* and build the query */
613: plc = placeholders;
614: ptr = inquery;
615:
616: do {
617: t = plc->pos - ptr;
618: if (t) {
619: memcpy(newbuffer, ptr, t);
620: newbuffer += t;
621: }
622: memcpy(newbuffer, plc->quoted, plc->qlen);
623: newbuffer += plc->qlen;
624: ptr = plc->pos + plc->len;
625:
626: plc = plc->next;
627: } while (plc);
628:
629: t = (inquery + inquery_len) - ptr;
630: if (t) {
631: memcpy(newbuffer, ptr, t);
632: newbuffer += t;
633: }
634: *newbuffer = '\0';
635: *outquery_len = newbuffer - *outquery;
636:
637: ret = 1;
638: goto clean_up;
639:
640: } else if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
641: /* rewrite ? to :pdoX */
642: char *name, *idxbuf;
643: const char *tmpl = stmt->named_rewrite_template ? stmt->named_rewrite_template : ":pdo%d";
644: int bind_no = 1;
645:
646: newbuffer_len = inquery_len;
647:
648: if (stmt->bound_param_map == NULL) {
649: ALLOC_HASHTABLE(stmt->bound_param_map);
650: zend_hash_init(stmt->bound_param_map, 13, NULL, NULL, 0);
651: }
652:
653: for (plc = placeholders; plc; plc = plc->next) {
654: int skip_map = 0;
655: char *p;
656: name = estrndup(plc->pos, plc->len);
657:
658: /* check if bound parameter is already available */
659: if (!strcmp(name, "?") || zend_hash_find(stmt->bound_param_map, name, plc->len + 1, (void**) &p) == FAILURE) {
660: spprintf(&idxbuf, 0, tmpl, bind_no++);
661: } else {
662: idxbuf = estrdup(p);
663: skip_map = 1;
664: }
665:
666: plc->quoted = idxbuf;
667: plc->qlen = strlen(plc->quoted);
668: plc->freeq = 1;
669: newbuffer_len += plc->qlen;
670:
671: if (!skip_map && stmt->named_rewrite_template) {
672: /* create a mapping */
673: zend_hash_update(stmt->bound_param_map, name, plc->len + 1, idxbuf, plc->qlen + 1, NULL);
674: }
675:
676: /* map number to name */
677: zend_hash_index_update(stmt->bound_param_map, plc->bindno, idxbuf, plc->qlen + 1, NULL);
678:
679: efree(name);
680: }
681:
682: goto rewrite;
683:
684: } else {
685: /* rewrite :name to ? */
686:
687: newbuffer_len = inquery_len;
688:
689: if (stmt->bound_param_map == NULL) {
690: ALLOC_HASHTABLE(stmt->bound_param_map);
691: zend_hash_init(stmt->bound_param_map, 13, NULL, NULL, 0);
692: }
693:
694: for (plc = placeholders; plc; plc = plc->next) {
695: char *name;
696:
697: name = estrndup(plc->pos, plc->len);
698: zend_hash_index_update(stmt->bound_param_map, plc->bindno, name, plc->len + 1, NULL);
699: efree(name);
700: plc->quoted = "?";
701: plc->qlen = 1;
702: }
703:
704: goto rewrite;
705: }
706:
707: clean_up:
708:
709: while (placeholders) {
710: plc = placeholders;
711: placeholders = plc->next;
712:
713: if (plc->freeq) {
714: efree(plc->quoted);
715: }
716:
717: efree(plc);
718: }
719:
720: return ret;
721: }
722:
723: #if 0
724: int old_pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery,
725: int *outquery_len TSRMLS_DC)
726: {
727: Scanner s;
728: char *ptr;
729: int t;
730: int bindno = 0;
731: int newbuffer_len;
732: int padding;
733: HashTable *params = stmt->bound_params;
734: struct pdo_bound_param_data *param;
735: /* allocate buffer for query with expanded binds, ptr is our writing pointer */
736: newbuffer_len = inquery_len;
737:
738: /* calculate the possible padding factor due to quoting */
739: if(stmt->dbh->max_escaped_char_length) {
740: padding = stmt->dbh->max_escaped_char_length;
741: } else {
742: padding = 3;
743: }
744: if(params) {
745: zend_hash_internal_pointer_reset(params);
746: while (SUCCESS == zend_hash_get_current_data(params, (void**)¶m)) {
747: if(param->parameter) {
748: convert_to_string(param->parameter);
749: /* accommodate a string that needs to be fully quoted
750: bind placeholders are at least 2 characters, so
751: the accommodate their own "'s
752: */
753: newbuffer_len += padding * Z_STRLEN_P(param->parameter);
754: }
755: zend_hash_move_forward(params);
756: }
757: }
758: *outquery = (char *) emalloc(newbuffer_len + 1);
759: *outquery_len = 0;
760:
761: ptr = *outquery;
762: s.cur = inquery;
763: while((t = scan(&s)) != PDO_PARSER_EOI) {
764: if(t == PDO_PARSER_TEXT) {
765: memcpy(ptr, s.tok, s.cur - s.tok);
766: ptr += (s.cur - s.tok);
767: *outquery_len += (s.cur - s.tok);
768: }
769: else if(t == PDO_PARSER_BIND) {
770: if(!params) {
771: /* error */
772: efree(*outquery);
773: *outquery = NULL;
774: return (int) (s.cur - inquery);
775: }
776: /* lookup bind first via hash and then index */
777: /* stupid keys need to be null-terminated, even though we know their length */
778: if((SUCCESS == zend_hash_find(params, s.tok, s.cur-s.tok,(void **)¶m))
779: ||
780: (SUCCESS == zend_hash_index_find(params, bindno, (void **)¶m)))
781: {
782: char *quotedstr;
783: int quotedstrlen;
784: /* restore the in-string key, doesn't need null-termination here */
785: /* currently everything is a string here */
786:
787: /* quote the bind value if necessary */
788: if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
789: Z_STRLEN_P(param->parameter), "edstr, "edstrlen TSRMLS_CC))
790: {
791: memcpy(ptr, quotedstr, quotedstrlen);
792: ptr += quotedstrlen;
793: *outquery_len += quotedstrlen;
794: efree(quotedstr);
795: } else {
796: memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
797: ptr += Z_STRLEN_P(param->parameter);
798: *outquery_len += (Z_STRLEN_P(param->parameter));
799: }
800: }
801: else {
802: /* error and cleanup */
803: efree(*outquery);
804: *outquery = NULL;
805: return (int) (s.cur - inquery);
806: }
807: bindno++;
808: }
809: else if(t == PDO_PARSER_BIND_POS) {
810: if(!params) {
811: /* error */
812: efree(*outquery);
813: *outquery = NULL;
814: return (int) (s.cur - inquery);
815: }
816: /* lookup bind by index */
817: if(SUCCESS == zend_hash_index_find(params, bindno, (void **)¶m))
818: {
819: char *quotedstr;
820: int quotedstrlen;
821: /* currently everything is a string here */
822:
823: /* quote the bind value if necessary */
824: if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
825: Z_STRLEN_P(param->parameter), "edstr, "edstrlen TSRMLS_CC))
826: {
827: memcpy(ptr, quotedstr, quotedstrlen);
828: ptr += quotedstrlen;
829: *outquery_len += quotedstrlen;
830: efree(quotedstr);
831: } else {
832: memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
833: ptr += Z_STRLEN_P(param->parameter);
834: *outquery_len += (Z_STRLEN_P(param->parameter));
835: }
836: }
837: else {
838: /* error and cleanup */
839: efree(*outquery);
840: *outquery = NULL;
841: return (int) (s.cur - inquery);
842: }
843: bindno++;
844: }
845: }
846: *ptr = '\0';
847: return 0;
848: }
849: #endif
850:
851: /*
852: * Local variables:
853: * tab-width: 4
854: * c-basic-offset: 4
855: * End:
856: * vim600: noet sw=4 ts=4 fdm=marker ft=c
857: * vim<600: noet sw=4 ts=4
858: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>