From: Wez Furlong Date: Mon, 27 Mar 2006 20:51:01 +0000 (+0000) Subject: The fix for #35332 caused #35671 (and thus PECL #6504). X-Git-Tag: php-5.1.3RC2~20 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fb7d5bd7804420d86b28c0ae763d161fd3e7b370;p=php The fix for #35332 caused #35671 (and thus PECL #6504). Partially back out that fix and introduce an extra optional step for drivers to canonicalize the "name" that is used for registering parameters. --- diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index c86aa91ac3..9e4cbf757f 100755 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -323,10 +323,14 @@ static int really_register_bound_param(struct pdo_bound_param_data *param, pdo_s } return 0; } - - /* tell the driver we just created a parameter */ + + /* ask the driver to perform any normalization it needs on the + * parameter name. Note that it is illegal for the driver to take + * a reference to param, as it resides in transient storage only + * at this time. */ if (stmt->methods->param_hook) { - if (!stmt->methods->param_hook(stmt, param, PDO_PARAM_EVT_ALLOC TSRMLS_CC)) { + if (!stmt->methods->param_hook(stmt, param, PDO_PARAM_EVT_NORMALIZE + TSRMLS_CC)) { if (param->name) { efree(param->name); param->name = NULL; @@ -335,16 +339,36 @@ static int really_register_bound_param(struct pdo_bound_param_data *param, pdo_s } } + /* delete any other parameter registered with this number. + * If the parameter is named, it will be removed and correctly + * disposed of by the hash_update call that follows */ if (param->paramno >= 0) { zend_hash_index_del(hash, param->paramno); } - + + /* allocate storage for the parameter, keyed by its "canonical" name */ if (param->name) { - zend_hash_update(hash, param->name, param->namelen, param, sizeof(*param), (void**)&pparam); + zend_hash_update(hash, param->name, param->namelen, param, + sizeof(*param), (void**)&pparam); } else { - zend_hash_index_update(hash, param->paramno, param, sizeof(*param), (void**)&pparam); + zend_hash_index_update(hash, param->paramno, param, sizeof(*param), + (void**)&pparam); } + /* tell the driver we just created a parameter */ + if (stmt->methods->param_hook) { + if (!stmt->methods->param_hook(stmt, pparam, PDO_PARAM_EVT_ALLOC + TSRMLS_CC)) { + /* undo storage allocation; the hash will free the parameter + * name if required */ + if (pparam->name) { + zend_hash_del(hash, pparam->name, pparam->namelen); + } else { + zend_hash_index_del(hash, pparam->paramno); + } + return 0; + } + } return 1; } /* }}} */ diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h index 5d0c068591..2b9d947a6a 100755 --- a/ext/pdo/php_pdo_driver.h +++ b/ext/pdo/php_pdo_driver.h @@ -44,7 +44,7 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC); # define FALSE 0 #endif -#define PDO_DRIVER_API 20051128 +#define PDO_DRIVER_API 20060327 enum pdo_param_type { PDO_PARAM_NULL, @@ -338,7 +338,8 @@ enum pdo_param_event { PDO_PARAM_EVT_EXEC_PRE, PDO_PARAM_EVT_EXEC_POST, PDO_PARAM_EVT_FETCH_PRE, - PDO_PARAM_EVT_FETCH_POST + PDO_PARAM_EVT_FETCH_POST, + PDO_PARAM_EVT_NORMALIZE }; typedef int (*pdo_stmt_param_hook_func)(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type TSRMLS_DC); diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index 02418fa140..d83b86ad78 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -221,7 +221,7 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data * } break; - case PDO_PARAM_EVT_ALLOC: + case PDO_PARAM_EVT_NORMALIZE: /* decode name from $1, $2 into 0, 1 etc. */ if (param->name) { if (param->name[0] == '$') { @@ -240,6 +240,10 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data * } break; + case PDO_PARAM_EVT_ALLOC: + /* work is handled by EVT_NORMALIZE */ + return 1; + case PDO_PARAM_EVT_EXEC_PRE: if (!S->param_values) { S->param_values = ecalloc(