diff options
Diffstat (limited to 'ext/mysqlnd/mysqlnd_ps_codec.c')
-rw-r--r-- | ext/mysqlnd/mysqlnd_ps_codec.c | 213 |
1 files changed, 107 insertions, 106 deletions
diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c index def140ad89..2b3ae62b8f 100644 --- a/ext/mysqlnd/mysqlnd_ps_codec.c +++ b/ext/mysqlnd/mysqlnd_ps_codec.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 2006-2016 The PHP Group | +----------------------------------------------------------------------+ @@ -42,7 +42,7 @@ enum mysqlnd_timestamp_type struct st_mysqlnd_time { unsigned int year, month, day, hour, minute, second; - unsigned long second_part; + zend_ulong second_part; zend_bool neg; enum mysqlnd_timestamp_type time_type; }; @@ -56,7 +56,7 @@ struct st_mysqlnd_perm_bind mysqlnd_ps_fetch_functions[MYSQL_TYPE_LAST + 1]; /* {{{ ps_fetch_from_1_to_8_bytes */ void ps_fetch_from_1_to_8_bytes(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, - zend_uchar ** row, unsigned int byte_count TSRMLS_DC) + zend_uchar ** row, unsigned int byte_count) { char tmp[22]; size_t tmp_len = 0; @@ -77,15 +77,15 @@ ps_fetch_from_1_to_8_bytes(zval * zv, const MYSQLND_FIELD * const field, unsigne case 1:uval = (uint64_t) uint1korr(*row);break; } -#if SIZEOF_LONG==4 +#if SIZEOF_ZEND_LONG==4 if (uval > INT_MAX) { DBG_INF("stringify"); tmp_len = sprintf((char *)&tmp, MYSQLND_LLU_SPEC, uval); - } else + } else #endif /* #if SIZEOF_LONG==4 */ { if (byte_count < 8 || uval <= L64(9223372036854775807)) { - ZVAL_LONG(zv, (long) uval); /* the cast is safe, we are in the range */ + ZVAL_LONG(zv, (zend_long) uval); /* the cast is safe, we are in the range */ } else { DBG_INF("stringify"); tmp_len = sprintf((char *)&tmp, MYSQLND_LLU_SPEC, uval); @@ -106,19 +106,19 @@ ps_fetch_from_1_to_8_bytes(zval * zv, const MYSQLND_FIELD * const field, unsigne case 1:lval = (int64_t) *(int8_t*)*row;break; } -#if SIZEOF_LONG==4 +#if SIZEOF_ZEND_LONG==4 if ((L64(2147483647) < (int64_t) lval) || (L64(-2147483648) > (int64_t) lval)) { DBG_INF("stringify"); tmp_len = sprintf((char *)&tmp, MYSQLND_LL_SPEC, lval); } else #endif /* SIZEOF */ { - ZVAL_LONG(zv, (long) lval); /* the cast is safe, we are in the range */ + ZVAL_LONG(zv, (zend_long) lval); /* the cast is safe, we are in the range */ } } if (tmp_len) { - ZVAL_STRINGL(zv, tmp, tmp_len, 1); + ZVAL_STRINGL(zv, tmp, tmp_len); } (*row)+= byte_count; DBG_VOID_RETURN; @@ -128,7 +128,7 @@ ps_fetch_from_1_to_8_bytes(zval * zv, const MYSQLND_FIELD * const field, unsigne /* {{{ ps_fetch_null */ static void -ps_fetch_null(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) +ps_fetch_null(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { ZVAL_NULL(zv); } @@ -137,43 +137,43 @@ ps_fetch_null(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len /* {{{ ps_fetch_int8 */ static void -ps_fetch_int8(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) +ps_fetch_int8(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { - ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 1 TSRMLS_CC); + ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 1); } /* }}} */ /* {{{ ps_fetch_int16 */ static void -ps_fetch_int16(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) +ps_fetch_int16(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { - ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 2 TSRMLS_CC); + ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 2); } /* }}} */ /* {{{ ps_fetch_int32 */ static void -ps_fetch_int32(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) +ps_fetch_int32(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { - ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 4 TSRMLS_CC); + ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 4); } /* }}} */ /* {{{ ps_fetch_int64 */ static void -ps_fetch_int64(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) +ps_fetch_int64(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { - ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 8 TSRMLS_CC); + ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 8); } /* }}} */ /* {{{ ps_fetch_float */ static void -ps_fetch_float(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) +ps_fetch_float(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { float fval; double dval; @@ -196,7 +196,7 @@ ps_fetch_float(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_l /* {{{ ps_fetch_double */ static void -ps_fetch_double(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) +ps_fetch_double(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { double value; DBG_ENTER("ps_fetch_double"); @@ -211,10 +211,10 @@ ps_fetch_double(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_ /* {{{ ps_fetch_time */ static void -ps_fetch_time(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) +ps_fetch_time(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { struct st_mysqlnd_time t; - unsigned long length; /* First byte encodes the length*/ + zend_ulong length; /* First byte encodes the length*/ char * value; DBG_ENTER("ps_fetch_time"); @@ -224,11 +224,11 @@ ps_fetch_time(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_le t.time_type = MYSQLND_TIMESTAMP_TIME; t.neg = (zend_bool) to[0]; - t.day = (unsigned long) sint4korr(to+1); + t.day = (zend_ulong) sint4korr(to+1); t.hour = (unsigned int) to[5]; t.minute = (unsigned int) to[6]; t.second = (unsigned int) to[7]; - t.second_part = (length > 8) ? (unsigned long) sint4korr(to+8) : 0; + t.second_part = (length > 8) ? (zend_ulong) sint4korr(to+8) : 0; t.year = t.month= 0; if (t.day) { /* Convert days to hours at once */ @@ -245,7 +245,7 @@ ps_fetch_time(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_le length = mnd_sprintf(&value, 0, "%s%02u:%02u:%02u", (t.neg ? "-" : ""), t.hour, t.minute, t.second); DBG_INF_FMT("%s", value); - ZVAL_STRINGL(zv, value, length, 1); + ZVAL_STRINGL(zv, value, length); mnd_sprintf_free(value); DBG_VOID_RETURN; } @@ -254,10 +254,10 @@ ps_fetch_time(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_le /* {{{ ps_fetch_date */ static void -ps_fetch_date(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) +ps_fetch_date(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { struct st_mysqlnd_time t = {0}; - unsigned long length; /* First byte encodes the length*/ + zend_ulong length; /* First byte encodes the length*/ char * value; DBG_ENTER("ps_fetch_date"); @@ -282,7 +282,7 @@ ps_fetch_date(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_le length = mnd_sprintf(&value, 0, "%04u-%02u-%02u", t.year, t.month, t.day); DBG_INF_FMT("%s", value); - ZVAL_STRINGL(zv, value, length, 1); + ZVAL_STRINGL(zv, value, length); mnd_sprintf_free(value); DBG_VOID_RETURN; } @@ -291,10 +291,10 @@ ps_fetch_date(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_le /* {{{ ps_fetch_datetime */ static void -ps_fetch_datetime(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) +ps_fetch_datetime(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { struct st_mysqlnd_time t; - unsigned long length; /* First byte encodes the length*/ + zend_ulong length; /* First byte encodes the length*/ char * value; DBG_ENTER("ps_fetch_datetime"); @@ -315,7 +315,7 @@ ps_fetch_datetime(zval * zv, const MYSQLND_FIELD * const field, unsigned int pac } else { t.hour = t.minute = t.second= 0; } - t.second_part = (length > 7) ? (unsigned long) sint4korr(to+7) : 0; + t.second_part = (length > 7) ? (zend_ulong) sint4korr(to+7) : 0; (*row)+= length; } else { @@ -326,7 +326,7 @@ ps_fetch_datetime(zval * zv, const MYSQLND_FIELD * const field, unsigned int pac length = mnd_sprintf(&value, 0, "%04u-%02u-%02u %02u:%02u:%02u", t.year, t.month, t.day, t.hour, t.minute, t.second); DBG_INF_FMT("%s", value); - ZVAL_STRINGL(zv, value, length, 1); + ZVAL_STRINGL(zv, value, length); mnd_sprintf_free(value); DBG_VOID_RETURN; } @@ -335,17 +335,17 @@ ps_fetch_datetime(zval * zv, const MYSQLND_FIELD * const field, unsigned int pac /* {{{ ps_fetch_string */ static void -ps_fetch_string(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) +ps_fetch_string(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { /* For now just copy, before we make it possible to write \0 to the row buffer */ - const unsigned long length = php_mysqlnd_net_field_length(row); + const zend_ulong length = php_mysqlnd_net_field_length(row); DBG_ENTER("ps_fetch_string"); DBG_INF_FMT("len = %lu", length); DBG_INF("copying from the row buffer"); - ZVAL_STRINGL(zv, (char *)*row, length, 1); + ZVAL_STRINGL(zv, (char *)*row, length); (*row) += length; DBG_VOID_RETURN; @@ -355,10 +355,10 @@ ps_fetch_string(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_ /* {{{ ps_fetch_bit */ static void -ps_fetch_bit(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC) +ps_fetch_bit(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { - unsigned long length = php_mysqlnd_net_field_length(row); - ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, length TSRMLS_CC); + zend_ulong length = php_mysqlnd_net_field_length(row); + ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, length); } /* }}} */ @@ -514,16 +514,13 @@ void _mysqlnd_init_ps_fetch_subsystem() /* {{{ mysqlnd_stmt_copy_it */ static enum_func_status -mysqlnd_stmt_copy_it(zval *** copies, zval * original, unsigned int param_count, unsigned int current TSRMLS_DC) +mysqlnd_stmt_copy_it(zval ** copies, zval * original, unsigned int param_count, unsigned int current) { if (!*copies) { - *copies = mnd_ecalloc(param_count, sizeof(zval *)); + *copies = mnd_ecalloc(param_count, sizeof(zval)); } if (*copies) { - MAKE_STD_ZVAL((*copies)[current]); - *(*copies)[current] = *original; - Z_SET_REFCOUNT_P((*copies)[current], 1); - zval_copy_ctor((*copies)[current]); + ZVAL_COPY(&(*copies)[current], original); return PASS; } return FAIL; @@ -533,14 +530,12 @@ mysqlnd_stmt_copy_it(zval *** copies, zval * original, unsigned int param_count, /* {{{ mysqlnd_stmt_free_copies */ static void -mysqlnd_stmt_free_copies(MYSQLND_STMT_DATA * stmt, zval ** copies TSRMLS_DC) +mysqlnd_stmt_free_copies(MYSQLND_STMT_DATA * stmt, zval *copies) { if (copies) { unsigned int i; for (i = 0; i < stmt->param_count; i++) { - if (copies[i]) { - zval_ptr_dtor(&copies[i]); - } + zval_ptr_dtor(&copies[i]); } mnd_efree(copies); } @@ -550,7 +545,7 @@ mysqlnd_stmt_free_copies(MYSQLND_STMT_DATA * stmt, zval ** copies TSRMLS_DC) /* {{{ mysqlnd_stmt_execute_check_n_enlarge_buffer */ static enum_func_status -mysqlnd_stmt_execute_check_n_enlarge_buffer(zend_uchar **buf, zend_uchar **p, size_t * buf_len, zend_uchar * const provided_buffer, size_t needed_bytes TSRMLS_DC) +mysqlnd_stmt_execute_check_n_enlarge_buffer(zend_uchar **buf, zend_uchar **p, size_t * buf_len, zend_uchar * const provided_buffer, size_t needed_bytes) { const size_t overalloc = 5; size_t left = (*buf_len - (*p - *buf)); @@ -578,39 +573,36 @@ mysqlnd_stmt_execute_check_n_enlarge_buffer(zend_uchar **buf, zend_uchar **p, si /* {{{ mysqlnd_stmt_execute_prepare_param_types */ static enum_func_status -mysqlnd_stmt_execute_prepare_param_types(MYSQLND_STMT_DATA * stmt, zval *** copies_param, int * resend_types_next_time TSRMLS_DC) +mysqlnd_stmt_execute_prepare_param_types(MYSQLND_STMT_DATA * stmt, zval ** copies_param, int * resend_types_next_time) { unsigned int i; 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_P(stmt->param_bind[i].zv) != IS_NULL && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) { - zval ** copies; + 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_P(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)) { SET_OOM_ERROR(*stmt->error_info); goto end; } - copies = *copies_param; /* 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_P(stmt->param_bind[i].zv) != IS_LONG) { - zval *tmp_data = (copies && copies[i])? copies[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 + 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; - MAKE_STD_ZVAL(tmp_data_copy); - *tmp_data_copy = *tmp_data; - Z_SET_REFCOUNT_P(tmp_data_copy, 1); - zval_copy_ctor(tmp_data_copy); + zval tmp_data_copy; + ZVAL_COPY(&tmp_data_copy, tmp_data); convert_to_double_ex(&tmp_data_copy); /* @@ -618,11 +610,11 @@ mysqlnd_stmt_execute_prepare_param_types(MYSQLND_STMT_DATA * stmt, zval *** copi Check bug #52891 : Wrong data inserted with mysqli/mysqlnd when using bind_param, value > LONG_MAX We do transformation here, which will be used later when sending types. The code later relies on this. */ - if (Z_DVAL_P(tmp_data_copy) > LONG_MAX || Z_DVAL_P(tmp_data_copy) < LONG_MIN) { + if (Z_DVAL(tmp_data_copy) > ZEND_LONG_MAX || Z_DVAL(tmp_data_copy) < ZEND_LONG_MIN) { stmt->send_types_to_server = *resend_types_next_time = 1; - convert_to_string_ex(&tmp_data); + convert_to_string_ex(tmp_data); } else { - convert_to_long_ex(&tmp_data); + convert_to_long_ex(tmp_data); } zval_ptr_dtor(&tmp_data_copy); @@ -638,24 +630,26 @@ end: /* {{{ mysqlnd_stmt_execute_store_types */ static void -mysqlnd_stmt_execute_store_types(MYSQLND_STMT_DATA * stmt, zval ** copies, zend_uchar ** p) +mysqlnd_stmt_execute_store_types(MYSQLND_STMT_DATA * stmt, zval * copies, zend_uchar ** p) { 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 SIZEOF_ZEND_LONG==8 if (current_type == MYSQL_TYPE_LONG) { current_type = MYSQL_TYPE_LONGLONG; } #endif - if (Z_TYPE_P(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)) { /* 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_P(stmt->param_bind[i].zv) != IS_LONG) { - const zval *tmp_data = (copies && 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. @@ -680,28 +674,33 @@ mysqlnd_stmt_execute_store_types(MYSQLND_STMT_DATA * stmt, zval ** copies, zend_ /* {{{ mysqlnd_stmt_execute_calculate_param_values_size */ static enum_func_status -mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval *** copies_param, size_t * data_size TSRMLS_DC) +mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval ** copies_param, size_t * data_size) { unsigned int i; DBG_ENTER("mysqlnd_stmt_execute_calculate_param_values_size"); 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 || !(*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)) { + SET_OOM_ERROR(*stmt->error_info); + goto end; + } } + break; } - break; } } @@ -709,8 +708,8 @@ mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval case MYSQL_TYPE_DOUBLE: *data_size += 8; if (Z_TYPE_P(the_var) != IS_DOUBLE) { - if (!*copies_param || !(*copies_param)[i]) { - if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i TSRMLS_CC)) { + if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) { + if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i)) { SET_OOM_ERROR(*stmt->error_info); goto end; } @@ -722,11 +721,11 @@ mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval /* fall-through */ case MYSQL_TYPE_LONG: { - zval *tmp_data = (*copies_param && (*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; } - convert_to_long_ex(&tmp_data); + convert_to_long_ex(tmp_data); } *data_size += 4 + is_longlong; break; @@ -744,15 +743,15 @@ mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval use_string: *data_size += 8; /* max 8 bytes for size */ if (Z_TYPE_P(the_var) != IS_STRING) { - if (!*copies_param || !(*copies_param)[i]) { - if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i TSRMLS_CC)) { + if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) { + if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i)) { SET_OOM_ERROR(*stmt->error_info); goto end; } } - the_var = (*copies_param)[i]; + the_var = &((*copies_param)[i]); } - convert_to_string_ex(&the_var); + convert_to_string_ex(the_var); *data_size += Z_STRLEN_P(the_var); break; } @@ -766,18 +765,21 @@ end: /* {{{ mysqlnd_stmt_execute_store_param_values */ static void -mysqlnd_stmt_execute_store_param_values(MYSQLND_STMT_DATA * stmt, zval ** copies, zend_uchar * buf, zend_uchar ** p, size_t null_byte_offset) +mysqlnd_stmt_execute_store_param_values(MYSQLND_STMT_DATA * stmt, zval * copies, zend_uchar * buf, zend_uchar ** p, size_t null_byte_offset) { unsigned int i; for (i = 0; i < stmt->param_count; i++) { - zval * data = (copies && 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 (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) { case MYSQL_TYPE_DOUBLE: - convert_to_double_ex(&data); + convert_to_double_ex(data); float8store(*p, Z_DVAL_P(data)); (*p) += 8; break; @@ -828,13 +830,12 @@ send_string: /* {{{ mysqlnd_stmt_execute_store_params */ static enum_func_status -mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar **p, size_t *buf_len TSRMLS_DC) +mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar **p, size_t *buf_len ) { MYSQLND_STMT_DATA * stmt = s->data; - unsigned int i = 0; zend_uchar * provided_buffer = *buf; size_t data_size = 0; - zval **copies = NULL;/* if there are different types */ + zval *copies = NULL;/* if there are different types */ enum_func_status ret = FAIL; int resend_types_next_time = 0; size_t null_byte_offset; @@ -843,7 +844,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar { unsigned int null_count = (stmt->param_count + 7) / 8; - if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, null_count TSRMLS_CC)) { + if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, null_count)) { SET_OOM_ERROR(*stmt->error_info); goto end; } @@ -861,7 +862,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar won't expect it and interpret the value as 0. Thus we need to resend the types, if any such values occur, and force resend for the next execution. */ - if (FAIL == mysqlnd_stmt_execute_prepare_param_types(stmt, &copies, &resend_types_next_time TSRMLS_CC)) { + if (FAIL == mysqlnd_stmt_execute_prepare_param_types(stmt, &copies, &resend_types_next_time)) { goto end; } @@ -869,7 +870,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar (*p)++; if (stmt->send_types_to_server) { - if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, stmt->param_count * 2 TSRMLS_CC)) { + if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, stmt->param_count * 2)) { SET_OOM_ERROR(*stmt->error_info); goto end; } @@ -880,12 +881,12 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar /* 2. Store data */ /* 2.1 Calculate how much space we need */ - if (FAIL == mysqlnd_stmt_execute_calculate_param_values_size(stmt, &copies, &data_size TSRMLS_CC)) { + if (FAIL == mysqlnd_stmt_execute_calculate_param_values_size(stmt, &copies, &data_size)) { goto end; } /* 2.2 Enlarge the buffer, if needed */ - if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, data_size TSRMLS_CC)) { + if (FAIL == mysqlnd_stmt_execute_check_n_enlarge_buffer(buf, p, buf_len, provided_buffer, data_size)) { SET_OOM_ERROR(*stmt->error_info); goto end; } @@ -895,7 +896,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar ret = PASS; end: - mysqlnd_stmt_free_copies(stmt, copies TSRMLS_CC); + mysqlnd_stmt_free_copies(stmt, copies); DBG_INF_FMT("ret=%s", ret == PASS? "PASS":"FAIL"); DBG_RETURN(ret); @@ -905,7 +906,7 @@ end: /* {{{ mysqlnd_stmt_execute_generate_request */ enum_func_status -mysqlnd_stmt_execute_generate_request(MYSQLND_STMT * const s, zend_uchar ** request, size_t *request_len, zend_bool * free_buffer TSRMLS_DC) +mysqlnd_stmt_execute_generate_request(MYSQLND_STMT * const s, zend_uchar ** request, size_t *request_len, zend_bool * free_buffer) { MYSQLND_STMT_DATA * stmt = s->data; zend_uchar *p = stmt->execute_cmd_buffer.buffer, @@ -923,12 +924,12 @@ mysqlnd_stmt_execute_generate_request(MYSQLND_STMT * const s, zend_uchar ** requ p++; /* Make it all zero */ - int4store(p, 0); + int4store(p, 0); int1store(p, 1); /* and send 1 for iteration count */ p+= 4; - ret = mysqlnd_stmt_execute_store_params(s, &cmd_buffer, &p, &cmd_buffer_length TSRMLS_CC); + ret = mysqlnd_stmt_execute_store_params(s, &cmd_buffer, &p, &cmd_buffer_length); *free_buffer = (cmd_buffer != stmt->execute_cmd_buffer.buffer); *request_len = (p - cmd_buffer); |