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