diff options
Diffstat (limited to 'ext/pdo')
| -rwxr-xr-x | ext/pdo/pdo.c | 4 | ||||
| -rwxr-xr-x | ext/pdo/pdo_dbh.c | 15 | ||||
| -rw-r--r-- | ext/pdo/pdo_sql_parser.c | 366 | ||||
| -rw-r--r-- | ext/pdo/pdo_sql_parser.c.orig | 396 | ||||
| -rw-r--r-- | ext/pdo/pdo_sql_parser.re | 58 | ||||
| -rw-r--r-- | ext/pdo/pdo_sqlstate.c | 4 | ||||
| -rwxr-xr-x | ext/pdo/pdo_stmt.c | 71 | ||||
| -rwxr-xr-x | ext/pdo/php_pdo.h | 4 | ||||
| -rwxr-xr-x | ext/pdo/php_pdo_driver.h | 4 | ||||
| -rwxr-xr-x | ext/pdo/php_pdo_int.h | 4 | ||||
| -rw-r--r-- | ext/pdo/tests/bug_36798.phpt | 32 | ||||
| -rw-r--r-- | ext/pdo/tests/bug_39398.phpt | 35 | ||||
| -rw-r--r-- | ext/pdo/tests/bug_39656.phpt | 50 | ||||
| -rw-r--r-- | ext/pdo/tests/bug_40285.phpt | 27 | ||||
| -rw-r--r-- | ext/pdo/tests/pdo_016.phpt | 4 | ||||
| -rwxr-xr-x | ext/pdo/tests/pdo_016a.phpt | 4 | ||||
| -rw-r--r-- | ext/pdo/tests/pdo_021.phpt | 4 |
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**) ¶m) == 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**) ¶m) == 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**) ¶m) == 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(¶m, stmt, 1 TSRMLS_CC)) { - zval_ptr_dtor(¶m.parameter); + if (param.parameter) { + zval_ptr_dtor(¶m.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(¶m, 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(¶m, 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'); |
