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