1/* Generated by re2c 0.13.5 */
2/*
3 +----------------------------------------------------------------------+
4 | PHP Version 5 |
5 +----------------------------------------------------------------------+
6 | Copyright (c) 1997-2015 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
40typedef struct Scanner {
41 char *ptr, *cur, *tok, *end;
42} Scanner;
43
44static 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 }
68yy2:
69 YYCURSOR = YYMARKER;
70 switch (yyaccept) {
71 case 0: goto yy4;
72 case 1: goto yy10;
73 }
74yy3:
75 yyaccept = 0;
76 yych = *(YYMARKER = ++YYCURSOR);
77 if (yych >= 0x01) goto yy43;
78yy4:
79 { SKIP_ONE(PDO_PARSER_TEXT); }
80yy5:
81 yyaccept = 0;
82 yych = *(YYMARKER = ++YYCURSOR);
83 if (yych <= 0x00) goto yy4;
84 goto yy38;
85yy6:
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 }
154yy7:
155 ++YYCURSOR;
156 switch ((yych = *YYCURSOR)) {
157 case '?': goto yy29;
158 default: goto yy8;
159 }
160yy8:
161 { RET(PDO_PARSER_BIND_POS); }
162yy9:
163 ++YYCURSOR;
164 switch ((yych = *YYCURSOR)) {
165 case '*': goto yy19;
166 default: goto yy13;
167 }
168yy10:
169 { RET(PDO_PARSER_TEXT); }
170yy11:
171 yych = *++YYCURSOR;
172 switch (yych) {
173 case '-': goto yy14;
174 default: goto yy13;
175 }
176yy12:
177 ++YYCURSOR;
178 if (YYLIMIT <= YYCURSOR) YYFILL(1);
179 yych = *YYCURSOR;
180yy13:
181 switch (yych) {
182 case 0x00:
183 case '"':
184 case '\'':
185 case ':':
186 case '?': goto yy10;
187 default: goto yy12;
188 }
189yy14:
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 }
203yy16:
204 { RET(PDO_PARSER_TEXT); }
205yy17:
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 }
214yy19:
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 }
228yy21:
229 ++YYCURSOR;
230 if (YYLIMIT <= YYCURSOR) YYFILL(1);
231 yych = *YYCURSOR;
232 switch (yych) {
233 case '*': goto yy26;
234 default: goto yy21;
235 }
236yy23:
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 }
251yy25:
252 yych = *++YYCURSOR;
253 switch (yych) {
254 case 0x00:
255 case '"':
256 case '\'':
257 case ':':
258 case '?': goto yy16;
259 default: goto yy12;
260 }
261yy26:
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 }
270yy28:
271 yych = *++YYCURSOR;
272 goto yy16;
273yy29:
274 ++YYCURSOR;
275 if (YYLIMIT <= YYCURSOR) YYFILL(1);
276 yych = *YYCURSOR;
277 switch (yych) {
278 case '?': goto yy29;
279 default: goto yy31;
280 }
281yy31:
282 { RET(PDO_PARSER_TEXT); }
283yy32:
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 }
353yy34:
354 { RET(PDO_PARSER_BIND); }
355yy35:
356 ++YYCURSOR;
357 if (YYLIMIT <= YYCURSOR) YYFILL(1);
358 yych = *YYCURSOR;
359 switch (yych) {
360 case ':': goto yy35;
361 default: goto yy31;
362 }
363yy37:
364 ++YYCURSOR;
365 if (YYLIMIT <= YYCURSOR) YYFILL(1);
366 yych = *YYCURSOR;
367yy38:
368 switch (yych) {
369 case 0x00: goto yy2;
370 case '\'': goto yy40;
371 case '\\': goto yy39;
372 default: goto yy37;
373 }
374yy39:
375 ++YYCURSOR;
376 if (YYLIMIT <= YYCURSOR) YYFILL(1);
377 yych = *YYCURSOR;
378 if (yych <= 0x00) goto yy2;
379 goto yy37;
380yy40:
381 ++YYCURSOR;
382 { RET(PDO_PARSER_TEXT); }
383yy42:
384 ++YYCURSOR;
385 if (YYLIMIT <= YYCURSOR) YYFILL(1);
386 yych = *YYCURSOR;
387yy43:
388 switch (yych) {
389 case 0x00: goto yy2;
390 case '"': goto yy45;
391 case '\\': goto yy44;
392 default: goto yy42;
393 }
394yy44:
395 ++YYCURSOR;
396 if (YYLIMIT <= YYCURSOR) YYFILL(1);
397 yych = *YYCURSOR;
398 if (yych <= 0x00) goto yy2;
399 goto yy42;
400yy45:
401 ++YYCURSOR;
402 { RET(PDO_PARSER_TEXT); }
403}
404
405}
406
407struct 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
417PDO_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 }
519safe:
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
610rewrite:
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
710clean_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
727int 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 */
862