diff options
author | Xinchen Hui <laruence@php.net> | 2014-06-19 22:28:43 +0800 |
---|---|---|
committer | Xinchen Hui <laruence@php.net> | 2014-06-19 22:28:43 +0800 |
commit | d8a4b1affb00298036cbadbaadc2067330488b41 (patch) | |
tree | 9134584289ab7c410d6a97ac608e2073cd870e14 /ext/mysqlnd/mysqlnd_ps_codec.c | |
parent | 4cc3c7387b4cfa7231e276ce5fc375b781c6b35b (diff) | |
download | php-git-d8a4b1affb00298036cbadbaadc2067330488b41.tar.gz |
Fixed paramters binding
Diffstat (limited to 'ext/mysqlnd/mysqlnd_ps_codec.c')
-rw-r--r-- | ext/mysqlnd/mysqlnd_ps_codec.c | 56 |
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) { |