summaryrefslogtreecommitdiff
path: root/ext/pdo
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo')
-rwxr-xr-xext/pdo/pdo.c4
-rwxr-xr-xext/pdo/pdo_dbh.c15
-rw-r--r--ext/pdo/pdo_sql_parser.c366
-rw-r--r--ext/pdo/pdo_sql_parser.c.orig396
-rw-r--r--ext/pdo/pdo_sql_parser.re58
-rw-r--r--ext/pdo/pdo_sqlstate.c4
-rwxr-xr-xext/pdo/pdo_stmt.c71
-rwxr-xr-xext/pdo/php_pdo.h4
-rwxr-xr-xext/pdo/php_pdo_driver.h4
-rwxr-xr-xext/pdo/php_pdo_int.h4
-rw-r--r--ext/pdo/tests/bug_36798.phpt32
-rw-r--r--ext/pdo/tests/bug_39398.phpt35
-rw-r--r--ext/pdo/tests/bug_39656.phpt50
-rw-r--r--ext/pdo/tests/bug_40285.phpt27
-rw-r--r--ext/pdo/tests/pdo_016.phpt4
-rwxr-xr-xext/pdo/tests/pdo_016a.phpt4
-rw-r--r--ext/pdo/tests/pdo_021.phpt4
17 files changed, 555 insertions, 527 deletions
diff --git a/ext/pdo/pdo.c b/ext/pdo/pdo.c
index d6786c4c8..c30ace636 100755
--- a/ext/pdo/pdo.c
+++ b/ext/pdo/pdo.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pdo.c,v 1.57.2.17.2.7 2006/10/14 15:06:11 bjori Exp $ */
+/* $Id: pdo.c,v 1.57.2.17.2.8 2007/01/01 09:36:04 sebastian Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c
index ec6d88041..116b37c9a 100755
--- a/ext/pdo/pdo_dbh.c
+++ b/ext/pdo/pdo_dbh.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pdo_dbh.c,v 1.82.2.31.2.7 2006/08/21 16:53:50 iliaa Exp $ */
+/* $Id: pdo_dbh.c,v 1.82.2.31.2.10 2007/04/29 14:47:34 iliaa Exp $ */
/* The PDO Database Handle Class */
@@ -706,6 +706,15 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_D
return SUCCESS;
case PDO_ATTR_DEFAULT_FETCH_MODE:
+ if (Z_TYPE_P(value) == IS_ARRAY) {
+ zval **tmp;
+ if (zend_hash_index_find(Z_ARRVAL_P(value), 0, (void**)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_LONG) {
+ if (Z_LVAL_PP(tmp) == PDO_FETCH_INTO || Z_LVAL_PP(tmp) == PDO_FETCH_CLASS) {
+ pdo_raise_impl_error(dbh, NULL, "HY000", "FETCH_INTO and FETCH_CLASS are not yet supported as default fetch modes" TSRMLS_CC);
+ return FAILURE;
+ }
+ }
+ }
convert_to_long(value);
if (Z_LVAL_P(value) == PDO_FETCH_USE_DEFAULT) {
pdo_raise_impl_error(dbh, NULL, "HY000", "invalid fetch mode type" TSRMLS_CC);
@@ -814,7 +823,7 @@ static PHP_METHOD(PDO, setAttribute)
PDO_CONSTRUCT_CHECK;
- if (pdo_dbh_attribute_set(dbh, attr, value TSRMLS_CC)) {
+ if (pdo_dbh_attribute_set(dbh, attr, value TSRMLS_CC) != FAILURE) {
RETURN_TRUE;
}
RETURN_FALSE;
diff --git a/ext/pdo/pdo_sql_parser.c b/ext/pdo/pdo_sql_parser.c
index e3e6541e4..10db41cd4 100644
--- a/ext/pdo/pdo_sql_parser.c
+++ b/ext/pdo/pdo_sql_parser.c
@@ -1,9 +1,9 @@
-/* Generated by re2c 0.9.11 on Wed Jan 25 11:31:13 2006 */
+/* Generated by re2c 0.11.0 on Mon Mar 5 19:42:28 2007 */
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pdo_sql_parser.c,v 1.35.2.6 2006/01/25 16:35:23 iliaa Exp $ */
+/* $Id: pdo_sql_parser.c,v 1.35.2.6.2.11 2007/03/06 00:52:55 iliaa Exp $ */
#include "php.h"
#include "php_pdo_driver.h"
@@ -30,14 +30,14 @@
#define RET(i) {s->cur = cursor; return i; }
-#define YYCTYPE char
+#define YYCTYPE unsigned char
#define YYCURSOR cursor
-#define YYLIMIT s->lim
+#define YYLIMIT cursor
#define YYMARKER s->ptr
#define YYFILL(n)
typedef struct Scanner {
- char *lim, *ptr, *cur, *tok;
+ char *ptr, *cur, *tok;
} Scanner;
static int scan(Scanner *s)
@@ -49,224 +49,123 @@ static int scan(Scanner *s)
{
static unsigned char yybm[] = {
- 0, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 52, 162, 162, 162, 162, 196,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 170, 170, 170, 170, 170, 170, 170, 170,
- 170, 170, 244, 162, 162, 162, 162, 244,
- 162, 170, 170, 170, 170, 170, 170, 170,
- 170, 170, 170, 170, 170, 170, 170, 170,
- 170, 170, 170, 170, 170, 170, 170, 170,
- 170, 170, 170, 162, 2, 162, 162, 170,
- 162, 170, 170, 170, 170, 170, 170, 170,
- 170, 170, 170, 170, 170, 170, 170, 170,
- 170, 170, 170, 170, 170, 170, 170, 170,
- 170, 170, 170, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
+ 192, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 64, 200, 200, 200, 200, 128,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 208, 200, 200, 200, 200, 208,
+ 200, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 232, 200, 200, 200, 200, 232,
+ 200, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 232, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
};
-{
- YYCTYPE yych;
- unsigned int yyaccept = 0;
- goto yy0;
- ++YYCURSOR;
-yy0:
- if((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
- yych = *YYCURSOR;
- if(yybm[0+yych] & 2) {
- goto yy8;
- }
- if(yych <= 0x00) goto yy11;
- if(yych <= '&') goto yy2;
- if(yych <= '\'') goto yy4;
- if(yych <= '>') goto yy5;
- goto yy6;
-yy2: yyaccept = 0;
- yych = *(YYMARKER = ++YYCURSOR);
- if(yybm[0+yych] & 64) {
- goto yy30;
- }
- if(yych <= 0x00) goto yy3;
- if(yych == '"') goto yy28;
- goto yy33;
+ {
+ YYCTYPE yych;
+
+ if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if(yybm[0+yych] & 8) {
+ goto yy8;
+ }
+ if(yych <= 0x00) goto yy11;
+ if(yych <= '&') goto yy2;
+ if(yych <= '\'') goto yy4;
+ if(yych <= '>') goto yy5;
+ goto yy6;
+yy2:
+ yych = *++YYCURSOR;
+ goto yy24;
yy3:
-{ RET(PDO_PARSER_TEXT); }
-yy4: yyaccept = 0;
- yych = *(YYMARKER = ++YYCURSOR);
- if(yybm[0+yych] & 16) {
- goto yy19;
- }
- if(yych <= 0x00) goto yy3;
- if(yych == '\'') goto yy21;
- goto yy24;
-yy5: yych = *++YYCURSOR;
- if(yybm[0+yych] & 4) {
- goto yy13;
- }
- if(yych <= 'Z'){
- if(yych <= '/') goto yy3;
- if(yych <= ':') goto yy16;
- if(yych <= '@') goto yy3;
- goto yy16;
- } else {
- if(yych <= '_'){
- if(yych <= '^') goto yy3;
+ { RET(PDO_PARSER_TEXT); }
+yy4:
+ yych = *++YYCURSOR;
+ goto yy20;
+yy5:
+ yych = *++YYCURSOR;
+ if(yybm[0+yych] & 32) {
goto yy16;
- } else {
- if(yych <= '`') goto yy3;
- if(yych <= 'z') goto yy16;
- goto yy3;
}
- }
-yy6: ++YYCURSOR;
- if(yybm[0+(yych = *YYCURSOR)] & 4) {
+ if(yych == ':') goto yy13;
+ if(yych == '?') goto yy13;
+ goto yy3;
+yy6:
+ ++YYCURSOR;
+ if(yybm[0+(yych = *YYCURSOR)] & 16) {
+ goto yy13;
+ }
+ { RET(PDO_PARSER_BIND_POS); }
+yy8:
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- goto yy13;
- }
- goto yy7;
-yy7:
-{ RET(PDO_PARSER_BIND_POS); }
-yy8: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- goto yy9;
-yy9: if(yybm[0+yych] & 2) {
- goto yy8;
- }
- goto yy10;
-yy10:
-{ RET(PDO_PARSER_TEXT); }
-yy11: ++YYCURSOR;
- goto yy12;
-yy12:
-{ RET(PDO_PARSER_EOI); }
-yy13: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- goto yy14;
-yy14: if(yybm[0+yych] & 4) {
- goto yy13;
- }
- goto yy15;
-yy15:
-{ RET(PDO_PARSER_TEXT); }
-yy16: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- goto yy17;
-yy17: if(yybm[0+yych] & 8) {
- goto yy16;
- }
- goto yy18;
-yy18:
-{ RET(PDO_PARSER_BIND); }
-yy19: yyaccept = 1;
- YYMARKER = ++YYCURSOR;
- if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
- yych = *YYCURSOR;
- goto yy20;
-yy20: if(yybm[0+yych] & 16) {
- goto yy19;
- }
- if(yych <= '\''){
- if(yych <= 0x00) goto yy15;
- if(yych <= '&') goto yy23;
- goto yy21;
- } else {
- if(yych == '\\') goto yy26;
- goto yy23;
- }
-yy21: ++YYCURSOR;
- if(yybm[0+(yych = *YYCURSOR)] & 4) {
+ if(yybm[0+yych] & 8) {
+ goto yy8;
+ }
+ { RET(PDO_PARSER_TEXT); }
+yy11:
+ ++YYCURSOR;
+ { RET(PDO_PARSER_EOI); }
+yy13:
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- goto yy13;
- }
- goto yy22;
-yy22:
-{ RET(PDO_PARSER_TEXT); }
-yy23: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- goto yy24;
-yy24: if(yybm[0+yych] & 32) {
- goto yy23;
- }
- if(yych <= 0x00) goto yy25;
- if(yych <= '[') goto yy27;
- goto yy26;
-yy25: YYCURSOR = YYMARKER;
- switch(yyaccept){
- case 1: goto yy15;
- case 0: goto yy3;
- }
-yy26: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- if(yych == '\'') goto yy23;
- goto yy25;
-yy27: yych = *++YYCURSOR;
- goto yy22;
-yy28: ++YYCURSOR;
- if(yybm[0+(yych = *YYCURSOR)] & 4) {
+ if(yybm[0+yych] & 16) {
+ goto yy13;
+ }
+ { RET(PDO_PARSER_TEXT); }
+yy16:
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- goto yy13;
- }
- goto yy29;
-yy29:
-{ RET(PDO_PARSER_TEXT); }
-yy30: yyaccept = 1;
- YYMARKER = ++YYCURSOR;
- if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
- yych = *YYCURSOR;
- goto yy31;
-yy31: if(yybm[0+yych] & 64) {
- goto yy30;
- }
- if(yych <= '"'){
- if(yych <= 0x00) goto yy15;
- if(yych >= '"') goto yy28;
- goto yy32;
- } else {
- if(yych == '\\') goto yy34;
- goto yy32;
- }
-yy32: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- goto yy33;
-yy33: if(yybm[0+yych] & 128) {
- goto yy32;
+ if(yybm[0+yych] & 32) {
+ goto yy16;
+ }
+ { RET(PDO_PARSER_BIND); }
+yy19:
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy20:
+ if(yybm[0+yych] & 64) {
+ goto yy19;
+ }
+ ++YYCURSOR;
+ { RET(PDO_PARSER_TEXT); }
+yy23:
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy24:
+ if(yybm[0+yych] & 128) {
+ goto yy23;
+ }
+ ++YYCURSOR;
+ { RET(PDO_PARSER_TEXT); }
}
- if(yych <= 0x00) goto yy25;
- if(yych <= '[') goto yy35;
- goto yy34;
-yy34: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- if(yych == '"') goto yy32;
- goto yy25;
-yy35: ++YYCURSOR;
- yych = *YYCURSOR;
- goto yy29;
-}
}
}
@@ -297,7 +196,6 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
ptr = *outquery;
s.cur = inquery;
- s.lim = inquery + inquery_len;
/* phase 1: look for args */
while((t = scan(&s)) != PDO_PARSER_EOI) {
@@ -333,10 +231,10 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
if (query_type == (PDO_PLACEHOLDER_NAMED|PDO_PLACEHOLDER_POSITIONAL)) {
/* they mixed both types; punt */
pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "mixed named and positional parameters" TSRMLS_CC);
- return -1;
+ ret = -1;
+ goto clean_up;
}
-
if (stmt->supports_placeholders == query_type && !stmt->named_rewrite_template) {
/* query matches native syntax */
ret = 0;
@@ -360,9 +258,27 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
ret = -1;
goto clean_up;
}
-
+
+ if (params && bindno != zend_hash_num_elements(params) && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
+ /* extra bit of validation for instances when same params are bound more then once */
+ if (query_type != PDO_PLACEHOLDER_POSITIONAL && bindno > zend_hash_num_elements(params)) {
+ int ok = 1;
+ for (plc = placeholders; plc; plc = plc->next) {
+ if (zend_hash_find(params, plc->pos, plc->len, (void**) &param) == FAILURE) {
+ ok = 0;
+ break;
+ }
+ }
+ if (ok) {
+ goto safe;
+ }
+ }
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "number of bound variables does not match number of tokens" TSRMLS_CC);
+ ret = -1;
+ goto clean_up;
+ }
+safe:
/* what are we going to do ? */
-
if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
/* query generation */
@@ -396,11 +312,14 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
/* bork */
ret = -1;
strcpy(stmt->error_code, stmt->dbh->error_code);
- efree(buf);
+ if (buf) {
+ efree(buf);
+ }
goto clean_up;
}
- efree(buf);
-
+ if (buf) {
+ efree(buf);
+ }
} else {
pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource" TSRMLS_CC);
ret = -1;
@@ -603,7 +522,6 @@ int old_pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char
ptr = *outquery;
s.cur = inquery;
- s.lim = inquery + inquery_len;
while((t = scan(&s)) != PDO_PARSER_EOI) {
if(t == PDO_PARSER_TEXT) {
memcpy(ptr, s.tok, s.cur - s.tok);
diff --git a/ext/pdo/pdo_sql_parser.c.orig b/ext/pdo/pdo_sql_parser.c.orig
index b5ca7203c..5b22830c2 100644
--- a/ext/pdo/pdo_sql_parser.c.orig
+++ b/ext/pdo/pdo_sql_parser.c.orig
@@ -1,10 +1,10 @@
-/* Generated by re2c 0.9.11 on Wed Jan 25 11:31:13 2006 */
+/* Generated by re2c 0.11.0 on Mon Mar 5 19:42:28 2007 */
#line 1 "ext/pdo/pdo_sql_parser.re"
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pdo_sql_parser.c,v 1.35.2.6 2006/01/25 16:35:23 iliaa Exp $ */
+/* $Id: pdo_sql_parser.c,v 1.35.2.6.2.11 2007/03/06 00:52:55 iliaa Exp $ */
#include "php.h"
#include "php_pdo_driver.h"
@@ -31,14 +31,14 @@
#define RET(i) {s->cur = cursor; return i; }
-#define YYCTYPE char
+#define YYCTYPE unsigned char
#define YYCURSOR cursor
-#define YYLIMIT s->lim
+#define YYLIMIT cursor
#define YYMARKER s->ptr
#define YYFILL(n)
typedef struct Scanner {
- char *lim, *ptr, *cur, *tok;
+ char *ptr, *cur, *tok;
} Scanner;
static int scan(Scanner *s)
@@ -46,248 +46,147 @@ static int scan(Scanner *s)
char *cursor = s->cur;
s->tok = cursor;
- #line 55 "ext/pdo/pdo_sql_parser.re"
+ #line 54 "ext/pdo/pdo_sql_parser.re"
{
static unsigned char yybm[] = {
- 0, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 52, 162, 162, 162, 162, 196,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 170, 170, 170, 170, 170, 170, 170, 170,
- 170, 170, 244, 162, 162, 162, 162, 244,
- 162, 170, 170, 170, 170, 170, 170, 170,
- 170, 170, 170, 170, 170, 170, 170, 170,
- 170, 170, 170, 170, 170, 170, 170, 170,
- 170, 170, 170, 162, 2, 162, 162, 170,
- 162, 170, 170, 170, 170, 170, 170, 170,
- 170, 170, 170, 170, 170, 170, 170, 170,
- 170, 170, 170, 170, 170, 170, 170, 170,
- 170, 170, 170, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 162, 162, 162, 162, 162, 162,
+ 192, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 64, 200, 200, 200, 200, 128,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 208, 200, 200, 200, 200, 208,
+ 200, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 232, 200, 200, 200, 200, 232,
+ 200, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 232, 232, 232, 232, 232, 232,
+ 232, 232, 232, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
+ 200, 200, 200, 200, 200, 200, 200, 200,
};
#line 89 "ext/pdo/pdo_sql_parser.c"
-{
- YYCTYPE yych;
- unsigned int yyaccept = 0;
- goto yy0;
- ++YYCURSOR;
-yy0:
- if((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
- yych = *YYCURSOR;
- if(yybm[0+yych] & 2) {
- goto yy8;
- }
- if(yych <= 0x00) goto yy11;
- if(yych <= '&') goto yy2;
- if(yych <= '\'') goto yy4;
- if(yych <= '>') goto yy5;
- goto yy6;
-yy2: yyaccept = 0;
- yych = *(YYMARKER = ++YYCURSOR);
- if(yybm[0+yych] & 64) {
- goto yy30;
- }
- if(yych <= 0x00) goto yy3;
- if(yych == '"') goto yy28;
- goto yy33;
+ {
+ YYCTYPE yych;
+
+ if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if(yybm[0+yych] & 8) {
+ goto yy8;
+ }
+ if(yych <= 0x00) goto yy11;
+ if(yych <= '&') goto yy2;
+ if(yych <= '\'') goto yy4;
+ if(yych <= '>') goto yy5;
+ goto yy6;
+yy2:
+ yych = *++YYCURSOR;
+ goto yy24;
yy3:
-#line 63 "ext/pdo/pdo_sql_parser.re"
-{ RET(PDO_PARSER_TEXT); }
-#line 117 "ext/pdo/pdo_sql_parser.c"
-yy4: yyaccept = 0;
- yych = *(YYMARKER = ++YYCURSOR);
- if(yybm[0+yych] & 16) {
- goto yy19;
- }
- if(yych <= 0x00) goto yy3;
- if(yych == '\'') goto yy21;
- goto yy24;
-yy5: yych = *++YYCURSOR;
- if(yybm[0+yych] & 4) {
- goto yy13;
- }
- if(yych <= 'Z'){
- if(yych <= '/') goto yy3;
- if(yych <= ':') goto yy16;
- if(yych <= '@') goto yy3;
- goto yy16;
- } else {
- if(yych <= '_'){
- if(yych <= '^') goto yy3;
+#line 62 "ext/pdo/pdo_sql_parser.re"
+ { RET(PDO_PARSER_TEXT); }
+#line 109 "ext/pdo/pdo_sql_parser.c"
+yy4:
+ yych = *++YYCURSOR;
+ goto yy20;
+yy5:
+ yych = *++YYCURSOR;
+ if(yybm[0+yych] & 32) {
goto yy16;
- } else {
- if(yych <= '`') goto yy3;
- if(yych <= 'z') goto yy16;
- goto yy3;
}
- }
-yy6: ++YYCURSOR;
- if(yybm[0+(yych = *YYCURSOR)] & 4) {
+ if(yych == ':') goto yy13;
+ if(yych == '?') goto yy13;
+ goto yy3;
+yy6:
+ ++YYCURSOR;
+ if(yybm[0+(yych = *YYCURSOR)] & 16) {
+ goto yy13;
+ }
+#line 61 "ext/pdo/pdo_sql_parser.re"
+ { RET(PDO_PARSER_BIND_POS); }
+#line 128 "ext/pdo/pdo_sql_parser.c"
+yy8:
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- goto yy13;
- }
- goto yy7;
-yy7:
-#line 62 "ext/pdo/pdo_sql_parser.re"
-{ RET(PDO_PARSER_BIND_POS); }
-#line 154 "ext/pdo/pdo_sql_parser.c"
-yy8: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- goto yy9;
-yy9: if(yybm[0+yych] & 2) {
- goto yy8;
- }
- goto yy10;
-yy10:
+ if(yybm[0+yych] & 8) {
+ goto yy8;
+ }
+#line 63 "ext/pdo/pdo_sql_parser.re"
+ { RET(PDO_PARSER_TEXT); }
+#line 138 "ext/pdo/pdo_sql_parser.c"
+yy11:
+ ++YYCURSOR;
#line 64 "ext/pdo/pdo_sql_parser.re"
-{ RET(PDO_PARSER_TEXT); }
-#line 166 "ext/pdo/pdo_sql_parser.c"
-yy11: ++YYCURSOR;
- goto yy12;
-yy12:
-#line 65 "ext/pdo/pdo_sql_parser.re"
-{ RET(PDO_PARSER_EOI); }
-#line 172 "ext/pdo/pdo_sql_parser.c"
-yy13: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- goto yy14;
-yy14: if(yybm[0+yych] & 4) {
- goto yy13;
- }
- goto yy15;
-yy15:
-#line 60 "ext/pdo/pdo_sql_parser.re"
-{ RET(PDO_PARSER_TEXT); }
-#line 184 "ext/pdo/pdo_sql_parser.c"
-yy16: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- goto yy17;
-yy17: if(yybm[0+yych] & 8) {
- goto yy16;
- }
- goto yy18;
-yy18:
-#line 61 "ext/pdo/pdo_sql_parser.re"
-{ RET(PDO_PARSER_BIND); }
-#line 196 "ext/pdo/pdo_sql_parser.c"
-yy19: yyaccept = 1;
- YYMARKER = ++YYCURSOR;
- if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
- yych = *YYCURSOR;
- goto yy20;
-yy20: if(yybm[0+yych] & 16) {
- goto yy19;
- }
- if(yych <= '\''){
- if(yych <= 0x00) goto yy15;
- if(yych <= '&') goto yy23;
- goto yy21;
- } else {
- if(yych == '\\') goto yy26;
- goto yy23;
- }
-yy21: ++YYCURSOR;
- if(yybm[0+(yych = *YYCURSOR)] & 4) {
+ { RET(PDO_PARSER_EOI); }
+#line 143 "ext/pdo/pdo_sql_parser.c"
+yy13:
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- goto yy13;
- }
- goto yy22;
-yy22:
+ if(yybm[0+yych] & 16) {
+ goto yy13;
+ }
#line 59 "ext/pdo/pdo_sql_parser.re"
-{ RET(PDO_PARSER_TEXT); }
-#line 222 "ext/pdo/pdo_sql_parser.c"
-yy23: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- goto yy24;
-yy24: if(yybm[0+yych] & 32) {
- goto yy23;
- }
- if(yych <= 0x00) goto yy25;
- if(yych <= '[') goto yy27;
- goto yy26;
-yy25: YYCURSOR = YYMARKER;
- switch(yyaccept){
- case 1: goto yy15;
- case 0: goto yy3;
- }
-yy26: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- if(yych == '\'') goto yy23;
- goto yy25;
-yy27: yych = *++YYCURSOR;
- goto yy22;
-yy28: ++YYCURSOR;
- if(yybm[0+(yych = *YYCURSOR)] & 4) {
+ { RET(PDO_PARSER_TEXT); }
+#line 153 "ext/pdo/pdo_sql_parser.c"
+yy16:
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- goto yy13;
- }
- goto yy29;
-yy29:
+ if(yybm[0+yych] & 32) {
+ goto yy16;
+ }
+#line 60 "ext/pdo/pdo_sql_parser.re"
+ { RET(PDO_PARSER_BIND); }
+#line 163 "ext/pdo/pdo_sql_parser.c"
+yy19:
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy20:
+ if(yybm[0+yych] & 64) {
+ goto yy19;
+ }
+ ++YYCURSOR;
#line 58 "ext/pdo/pdo_sql_parser.re"
-{ RET(PDO_PARSER_TEXT); }
-#line 254 "ext/pdo/pdo_sql_parser.c"
-yy30: yyaccept = 1;
- YYMARKER = ++YYCURSOR;
- if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
- yych = *YYCURSOR;
- goto yy31;
-yy31: if(yybm[0+yych] & 64) {
- goto yy30;
- }
- if(yych <= '"'){
- if(yych <= 0x00) goto yy15;
- if(yych >= '"') goto yy28;
- goto yy32;
- } else {
- if(yych == '\\') goto yy34;
- goto yy32;
- }
-yy32: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- goto yy33;
-yy33: if(yybm[0+yych] & 128) {
- goto yy32;
+ { RET(PDO_PARSER_TEXT); }
+#line 175 "ext/pdo/pdo_sql_parser.c"
+yy23:
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+yy24:
+ if(yybm[0+yych] & 128) {
+ goto yy23;
+ }
+ ++YYCURSOR;
+#line 57 "ext/pdo/pdo_sql_parser.re"
+ { RET(PDO_PARSER_TEXT); }
+#line 187 "ext/pdo/pdo_sql_parser.c"
}
- if(yych <= 0x00) goto yy25;
- if(yych <= '[') goto yy35;
- goto yy34;
-yy34: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- if(yych == '"') goto yy32;
- goto yy25;
-yy35: ++YYCURSOR;
- yych = *YYCURSOR;
- goto yy29;
-}
}
-#line 66 "ext/pdo/pdo_sql_parser.re"
+#line 65 "ext/pdo/pdo_sql_parser.re"
}
@@ -317,7 +216,6 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
ptr = *outquery;
s.cur = inquery;
- s.lim = inquery + inquery_len;
/* phase 1: look for args */
while((t = scan(&s)) != PDO_PARSER_EOI) {
@@ -353,10 +251,10 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
if (query_type == (PDO_PLACEHOLDER_NAMED|PDO_PLACEHOLDER_POSITIONAL)) {
/* they mixed both types; punt */
pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "mixed named and positional parameters" TSRMLS_CC);
- return -1;
+ ret = -1;
+ goto clean_up;
}
-
if (stmt->supports_placeholders == query_type && !stmt->named_rewrite_template) {
/* query matches native syntax */
ret = 0;
@@ -380,9 +278,27 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
ret = -1;
goto clean_up;
}
-
+
+ if (params && bindno != zend_hash_num_elements(params) && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
+ /* extra bit of validation for instances when same params are bound more then once */
+ if (query_type != PDO_PLACEHOLDER_POSITIONAL && bindno > zend_hash_num_elements(params)) {
+ int ok = 1;
+ for (plc = placeholders; plc; plc = plc->next) {
+ if (zend_hash_find(params, plc->pos, plc->len, (void**) &param) == FAILURE) {
+ ok = 0;
+ break;
+ }
+ }
+ if (ok) {
+ goto safe;
+ }
+ }
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "number of bound variables does not match number of tokens" TSRMLS_CC);
+ ret = -1;
+ goto clean_up;
+ }
+safe:
/* what are we going to do ? */
-
if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
/* query generation */
@@ -416,11 +332,14 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
/* bork */
ret = -1;
strcpy(stmt->error_code, stmt->dbh->error_code);
- efree(buf);
+ if (buf) {
+ efree(buf);
+ }
goto clean_up;
}
- efree(buf);
-
+ if (buf) {
+ efree(buf);
+ }
} else {
pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource" TSRMLS_CC);
ret = -1;
@@ -623,7 +542,6 @@ int old_pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char
ptr = *outquery;
s.cur = inquery;
- s.lim = inquery + inquery_len;
while((t = scan(&s)) != PDO_PARSER_EOI) {
if(t == PDO_PARSER_TEXT) {
memcpy(ptr, s.tok, s.cur - s.tok);
diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re
index beff5e874..6775ae51b 100644
--- a/ext/pdo/pdo_sql_parser.re
+++ b/ext/pdo/pdo_sql_parser.re
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pdo_sql_parser.re,v 1.28.2.4 2006/01/25 16:35:23 iliaa Exp $ */
+/* $Id: pdo_sql_parser.re,v 1.28.2.4.2.8 2007/03/06 00:52:55 iliaa Exp $ */
#include "php.h"
#include "php_pdo_driver.h"
@@ -29,14 +29,14 @@
#define RET(i) {s->cur = cursor; return i; }
-#define YYCTYPE char
+#define YYCTYPE unsigned char
#define YYCURSOR cursor
-#define YYLIMIT s->lim
+#define YYLIMIT cursor
#define YYMARKER s->ptr
#define YYFILL(n)
typedef struct Scanner {
- char *lim, *ptr, *cur, *tok;
+ char *ptr, *cur, *tok;
} Scanner;
static int scan(Scanner *s)
@@ -48,16 +48,15 @@ static int scan(Scanner *s)
BINDCHR = [:][a-zA-Z0-9_]+;
QUESTION = [?];
SPECIALS = [:?"'];
- ESCQQ = [\\]["];
- ESCQ = [\\]['];
- EOF = [\000];
+ MULTICHAR = [:?];
+ EOF = [\000];
ANYNOEOF = [\001-\377];
*/
/*!re2c
- (["] (ESCQQ|ANYNOEOF\[\\"])* ["]) { RET(PDO_PARSER_TEXT); }
- (['] (ESCQ|ANYNOEOF\[\\'])* [']) { RET(PDO_PARSER_TEXT); }
- SPECIALS{2,} { RET(PDO_PARSER_TEXT); }
+ (["] ([^"])* ["]) { RET(PDO_PARSER_TEXT); }
+ (['] ([^'])* [']) { RET(PDO_PARSER_TEXT); }
+ MULTICHAR{2,} { RET(PDO_PARSER_TEXT); }
BINDCHR { RET(PDO_PARSER_BIND); }
QUESTION { RET(PDO_PARSER_BIND_POS); }
SPECIALS { RET(PDO_PARSER_TEXT); }
@@ -92,7 +91,6 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
ptr = *outquery;
s.cur = inquery;
- s.lim = inquery + inquery_len;
/* phase 1: look for args */
while((t = scan(&s)) != PDO_PARSER_EOI) {
@@ -128,10 +126,10 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
if (query_type == (PDO_PLACEHOLDER_NAMED|PDO_PLACEHOLDER_POSITIONAL)) {
/* they mixed both types; punt */
pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "mixed named and positional parameters" TSRMLS_CC);
- return -1;
+ ret = -1;
+ goto clean_up;
}
-
if (stmt->supports_placeholders == query_type && !stmt->named_rewrite_template) {
/* query matches native syntax */
ret = 0;
@@ -155,9 +153,27 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
ret = -1;
goto clean_up;
}
-
+
+ if (params && bindno != zend_hash_num_elements(params) && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
+ /* extra bit of validation for instances when same params are bound more then once */
+ if (query_type != PDO_PLACEHOLDER_POSITIONAL && bindno > zend_hash_num_elements(params)) {
+ int ok = 1;
+ for (plc = placeholders; plc; plc = plc->next) {
+ if (zend_hash_find(params, plc->pos, plc->len, (void**) &param) == FAILURE) {
+ ok = 0;
+ break;
+ }
+ }
+ if (ok) {
+ goto safe;
+ }
+ }
+ pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "number of bound variables does not match number of tokens" TSRMLS_CC);
+ ret = -1;
+ goto clean_up;
+ }
+safe:
/* what are we going to do ? */
-
if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
/* query generation */
@@ -191,11 +207,14 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
/* bork */
ret = -1;
strcpy(stmt->error_code, stmt->dbh->error_code);
- efree(buf);
+ if (buf) {
+ efree(buf);
+ }
goto clean_up;
}
- efree(buf);
-
+ if (buf) {
+ efree(buf);
+ }
} else {
pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource" TSRMLS_CC);
ret = -1;
@@ -398,7 +417,6 @@ int old_pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char
ptr = *outquery;
s.cur = inquery;
- s.lim = inquery + inquery_len;
while((t = scan(&s)) != PDO_PARSER_EOI) {
if(t == PDO_PARSER_TEXT) {
memcpy(ptr, s.tok, s.cur - s.tok);
diff --git a/ext/pdo/pdo_sqlstate.c b/ext/pdo/pdo_sqlstate.c
index 338309f4c..c92ea4b4e 100644
--- a/ext/pdo/pdo_sqlstate.c
+++ b/ext/pdo/pdo_sqlstate.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pdo_sqlstate.c,v 1.7.2.1 2006/01/01 12:50:11 sniper Exp $ */
+/* $Id: pdo_sqlstate.c,v 1.7.2.1.2.1 2007/01/01 09:36:04 sebastian Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index a837a14f0..cff987497 100755
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pdo_stmt.c,v 1.118.2.38.2.8 2006/08/23 19:15:57 tony2001 Exp $ */
+/* $Id: pdo_stmt.c,v 1.118.2.38.2.16 2007/04/17 17:00:16 tony2001 Exp $ */
/* The PDO Statement Handle Class */
@@ -251,7 +251,10 @@ static void param_dtor(void *data) /* {{{ */
efree(param->name);
}
- zval_ptr_dtor(&(param->parameter));
+ if (param->parameter) {
+ zval_ptr_dtor(&(param->parameter));
+ param->parameter = NULL;
+ }
if (param->driver_params) {
zval_ptr_dtor(&(param->driver_params));
}
@@ -278,6 +281,10 @@ static int really_register_bound_param(struct pdo_bound_param_data *param, pdo_s
if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && ! ZVAL_IS_NULL(param->parameter)) {
convert_to_string(param->parameter);
+ } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) {
+ convert_to_long(param->parameter);
+ } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && Z_TYPE_P(param->parameter) == IS_LONG) {
+ convert_to_boolean(param->parameter);
}
param->stmt = stmt;
@@ -366,6 +373,8 @@ static int really_register_bound_param(struct pdo_bound_param_data *param, pdo_s
} else {
zend_hash_index_del(hash, pparam->paramno);
}
+ /* param->parameter is freed by hash dtor */
+ param->parameter = NULL;
return 0;
}
}
@@ -424,7 +433,9 @@ static PHP_METHOD(PDOStatement, execute)
INIT_PZVAL(param.parameter);
if (!really_register_bound_param(&param, stmt, 1 TSRMLS_CC)) {
- zval_ptr_dtor(&param.parameter);
+ if (param.parameter) {
+ zval_ptr_dtor(&param.parameter);
+ }
RETURN_FALSE;
}
@@ -462,7 +473,7 @@ static PHP_METHOD(PDOStatement, execute)
if (!stmt->executed) {
/* this is the first execute */
- if (stmt->dbh->alloc_own_columns) {
+ if (stmt->dbh->alloc_own_columns && !stmt->columns) {
/* for "big boy" drivers, we need to allocate memory to fetch
* the results into, so lets do that now */
ret = pdo_stmt_describe_columns(stmt TSRMLS_CC);
@@ -613,6 +624,10 @@ static inline void fetch_value(pdo_stmt_t *stmt, zval *dest, int colno, int *typ
static int do_fetch_common(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori,
long offset, int do_bind TSRMLS_DC) /* {{{ */
{
+ if (!stmt->executed) {
+ return 0;
+ }
+
if (!dispatch_param_event(stmt, PDO_PARAM_EVT_FETCH_PRE TSRMLS_CC)) {
return 0;
}
@@ -1545,7 +1560,10 @@ static int register_bound_param(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt,
ZVAL_ADDREF(param.parameter);
if (!really_register_bound_param(&param, stmt, is_param TSRMLS_CC)) {
- zval_ptr_dtor(&(param.parameter));
+ if (param.parameter) {
+ zval_ptr_dtor(&(param.parameter));
+ param.parameter = NULL;
+ }
return 0;
}
return 1;
@@ -1578,7 +1596,10 @@ static PHP_METHOD(PDOStatement, bindValue)
ZVAL_ADDREF(param.parameter);
if (!really_register_bound_param(&param, stmt, TRUE TSRMLS_CC)) {
- zval_ptr_dtor(&(param.parameter));
+ if (param.parameter) {
+ zval_ptr_dtor(&(param.parameter));
+ param.parameter = NULL;
+ }
RETURN_FALSE;
}
RETURN_TRUE;
@@ -1859,12 +1880,11 @@ fail_out:
stmt->fetch.cls.ce = *cep;
stmt->fetch.cls.ctor_args = NULL;
-
+#ifdef ilia_0 /* we'll only need this when we have persistent statements, if ever */
if (stmt->dbh->is_persistent) {
- /* TODO: CRITICAL for final release */
php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP might crash if you don't call $stmt->setFetchMode() to reset to defaults on this persistent statement. This will be fixed in a later release");
}
-
+#endif
if (argc == 3) {
if (Z_TYPE_PP(args[skip+2]) != IS_NULL && Z_TYPE_PP(args[skip+2]) != IS_ARRAY) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "ctor_args must be either NULL or an array" TSRMLS_CC);
@@ -1885,11 +1905,11 @@ fail_out:
if (Z_TYPE_PP(args[skip+1]) != IS_OBJECT) {
goto fail_out;
}
-
+#ifdef ilia_0 /* we'll only need this when we have persistent statements, if ever */
if (stmt->dbh->is_persistent) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP might crash if you don't call $stmt->setFetchMode() to reset to defaults on this persistent statement. This will be fixed in a later release");
}
-
+#endif
MAKE_STD_ZVAL(stmt->fetch.into);
Z_TYPE_P(stmt->fetch.into) = IS_OBJECT;
@@ -1925,10 +1945,6 @@ static PHP_METHOD(PDOStatement, setFetchMode)
static int pdo_stmt_do_next_rowset(pdo_stmt_t *stmt TSRMLS_DC)
{
- if (!stmt->methods->next_rowset(stmt TSRMLS_CC)) {
- return 0;
- }
-
/* un-describe */
if (stmt->columns) {
int i;
@@ -1942,6 +1958,10 @@ static int pdo_stmt_do_next_rowset(pdo_stmt_t *stmt TSRMLS_DC)
stmt->column_count = 0;
}
+ if (!stmt->methods->next_rowset(stmt TSRMLS_CC)) {
+ return 0;
+ }
+
pdo_stmt_describe_columns(stmt TSRMLS_CC);
return 1;
@@ -1962,8 +1982,6 @@ static PHP_METHOD(PDOStatement, nextRowset)
PDO_HANDLE_STMT_ERR();
RETURN_FALSE;
}
-
- pdo_stmt_describe_columns(stmt TSRMLS_CC);
RETURN_TRUE;
}
@@ -1989,6 +2007,7 @@ static PHP_METHOD(PDOStatement, closeCursor)
}
} while (1);
+ stmt->executed = 0;
RETURN_TRUE;
}
@@ -1998,7 +2017,7 @@ static PHP_METHOD(PDOStatement, closeCursor)
PDO_HANDLE_STMT_ERR();
RETURN_FALSE;
}
-
+ stmt->executed = 0;
RETURN_TRUE;
}
/* }}} */
@@ -2506,28 +2525,18 @@ static void row_prop_or_dim_delete(zval *object, zval *offset TSRMLS_DC)
static HashTable *row_get_properties(zval *object TSRMLS_DC)
{
- zval *tmp;
pdo_stmt_t * stmt = (pdo_stmt_t *) zend_object_store_get_object(object TSRMLS_CC);
int i;
- HashTable *ht;
-
- MAKE_STD_ZVAL(tmp);
- array_init(tmp);
for (i = 0; i < stmt->column_count; i++) {
zval *val;
MAKE_STD_ZVAL(val);
fetch_value(stmt, val, i, NULL TSRMLS_CC);
- add_assoc_zval(tmp, stmt->columns[i].name, val);
+ zend_hash_update(stmt->properties, stmt->columns[i].name, stmt->columns[i].namelen + 1, (void *)&val, sizeof(zval *), NULL);
}
- ht = Z_ARRVAL_P(tmp);
-
- ZVAL_NULL(tmp);
- FREE_ZVAL(tmp);
-
- return ht;
+ return stmt->properties;
}
static union _zend_function *row_method_get(
diff --git a/ext/pdo/php_pdo.h b/ext/pdo/php_pdo.h
index 31c610c54..52ecbd3d0 100755
--- a/ext/pdo/php_pdo.h
+++ b/ext/pdo/php_pdo.h
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_pdo.h,v 1.7.2.5.2.2 2006/06/07 21:09:52 rasmus Exp $ */
+/* $Id: php_pdo.h,v 1.7.2.5.2.3 2007/01/01 09:36:04 sebastian Exp $ */
#ifndef PHP_PDO_H
#define PHP_PDO_H
diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h
index e87650b1b..bf3f4adf8 100755
--- a/ext/pdo/php_pdo_driver.h
+++ b/ext/pdo/php_pdo_driver.h
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_pdo_driver.h,v 1.66.2.11.2.3 2006/09/28 23:27:59 tony2001 Exp $ */
+/* $Id: php_pdo_driver.h,v 1.66.2.11.2.4 2007/01/01 09:36:04 sebastian Exp $ */
#ifndef PHP_PDO_DRIVER_H
#define PHP_PDO_DRIVER_H
diff --git a/ext/pdo/php_pdo_int.h b/ext/pdo/php_pdo_int.h
index c489903dd..3f8f76888 100755
--- a/ext/pdo/php_pdo_int.h
+++ b/ext/pdo/php_pdo_int.h
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_pdo_int.h,v 1.17.2.6.2.1 2006/05/11 22:43:44 helly Exp $ */
+/* $Id: php_pdo_int.h,v 1.17.2.6.2.2 2007/01/01 09:36:04 sebastian Exp $ */
/* Stuff private to the PDO extension and not for consumption by PDO drivers
* */
diff --git a/ext/pdo/tests/bug_36798.phpt b/ext/pdo/tests/bug_36798.phpt
new file mode 100644
index 000000000..4e301eb0e
--- /dev/null
+++ b/ext/pdo/tests/bug_36798.phpt
@@ -0,0 +1,32 @@
+--TEST--
+PDO Common: Bug #36798 (Error parsing named parameters with queries containing high-ascii chars)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec("CREATE TABLE test (id INTEGER)");
+$db->exec("INSERT INTO test (id) VALUES (1)");
+
+$stmt = $db->prepare("SELECT 'Ã' as test FROM test WHERE id = :id");
+$stmt->execute(array(":id" => 1));
+
+$row = $stmt->fetch(PDO::FETCH_NUM);
+var_dump( $row );
+
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ string(1) "Ã"
+}
diff --git a/ext/pdo/tests/bug_39398.phpt b/ext/pdo/tests/bug_39398.phpt
new file mode 100644
index 000000000..7b81747cf
--- /dev/null
+++ b/ext/pdo/tests/bug_39398.phpt
@@ -0,0 +1,35 @@
+--TEST--
+PDO Common: PHP Bug #39398: Booleans are not automatically translated to integers
+--SKIPIF--
+<?php # vim:ft=php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+$db = PDOTest::factory();
+$db->exec("CREATE TABLE test (test INT)");
+
+$boolean = 1;
+$stmt = $db->prepare('INSERT INTO test VALUES (:boolean)');
+$stmt->bindValue(':boolean', isset($boolean), PDO::PARAM_INT);
+$stmt->execute();
+
+var_dump($db->query("SELECT * FROM test")->fetchAll(PDO::FETCH_ASSOC));
+?>
+===DONE===
+--EXPECT--
+array(1) {
+ [0]=>
+ array(1) {
+ ["test"]=>
+ string(1) "1"
+ }
+}
+===DONE===
diff --git a/ext/pdo/tests/bug_39656.phpt b/ext/pdo/tests/bug_39656.phpt
new file mode 100644
index 000000000..e1a283ce0
--- /dev/null
+++ b/ext/pdo/tests/bug_39656.phpt
@@ -0,0 +1,50 @@
+--TEST--
+PDO Common: Bug #39656 (Crash when calling fetch() on a PDO statment object after closeCursor())
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+@$db->exec("DROP TABLE testtable");
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+$db->exec("CREATE TABLE testtable (id INTEGER NOT NULL PRIMARY KEY, usr VARCHAR( 256 ) NOT NULL)");
+$db->exec("INSERT INTO testtable (id, usr) VALUES (1, 'user')");
+
+$stmt = $db->prepare("SELECT * FROM testtable WHERE id = ?");
+$stmt->bindValue(1, 1, PDO::PARAM_INT );
+$stmt->execute();
+$row = $stmt->fetch();
+var_dump( $row );
+
+$stmt->execute();
+$stmt->closeCursor();
+$row = $stmt->fetch(); // this line will crash CLI
+var_dump( $row );
+
+echo "Done\n";
+?>
+--EXPECT--
+array(4) {
+ ["id"]=>
+ string(1) "1"
+ [0]=>
+ string(1) "1"
+ ["usr"]=>
+ string(4) "user"
+ [1]=>
+ string(4) "user"
+}
+bool(false)
+Done
+
diff --git a/ext/pdo/tests/bug_40285.phpt b/ext/pdo/tests/bug_40285.phpt
new file mode 100644
index 000000000..c0a567438
--- /dev/null
+++ b/ext/pdo/tests/bug_40285.phpt
@@ -0,0 +1,27 @@
+--TEST--
+PDO Common: Bug #40285 (The prepare parser goes into an infinite loop on ': or ":)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+
+$db->exec('CREATE TABLE test (field1 VARCHAR(32), field2 VARCHAR(32), field3 VARCHAR(32), field4 INT)');
+
+$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
+$s = $db->prepare("INSERT INTO test VALUES( ':id', 'name', 'section', 22)" );
+$s->execute();
+
+echo "Done\n";
+?>
+--EXPECT--
+Done
diff --git a/ext/pdo/tests/pdo_016.phpt b/ext/pdo/tests/pdo_016.phpt
index 8d193d37e..f3aba13e0 100644
--- a/ext/pdo/tests/pdo_016.phpt
+++ b/ext/pdo/tests/pdo_016.phpt
@@ -14,6 +14,10 @@ if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE_
require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
$db = PDOTest::factory();
+if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
+ $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
+}
+
$db->exec('CREATE TABLE test(idx int NOT NULL PRIMARY KEY, txt VARCHAR(20))');
$db->exec('INSERT INTO test VALUES(0, \'String0\')');
$db->exec('INSERT INTO test VALUES(1, \'String1\')');
diff --git a/ext/pdo/tests/pdo_016a.phpt b/ext/pdo/tests/pdo_016a.phpt
index cdb9dd7a8..00b75aeca 100755
--- a/ext/pdo/tests/pdo_016a.phpt
+++ b/ext/pdo/tests/pdo_016a.phpt
@@ -14,6 +14,10 @@ if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE_
require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
$db = PDOTest::factory();
+if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
+ $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
+}
+
$db->exec('CREATE TABLE test(idx int NOT NULL PRIMARY KEY, txt VARCHAR(20))');
$db->exec('INSERT INTO test VALUES(0, \'String0\')');
$db->exec('INSERT INTO test VALUES(1, \'String1\')');
diff --git a/ext/pdo/tests/pdo_021.phpt b/ext/pdo/tests/pdo_021.phpt
index 104c3394d..688bd4a61 100644
--- a/ext/pdo/tests/pdo_021.phpt
+++ b/ext/pdo/tests/pdo_021.phpt
@@ -14,6 +14,10 @@ if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE_
require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
$db = PDOTest::factory();
+if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
+ $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
+}
+
$db->exec('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))');
$select = $db->prepare('SELECT COUNT(id) FROM test');