From c2d53719c2ad50d354c186c439c2c7e4528e0ccc Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Fri, 25 Nov 2005 00:29:04 +0000 Subject: [PATCH] Fix for #35332. The problem is caused by the user mixing positional and named parameters. PDO was blindly adding the parameters, unaware that the same parameters were already allocated by position. What we do now is register the parameter with the driver before adding it to any hash. This gives the driver an opportunity to normalize the name and parameter number. PDO can then ensure that only one entry is occupied in the hash for a given parameter. --- ext/pdo/pdo_stmt.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index db2b45e769..ec71734748 100755 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -288,7 +288,7 @@ static int really_register_bound_param(struct pdo_bound_param_data *param, pdo_s ZVAL_ADDREF(param->driver_params); } - if (param->name && stmt->columns) { + if (!is_param && param->name && stmt->columns) { /* try to map the name to the column */ int i; @@ -299,13 +299,15 @@ static int really_register_bound_param(struct pdo_bound_param_data *param, pdo_s } } -#if 0 /* if you prepare and then execute passing an array of params keyed by names, * then this will trigger, and we don't want that */ if (param->paramno == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Did not found column name '%s' in the defined columns; it will not be bound", param->name); } -#endif + } + + if (is_param && !rewrite_name_to_position(stmt, param TSRMLS_CC)) { + return 0; } if (param->name) { @@ -317,30 +319,26 @@ static int really_register_bound_param(struct pdo_bound_param_data *param, pdo_s } else { param->name = estrndup(param->name, param->namelen); } - 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); - } - - if (is_param && !rewrite_name_to_position(stmt, pparam TSRMLS_CC)) { - return 0; } /* tell the driver we just created a parameter */ if (stmt->methods->param_hook) { - if (!stmt->methods->param_hook(stmt, pparam, + if (!stmt->methods->param_hook(stmt, param, PDO_PARAM_EVT_ALLOC TSRMLS_CC)) { - /* driver indicates that the parameter doesn't exist. - * remove it from our hash */ - if (pparam->name) { - zend_hash_del(hash, pparam->name, pparam->namelen); - } else { - zend_hash_index_del(hash, pparam->paramno); - } return 0; } } + if (param->paramno >= 0) { + zend_hash_index_del(hash, param->paramno); + } + + if (param->name) { + 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); + } + return 1; } /* }}} */ -- 2.40.0