summaryrefslogtreecommitdiff
path: root/ext/mysqlnd/mysqlnd_ps_codec.c
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2014-06-19 22:28:43 +0800
committerXinchen Hui <laruence@php.net>2014-06-19 22:28:43 +0800
commitd8a4b1affb00298036cbadbaadc2067330488b41 (patch)
tree9134584289ab7c410d6a97ac608e2073cd870e14 /ext/mysqlnd/mysqlnd_ps_codec.c
parent4cc3c7387b4cfa7231e276ce5fc375b781c6b35b (diff)
downloadphp-git-d8a4b1affb00298036cbadbaadc2067330488b41.tar.gz
Fixed paramters binding
Diffstat (limited to 'ext/mysqlnd/mysqlnd_ps_codec.c')
-rw-r--r--ext/mysqlnd/mysqlnd_ps_codec.c56
1 files changed, 33 insertions, 23 deletions
diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c
index 234cec4fb7..5d860f254d 100644
--- a/ext/mysqlnd/mysqlnd_ps_codec.c
+++ b/ext/mysqlnd/mysqlnd_ps_codec.c
@@ -505,7 +505,6 @@ mysqlnd_stmt_copy_it(zval ** copies, zval * original, unsigned int param_count,
*copies = mnd_ecalloc(param_count, sizeof(zval));
}
if (*copies) {
- ZVAL_DEREF(original);
ZVAL_COPY(&(*copies)[current], original);
//????Z_SET_REFCOUNT_P((*copies)[current], 1);
//zval_copy_ctor((*copies)[current]);
@@ -567,11 +566,13 @@ mysqlnd_stmt_execute_prepare_param_types(MYSQLND_STMT_DATA * stmt, zval ** copie
DBG_ENTER("mysqlnd_stmt_execute_prepare_param_types");
for (i = 0; i < stmt->param_count; i++) {
short current_type = stmt->param_bind[i].type;
+ zval *parameter = &stmt->param_bind[i].zv;
- if (Z_TYPE(stmt->param_bind[i].zv) != IS_NULL && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) {
+ ZVAL_DEREF(parameter);
+ if (!Z_ISNULL_P(parameter) && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) {
/* always copy the var, because we do many conversions */
- if (Z_TYPE(stmt->param_bind[i].zv) != IS_LONG &&
- PASS != mysqlnd_stmt_copy_it(copies_param, &stmt->param_bind[i].zv, stmt->param_count, i TSRMLS_CC))
+ if (Z_TYPE_P(parameter) != IS_LONG &&
+ PASS != mysqlnd_stmt_copy_it(copies_param, parameter, stmt->param_count, i TSRMLS_CC))
{
SET_OOM_ERROR(*stmt->error_info);
goto end;
@@ -580,15 +581,14 @@ mysqlnd_stmt_execute_prepare_param_types(MYSQLND_STMT_DATA * stmt, zval ** copie
if it doesn't fit in a long send it as a string.
Check bug #52891 : Wrong data inserted with mysqli/mysqlnd when using bind_param, value > LONG_MAX
*/
- if (Z_TYPE(stmt->param_bind[i].zv) != IS_LONG) {
- zval *tmp_data = (*copies_param && !Z_ISUNDEF((*copies_param)[i]))? &(*copies_param)[i]: &stmt->param_bind[i].zv;
+ if (Z_TYPE_P(parameter) != IS_LONG) {
+ zval *tmp_data = (*copies_param && !Z_ISUNDEF((*copies_param)[i]))? &(*copies_param)[i]: parameter;
/*
Because converting to double and back to long can lead
to losing precision we need second variable. Conversion to double is to see if
value is too big for a long. As said, precision could be lost.
*/
zval tmp_data_copy;
- ZVAL_DEREF(tmp_data);
ZVAL_COPY(&tmp_data_copy, tmp_data);
convert_to_double_ex(&tmp_data_copy);
@@ -622,19 +622,21 @@ mysqlnd_stmt_execute_store_types(MYSQLND_STMT_DATA * stmt, zval * copies, zend_u
unsigned int i;
for (i = 0; i < stmt->param_count; i++) {
short current_type = stmt->param_bind[i].type;
+ zval *parameter = &stmt->param_bind[i].zv;
/* our types are not unsigned */
#if SIZEOF_LONG==8
if (current_type == MYSQL_TYPE_LONG) {
current_type = MYSQL_TYPE_LONGLONG;
}
#endif
- if (!Z_ISNULL(stmt->param_bind[i].zv) && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) {
+ ZVAL_DEREF(parameter);
+ if (!Z_ISNULL_P(parameter) && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) {
/*
if it doesn't fit in a long send it as a string.
Check bug #52891 : Wrong data inserted with mysqli/mysqlnd when using bind_param, value > LONG_MAX
*/
- if (Z_TYPE(stmt->param_bind[i].zv) != IS_LONG) {
- const zval *tmp_data = (copies && !Z_ISUNDEF(copies[i]))? &copies[i]: &stmt->param_bind[i].zv;
+ if (Z_TYPE_P(parameter) != IS_LONG) {
+ const zval *tmp_data = (copies && !Z_ISUNDEF(copies[i]))? &copies[i] : parameter;
/*
In case of IS_LONG we do nothing, it is ok, in case of string, we just need to set current_type.
The actual transformation has been performed several dozens line above.
@@ -666,21 +668,26 @@ mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval
for (i = 0; i < stmt->param_count; i++) {
unsigned short is_longlong = 0;
unsigned int j;
- zval *the_var = &stmt->param_bind[i].zv;
+ zval *bind_var, *the_var = &stmt->param_bind[i].zv;
- if (!the_var || (stmt->param_bind[i].type != MYSQL_TYPE_LONG_BLOB && Z_TYPE_P(the_var) == IS_NULL)) {
+ bind_var = the_var;
+ ZVAL_DEREF(the_var);
+ if ((stmt->param_bind[i].type != MYSQL_TYPE_LONG_BLOB && Z_TYPE_P(the_var) == IS_NULL)) {
continue;
}
- for (j = i + 1; j < stmt->param_count; j++) {
- if (&stmt->param_bind[j].zv == the_var) {
- /* Double binding of the same zval, make a copy */
- if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) {
- if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i TSRMLS_CC)) {
- SET_OOM_ERROR(*stmt->error_info);
- goto end;
+
+ if (Z_ISREF_P(bind_var)) {
+ for (j = i + 1; j < stmt->param_count; j++) {
+ if (Z_ISREF(stmt->param_bind[j].zv) && Z_REFVAL(stmt->param_bind[j].zv) == the_var) {
+ /* Double binding of the same zval, make a copy */
+ if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) {
+ if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i TSRMLS_CC)) {
+ SET_OOM_ERROR(*stmt->error_info);
+ goto end;
+ }
}
+ break;
}
- break;
}
}
@@ -701,7 +708,7 @@ mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval
/* fall-through */
case MYSQL_TYPE_LONG:
{
- zval *tmp_data = (*copies_param && !Z_ISUNDEF((*copies_param)[i]))? &(*copies_param)[i]: &stmt->param_bind[i].zv;
+ zval *tmp_data = (*copies_param && !Z_ISUNDEF((*copies_param)[i]))? &(*copies_param)[i]: the_var;
if (Z_TYPE_P(tmp_data) == IS_STRING) {
goto use_string;
}
@@ -749,9 +756,12 @@ mysqlnd_stmt_execute_store_param_values(MYSQLND_STMT_DATA * stmt, zval * copies,
{
unsigned int i;
for (i = 0; i < stmt->param_count; i++) {
- zval * data = (copies && !Z_ISUNDEF(copies[i]))? &copies[i]: &stmt->param_bind[i].zv;
+ zval *data, *parameter = &stmt->param_bind[i].zv;
+
+ ZVAL_DEREF(parameter);
+ data = (copies && !Z_ISUNDEF(copies[i]))? &copies[i]: parameter;
/* Handle long data */
- if (!Z_ISUNDEF(stmt->param_bind[i].zv) && Z_TYPE_P(data) == IS_NULL) {
+ if (!Z_ISUNDEF_P(parameter) && Z_TYPE_P(data) == IS_NULL) {
(buf + null_byte_offset)[i/8] |= (zend_uchar) (1 << (i & 7));
} else {
switch (stmt->param_bind[i].type) {