diff options
Diffstat (limited to 'ext/mysqlnd/mysqlnd_ps_codec.c')
-rw-r--r-- | ext/mysqlnd/mysqlnd_ps_codec.c | 182 |
1 files changed, 114 insertions, 68 deletions
diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c index 650584c0f..9256763a9 100644 --- a/ext/mysqlnd/mysqlnd_ps_codec.c +++ b/ext/mysqlnd/mysqlnd_ps_codec.c @@ -1,8 +1,8 @@ /* +----------------------------------------------------------------------+ - | PHP Version 6 | + | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 2006-2009 The PHP Group | + | Copyright (c) 2006-2010 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_ps_codec.c 289030 2009-09-30 23:34:56Z andrey $ */ +/* $Id: mysqlnd_ps_codec.c 300735 2010-06-24 19:52:13Z andrey $ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_wireprotocol.h" @@ -61,7 +61,7 @@ void ps_fetch_from_1_to_8_bytes(zval *zv, const MYSQLND_FIELD * const field, size_t tmp_len = 0; zend_bool is_bit = field->type == MYSQL_TYPE_BIT; DBG_ENTER("ps_fetch_from_1_to_8_bytes"); - DBG_INF_FMT("zv=%p byte_count=%d", zv, byte_count); + DBG_INF_FMT("zv=%p byte_count=%u", zv, byte_count); if (field->flags & UNSIGNED_FLAG) { uint64_t uval = 0; @@ -106,10 +106,10 @@ void ps_fetch_from_1_to_8_bytes(zval *zv, const MYSQLND_FIELD * const field, } #if SIZEOF_LONG==4 - if ((L64(2147483647) < (int64_t) lval) || (L64(-2147483648) > (int64_t) lval)) { + if ((L64(2147483647) < (int64_t) lval) || (L64(-2147483648) > (int64_t) lval)) { DBG_INF("stringify"); tmp_len = sprintf((char *)&tmp, MYSQLND_LL_SPEC, lval); - } else + } else #endif /* SIZEOF */ { ZVAL_LONG(zv, lval); @@ -126,7 +126,7 @@ void ps_fetch_from_1_to_8_bytes(zval *zv, const MYSQLND_FIELD * const field, { DBG_INF("stringify"); ZVAL_STRINGL(zv, tmp, tmp_len, 1); - } + } } (*row)+= byte_count; DBG_VOID_RETURN; @@ -199,7 +199,7 @@ void ps_fetch_float(zval *zv, const MYSQLND_FIELD * const field, DBG_ENTER("ps_fetch_float"); float4get(value, *row); ZVAL_DOUBLE(zv, value); - (*row)+= 4; + (*row)+= 4; DBG_INF_FMT("value=%f", value); DBG_VOID_RETURN; } @@ -256,24 +256,23 @@ void ps_fetch_time(zval *zv, const MYSQLND_FIELD * const field, } else { memset(&t, 0, sizeof(t)); t.time_type = MYSQLND_TIMESTAMP_TIME; - } + } /* QQ : How to make this unicode without copying two times the buffer - Unicode equivalent of spprintf? */ - length = spprintf(&to, 0, "%s%02u:%02u:%02u", - (t.neg ? "-" : ""), t.hour, t.minute, t.second); + length = spprintf(&to, 0, "%s%02u:%02u:%02u", (t.neg ? "-" : ""), t.hour, t.minute, t.second); DBG_INF_FMT("%s", to); #if PHP_MAJOR_VERSION >= 6 if (!as_unicode) { #endif ZVAL_STRINGL(zv, to, length, 1); - mnd_efree(to); + efree(to); /* allocated by spprintf */ #if PHP_MAJOR_VERSION >= 6 } else { - ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); + ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); } #endif DBG_VOID_RETURN; @@ -321,10 +320,10 @@ void ps_fetch_date(zval *zv, const MYSQLND_FIELD * const field, if (!as_unicode) { #endif ZVAL_STRINGL(zv, to, length, 1); - mnd_efree(to); + efree(to); /* allocated by spprintf */ #if PHP_MAJOR_VERSION >= 6 } else { - ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); + ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); } #endif DBG_VOID_RETURN; @@ -358,7 +357,7 @@ void ps_fetch_datetime(zval *zv, const MYSQLND_FIELD * const field, t.minute = (unsigned int) to[5]; t.second = (unsigned int) to[6]; } else { - t.hour = t.minute = t.second= 0; + t.hour = t.minute = t.second= 0; } t.second_part = (length > 7) ? (unsigned long) sint4korr(to+7) : 0; @@ -380,10 +379,10 @@ void ps_fetch_datetime(zval *zv, const MYSQLND_FIELD * const field, if (!as_unicode) { #endif ZVAL_STRINGL(zv, to, length, 1); - mnd_efree(to); + efree(to); /* allocated by spprintf */ #if PHP_MAJOR_VERSION >= 6 } else { - ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); + ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); } #endif DBG_VOID_RETURN; @@ -406,7 +405,7 @@ void ps_fetch_string(zval *zv, const MYSQLND_FIELD * const field, DBG_INF_FMT("len = %lu", length); #if PHP_MAJOR_VERSION < 6 DBG_INF("copying from the row buffer"); - ZVAL_STRINGL(zv, (char *)*row, length, 1); + ZVAL_STRINGL(zv, (char *)*row, length, 1); #else if (field->charsetnr == MYSQLND_BINARY_CHARSET_NR) { DBG_INF("Binary charset"); @@ -440,92 +439,92 @@ void _mysqlnd_init_ps_fetch_subsystem() { memset(mysqlnd_ps_fetch_functions, 0, sizeof(mysqlnd_ps_fetch_functions)); mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].func = ps_fetch_null; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].pack_len = 0; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].php_type = IS_NULL; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].pack_len = 0; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].php_type = IS_NULL; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY].func = ps_fetch_int8; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY].pack_len = 1; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY].php_type = IS_LONG; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_SHORT].func = ps_fetch_int16; mysqlnd_ps_fetch_functions[MYSQL_TYPE_SHORT].pack_len = 2; mysqlnd_ps_fetch_functions[MYSQL_TYPE_SHORT].php_type = IS_LONG; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_SHORT].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_SHORT].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_YEAR].func = ps_fetch_int16; mysqlnd_ps_fetch_functions[MYSQL_TYPE_YEAR].pack_len = 2; mysqlnd_ps_fetch_functions[MYSQL_TYPE_YEAR].php_type = IS_LONG; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_YEAR].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_YEAR].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_INT24].func = ps_fetch_int32; mysqlnd_ps_fetch_functions[MYSQL_TYPE_INT24].pack_len = 4; mysqlnd_ps_fetch_functions[MYSQL_TYPE_INT24].php_type = IS_LONG; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_INT24].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_INT24].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG].func = ps_fetch_int32; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG].pack_len = 4; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG].php_type = IS_LONG; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG].php_type = IS_LONG; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONGLONG].func = ps_fetch_int64; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONGLONG].pack_len= 8; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONGLONG].php_type = IS_LONG; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONGLONG].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONGLONG].php_type= IS_LONG; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONGLONG].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_FLOAT].func = ps_fetch_float; mysqlnd_ps_fetch_functions[MYSQL_TYPE_FLOAT].pack_len = 4; mysqlnd_ps_fetch_functions[MYSQL_TYPE_FLOAT].php_type = IS_DOUBLE; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_FLOAT].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_FLOAT].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DOUBLE].func = ps_fetch_double; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DOUBLE].pack_len = 8; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_DOUBLE].php_type = IS_DOUBLE; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_DOUBLE].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_DOUBLE].php_type = IS_DOUBLE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_DOUBLE].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIME].func = ps_fetch_time; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIME].pack_len = MYSQLND_PS_SKIP_RESULT_W_LEN; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIME].php_type = IS_STRING; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIME].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIME].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATE].func = ps_fetch_date; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATE].pack_len = MYSQLND_PS_SKIP_RESULT_W_LEN; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATE].php_type = IS_STRING; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATE].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATE].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDATE].func = ps_fetch_date; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDATE].pack_len = MYSQLND_PS_SKIP_RESULT_W_LEN; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDATE].php_type = IS_STRING; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDATE].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDATE].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATETIME].func = ps_fetch_datetime; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATETIME].pack_len= MYSQLND_PS_SKIP_RESULT_W_LEN; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATETIME].php_type= IS_STRING; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATETIME].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATETIME].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].func = ps_fetch_datetime; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].pack_len= MYSQLND_PS_SKIP_RESULT_W_LEN; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].php_type= IS_STRING; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].pack_len= MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].is_possibly_blob = TRUE; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].pack_len = MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].is_possibly_blob = TRUE; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].can_ret_as_str_in_uni = TRUE; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].func = ps_fetch_string; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].pack_len= MYSQLND_PS_SKIP_RESULT_STR; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].php_type= IS_STRING; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].func = ps_fetch_string; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].pack_len = MYSQLND_PS_SKIP_RESULT_STR; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].is_possibly_blob = TRUE; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].pack_len = MYSQLND_PS_SKIP_RESULT_STR; @@ -545,23 +544,23 @@ void _mysqlnd_init_ps_fetch_subsystem() mysqlnd_ps_fetch_functions[MYSQL_TYPE_VARCHAR].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_VARCHAR].pack_len = MYSQLND_PS_SKIP_RESULT_STR; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_VARCHAR].php_type = IS_STRING; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_VARCHAR].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_VARCHAR].is_possibly_blob = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_STRING].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_STRING].pack_len = MYSQLND_PS_SKIP_RESULT_STR; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_STRING].php_type = IS_STRING; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_STRING].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_STRING].is_possibly_blob = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DECIMAL].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DECIMAL].pack_len = MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DECIMAL].php_type = IS_STRING; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_DECIMAL].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_DECIMAL].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDECIMAL].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDECIMAL].pack_len = MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDECIMAL].php_type = IS_STRING; - mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDECIMAL].can_ret_as_str_in_uni = TRUE; + mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDECIMAL].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_ENUM].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_ENUM].pack_len = MYSQLND_PS_SKIP_RESULT_STR; @@ -579,29 +578,38 @@ void _mysqlnd_init_ps_fetch_subsystem() /* {{{ mysqlnd_stmt_copy_it */ -static void +static enum_func_status mysqlnd_stmt_copy_it(zval *** copies, zval *original, unsigned int param_count, unsigned int current TSRMLS_DC) { 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]); + return PASS; } - MAKE_STD_ZVAL((*copies)[current]); - *(*copies)[current] = *original; - Z_SET_REFCOUNT_P((*copies)[current], 1); - zval_copy_ctor((*copies)[current]); + return FAIL; } /* }}} */ /* {{{ mysqlnd_stmt_execute_store_params */ -static void -mysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uchar **p, +static enum_func_status +mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar **p, size_t *buf_len, unsigned int null_byte_offset TSRMLS_DC) { + MYSQLND_STMT_DATA * stmt = s->data; unsigned int i = 0; + zend_uchar * provided_buffer = *buf; size_t left = (*buf_len - (*p - *buf)); size_t data_size = 0; zval **copies = NULL;/* if there are different types */ + enum_func_status ret = FAIL; + + DBG_ENTER("mysqlnd_stmt_execute_store_params"); /* 1. Store type information */ if (stmt->send_types_to_server) { @@ -612,6 +620,10 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uch zend_uchar *tmp_buf; *buf_len = offset + stmt->param_count * 2 + 20; tmp_buf = mnd_emalloc(*buf_len); + if (!tmp_buf) { + SET_OOM_ERROR(stmt->error_info); + goto end; + } memcpy(tmp_buf, *buf, offset); *buf = tmp_buf; @@ -636,14 +648,16 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uch unsigned int j; zval *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)) { + if (!the_var || (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 */ - mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC); + if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) { + SET_OOM_ERROR(stmt->error_info); + goto end; + } break; } } @@ -653,7 +667,10 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uch data_size += 8; if (Z_TYPE_P(the_var) != IS_DOUBLE) { if (!copies || !copies[i]) { - mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC); + if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) { + SET_OOM_ERROR(stmt->error_info); + goto end; + } } } break; @@ -668,7 +685,10 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uch #endif if (Z_TYPE_P(the_var) != IS_LONG) { if (!copies || !copies[i]) { - mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC); + if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) { + SET_OOM_ERROR(stmt->error_info); + goto end; + } } } break; @@ -691,7 +711,10 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uch #endif { if (!copies || !copies[i]) { - mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC); + if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) { + SET_OOM_ERROR(stmt->error_info); + goto end; + } } the_var = copies[i]; #if PHP_MAJOR_VERSION >= 6 @@ -714,10 +737,22 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uch zend_uchar *tmp_buf; *buf_len = offset + data_size + 10; /* Allocate + 10 for safety */ tmp_buf = mnd_emalloc(*buf_len); + if (!tmp_buf) { + SET_OOM_ERROR(stmt->error_info); + goto end; + } memcpy(tmp_buf, *buf, offset); + /* + When too many columns the buffer provided to the function might not be sufficient. + In this case new buffer has been allocated above. When we allocate a buffer and then + allocate a bigger one here, we should free the first one. + */ + if (*buf != provided_buffer) { + mnd_efree(*buf); + } *buf = tmp_buf; /* Update our pos pointer */ - *p = *buf + offset; + *p = *buf + offset; } /* 2.3 Store the actual data */ @@ -771,27 +806,36 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uch } } } + ret = PASS; +end: if (copies) { for (i = 0; i < stmt->param_count; i++) { if (copies[i]) { zval_ptr_dtor(&copies[i]); } } - mnd_efree(copies); + mnd_efree(copies); } + + DBG_INF_FMT("ret=%s", ret == PASS? "PASS":"FAIL"); + DBG_RETURN(ret); } /* }}} */ /* {{{ mysqlnd_stmt_execute_generate_request */ -zend_uchar* mysqlnd_stmt_execute_generate_request(MYSQLND_STMT *stmt, size_t *request_len, - zend_bool *free_buffer TSRMLS_DC) +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_DATA * stmt = s->data; zend_uchar *p = stmt->execute_cmd_buffer.buffer, *cmd_buffer = stmt->execute_cmd_buffer.buffer; size_t cmd_buffer_length = stmt->execute_cmd_buffer.length; unsigned int null_byte_offset, null_count= (stmt->param_count + 7) / 8; + enum_func_status ret; + + DBG_ENTER("mysqlnd_stmt_execute_generate_request"); int4store(p, stmt->stmt_id); p += 4; @@ -815,11 +859,13 @@ zend_uchar* mysqlnd_stmt_execute_generate_request(MYSQLND_STMT *stmt, size_t *re int1store(p, stmt->send_types_to_server); p++; - mysqlnd_stmt_execute_store_params(stmt, &cmd_buffer, &p, &cmd_buffer_length, null_byte_offset TSRMLS_CC); + ret = mysqlnd_stmt_execute_store_params(s, &cmd_buffer, &p, &cmd_buffer_length, null_byte_offset TSRMLS_CC); *free_buffer = (cmd_buffer != stmt->execute_cmd_buffer.buffer); *request_len = (p - cmd_buffer); - return cmd_buffer; + *request = cmd_buffer; + DBG_INF_FMT("ret=%s", ret == PASS? "PASS":"FAIL"); + DBG_RETURN(ret); } /* }}} */ |