1 /* Generated by re2c 0.13.5 */
2 #line 1 "ext/pdo/pdo_sql_parser.re"
3 /*
4 +----------------------------------------------------------------------+
5 | PHP Version 7 |
6 +----------------------------------------------------------------------+
7 | Copyright (c) 1997-2017 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 size_t len;
386 int bindno;
387 size_t qlen; /* quoted length of value */
388 char *quoted; /* quoted value */
389 int freeq;
390 struct placeholder *next;
391 };
392
free_param_name(zval * el)393 static void free_param_name(zval *el) {
394 efree(Z_PTR_P(el));
395 }
396
pdo_parse_params(pdo_stmt_t * stmt,char * inquery,size_t inquery_len,char ** outquery,size_t * outquery_len)397 PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, size_t inquery_len,
398 char **outquery, size_t *outquery_len)
399 {
400 Scanner s;
401 char *ptr, *newbuffer;
402 int t;
403 int bindno = 0;
404 int ret = 0;
405 size_t newbuffer_len;
406 HashTable *params;
407 struct pdo_bound_param_data *param;
408 int query_type = PDO_PLACEHOLDER_NONE;
409 struct placeholder *placeholders = NULL, *placetail = NULL, *plc = NULL;
410
411 ptr = *outquery;
412 s.cur = inquery;
413 s.end = inquery + inquery_len + 1;
414
415 /* phase 1: look for args */
416 while((t = scan(&s)) != PDO_PARSER_EOI) {
417 if (t == PDO_PARSER_BIND || t == PDO_PARSER_BIND_POS) {
418 if (t == PDO_PARSER_BIND) {
419 int len = s.cur - s.tok;
420 if ((inquery < (s.cur - len)) && isalnum(*(s.cur - len - 1))) {
421 continue;
422 }
423 query_type |= PDO_PLACEHOLDER_NAMED;
424 } else {
425 query_type |= PDO_PLACEHOLDER_POSITIONAL;
426 }
427
428 plc = emalloc(sizeof(*plc));
429 memset(plc, 0, sizeof(*plc));
430 plc->next = NULL;
431 plc->pos = s.tok;
432 plc->len = s.cur - s.tok;
433 plc->bindno = bindno++;
434
435 if (placetail) {
436 placetail->next = plc;
437 } else {
438 placeholders = plc;
439 }
440 placetail = plc;
441 }
442 }
443
444 if (bindno == 0) {
445 /* nothing to do; good! */
446 return 0;
447 }
448
449 /* did the query make sense to me? */
450 if (query_type == (PDO_PLACEHOLDER_NAMED|PDO_PLACEHOLDER_POSITIONAL)) {
451 /* they mixed both types; punt */
452 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "mixed named and positional parameters");
453 ret = -1;
454 goto clean_up;
455 }
456
457 if (stmt->supports_placeholders == query_type && !stmt->named_rewrite_template) {
458 /* query matches native syntax */
459 ret = 0;
460 goto clean_up;
461 }
462
463 if (stmt->named_rewrite_template) {
464 /* magic/hack.
465 * We we pretend that the query was positional even if
466 * it was named so that we fall into the
467 * named rewrite case below. Not too pretty,
468 * but it works. */
469 query_type = PDO_PLACEHOLDER_POSITIONAL;
470 }
471
472 params = stmt->bound_params;
473
474 /* Do we have placeholders but no bound params */
475 if (bindno && !params && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
476 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "no parameters were bound");
477 ret = -1;
478 goto clean_up;
479 }
480
481 if (params && bindno != zend_hash_num_elements(params) && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
482 /* extra bit of validation for instances when same params are bound more than once */
483 if (query_type != PDO_PLACEHOLDER_POSITIONAL && bindno > zend_hash_num_elements(params)) {
484 int ok = 1;
485 for (plc = placeholders; plc; plc = plc->next) {
486 if ((param = zend_hash_str_find_ptr(params, plc->pos, plc->len)) == NULL) {
487 ok = 0;
488 break;
489 }
490 }
491 if (ok) {
492 goto safe;
493 }
494 }
495 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "number of bound variables does not match number of tokens");
496 ret = -1;
497 goto clean_up;
498 }
499 safe:
500 /* what are we going to do ? */
501 if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
502 /* query generation */
503
504 newbuffer_len = inquery_len;
505
506 /* let's quote all the values */
507 for (plc = placeholders; plc; plc = plc->next) {
508 if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
509 param = zend_hash_index_find_ptr(params, plc->bindno);
510 } else {
511 param = zend_hash_str_find_ptr(params, plc->pos, plc->len);
512 }
513 if (param == NULL) {
514 /* parameter was not defined */
515 ret = -1;
516 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined");
517 goto clean_up;
518 }
519 if (stmt->dbh->methods->quoter) {
520 zval *parameter;
521 if (Z_ISREF(param->parameter)) {
522 parameter = Z_REFVAL(param->parameter);
523 } else {
524 parameter = ¶m->parameter;
525 }
526 if (param->param_type == PDO_PARAM_LOB && Z_TYPE_P(parameter) == IS_RESOURCE) {
527 php_stream *stm;
528
529 php_stream_from_zval_no_verify(stm, parameter);
530 if (stm) {
531 zend_string *buf;
532
533 buf = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0);
534 if (!buf) {
535 buf = ZSTR_EMPTY_ALLOC();
536 }
537 if (!stmt->dbh->methods->quoter(stmt->dbh, ZSTR_VAL(buf), ZSTR_LEN(buf), &plc->quoted, &plc->qlen,
538 param->param_type)) {
539 /* bork */
540 ret = -1;
541 strncpy(stmt->error_code, stmt->dbh->error_code, 6);
542 if (buf) {
543 zend_string_release(buf);
544 }
545 goto clean_up;
546 }
547 if (buf) {
548 zend_string_release(buf);
549 }
550 } else {
551 pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource");
552 ret = -1;
553 goto clean_up;
554 }
555 plc->freeq = 1;
556 } else {
557 zval tmp_param;
558 ZVAL_DUP(&tmp_param, parameter);
559 switch (Z_TYPE(tmp_param)) {
560 case IS_NULL:
561 plc->quoted = "NULL";
562 plc->qlen = sizeof("NULL")-1;
563 plc->freeq = 0;
564 break;
565
566 case IS_FALSE:
567 case IS_TRUE:
568 convert_to_long(&tmp_param);
569 /* fall through */
570 case IS_LONG:
571 case IS_DOUBLE:
572 convert_to_string(&tmp_param);
573 plc->qlen = Z_STRLEN(tmp_param);
574 plc->quoted = estrdup(Z_STRVAL(tmp_param));
575 plc->freeq = 1;
576 break;
577
578 default:
579 convert_to_string(&tmp_param);
580 if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL(tmp_param),
581 Z_STRLEN(tmp_param), &plc->quoted, &plc->qlen,
582 param->param_type)) {
583 /* bork */
584 ret = -1;
585 strncpy(stmt->error_code, stmt->dbh->error_code, 6);
586 goto clean_up;
587 }
588 plc->freeq = 1;
589 }
590 zval_dtor(&tmp_param);
591 }
592 } else {
593 zval *parameter;
594 if (Z_ISREF(param->parameter)) {
595 parameter = Z_REFVAL(param->parameter);
596 } else {
597 parameter = ¶m->parameter;
598 }
599 plc->quoted = Z_STRVAL_P(parameter);
600 plc->qlen = Z_STRLEN_P(parameter);
601 }
602 newbuffer_len += plc->qlen;
603 }
604
605 rewrite:
606 /* allocate output buffer */
607 newbuffer = emalloc(newbuffer_len + 1);
608 *outquery = newbuffer;
609
610 /* and build the query */
611 plc = placeholders;
612 ptr = inquery;
613
614 do {
615 t = plc->pos - ptr;
616 if (t) {
617 memcpy(newbuffer, ptr, t);
618 newbuffer += t;
619 }
620 memcpy(newbuffer, plc->quoted, plc->qlen);
621 newbuffer += plc->qlen;
622 ptr = plc->pos + plc->len;
623
624 plc = plc->next;
625 } while (plc);
626
627 t = (inquery + inquery_len) - ptr;
628 if (t) {
629 memcpy(newbuffer, ptr, t);
630 newbuffer += t;
631 }
632 *newbuffer = '\0';
633 *outquery_len = newbuffer - *outquery;
634
635 ret = 1;
636 goto clean_up;
637
638 } else if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
639 /* rewrite ? to :pdoX */
640 char *name, *idxbuf;
641 const char *tmpl = stmt->named_rewrite_template ? stmt->named_rewrite_template : ":pdo%d";
642 int bind_no = 1;
643
644 newbuffer_len = inquery_len;
645
646 if (stmt->bound_param_map == NULL) {
647 ALLOC_HASHTABLE(stmt->bound_param_map);
648 zend_hash_init(stmt->bound_param_map, 13, NULL, free_param_name, 0);
649 }
650
651 for (plc = placeholders; plc; plc = plc->next) {
652 int skip_map = 0;
653 char *p;
654 name = estrndup(plc->pos, plc->len);
655
656 /* check if bound parameter is already available */
657 if (!strcmp(name, "?") || (p = zend_hash_str_find_ptr(stmt->bound_param_map, name, plc->len)) == NULL) {
658 spprintf(&idxbuf, 0, tmpl, bind_no++);
659 } else {
660 idxbuf = estrdup(p);
661 skip_map = 1;
662 }
663
664 plc->quoted = idxbuf;
665 plc->qlen = strlen(plc->quoted);
666 plc->freeq = 1;
667 newbuffer_len += plc->qlen;
668
669 if (!skip_map && stmt->named_rewrite_template) {
670 /* create a mapping */
671 zend_hash_str_update_mem(stmt->bound_param_map, name, plc->len, idxbuf, plc->qlen + 1);
672 }
673
674 /* map number to name */
675 zend_hash_index_update_mem(stmt->bound_param_map, plc->bindno, idxbuf, plc->qlen + 1);
676
677 efree(name);
678 }
679
680 goto rewrite;
681
682 } else {
683 /* rewrite :name to ? */
684
685 newbuffer_len = inquery_len;
686
687 if (stmt->bound_param_map == NULL) {
688 ALLOC_HASHTABLE(stmt->bound_param_map);
689 zend_hash_init(stmt->bound_param_map, 13, NULL, free_param_name, 0);
690 }
691
692 for (plc = placeholders; plc; plc = plc->next) {
693 char *name;
694 name = estrndup(plc->pos, plc->len);
695 zend_hash_index_update_mem(stmt->bound_param_map, plc->bindno, name, plc->len + 1);
696 efree(name);
697 plc->quoted = "?";
698 plc->qlen = 1;
699 }
700
701 goto rewrite;
702 }
703
704 clean_up:
705
706 while (placeholders) {
707 plc = placeholders;
708 placeholders = plc->next;
709
710 if (plc->freeq) {
711 efree(plc->quoted);
712 }
713
714 efree(plc);
715 }
716
717 return ret;
718 }
719
720 #if 0
721 int old_pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery,
722 int *outquery_len)
723 {
724 Scanner s;
725 char *ptr;
726 int t;
727 int bindno = 0;
728 int newbuffer_len;
729 int padding;
730 HashTable *params = stmt->bound_params;
731 struct pdo_bound_param_data *param;
732 /* allocate buffer for query with expanded binds, ptr is our writing pointer */
733 newbuffer_len = inquery_len;
734
735 /* calculate the possible padding factor due to quoting */
736 if(stmt->dbh->max_escaped_char_length) {
737 padding = stmt->dbh->max_escaped_char_length;
738 } else {
739 padding = 3;
740 }
741 if(params) {
742 ZEND_HASH_FOREACH_PTR(params, param) {
743 if(param->parameter) {
744 convert_to_string(param->parameter);
745 /* accommodate a string that needs to be fully quoted
746 bind placeholders are at least 2 characters, so
747 the accommodate their own "'s
748 */
749 newbuffer_len += padding * Z_STRLEN_P(param->parameter);
750 }
751 } ZEND_HASH_FOREACH_END();
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((NULL != (param = zend_hash_str_find_ptr(params, s.tok, s.cur-s.tok))
774 ||
775 NULL != (params = zend_hash_index_find_ptr(params, bindno)))
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))
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(NULL != (params = zend_hash_index_find_ptr(params, bindno)))
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))
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 */
854