com php-src: Fixed bugs in binding result: ext/mysqlnd/mysqlnd _ps.c
| From: | Xinchen Hui | Date: | Fri, 20 Jun 2014 05:08:40 +0000 |
| Subject: | com php-src: Fixed bugs in binding result: ext/mysqlnd/mysqlnd _ps.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-78996@lists.php.net to get a copy of this message | ||
Commit: e091a91f4337f79c4314b18706dfd277ce1c01fc
Author: Xinchen Hui <laruence@php.net> Fri, 20 Jun 2014 13:08:40 +0800
Parents: 80108a16072c335050cfa778456ef667f480cf91
Branches: phpng
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=e091a91f4337f79c4314b18706dfd277ce1c01fc
Log:
Fixed bugs in binding result
Changed paths:
M ext/mysqlnd/mysqlnd_ps.c
Diff:
diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c
index b114296..b638863 100644
--- a/ext/mysqlnd/mysqlnd_ps.c
+++ b/ext/mysqlnd/mysqlnd_ps.c
@@ -644,13 +644,15 @@ MYSQLND_METHOD(mysqlnd_stmt, execute)(MYSQLND_STMT * const s TSRMLS_DC)
fetch(); <-- no binding, but that's not a problem
bind_result();
execute(); <-- here we will leak because we separate without need
+ */
unsigned int i;
for (i = 0; i < stmt->field_count; i++) {
if (stmt->result_bind[i].bound == TRUE) {
- zval_copy_ctor(&stmt->result_bind[i].zv);
+ zval *result = &stmt->result_bind[i].zv;
+ ZVAL_DEREF(result);
+ zval_copy_ctor(result);
}
}
- */
}
#endif
@@ -786,9 +788,12 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, unsigned
int
}
for (i = 0; i < result->field_count; i++) {
+ zval *result = &stmt->result_bind[i].zv;
+
+ ZVAL_DEREF(result);
/* Clean what we copied last time */
#ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
- zval_dtor(Z_REFVAL(stmt->result_bind[i].zv));
+ zval_dtor(result);
#endif
/* copy the type */
if (stmt->result_bind[i].bound == TRUE) {
@@ -802,12 +807,12 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES * result, void * param, unsigned
int
counting the user can't delete the strings the variables point to.
*/
- ZVAL_COPY_VALUE(Z_REFVAL(stmt->result_bind[i].zv), ¤t_row[i]);
+ ZVAL_COPY_VALUE(result, ¤t_row[i]);
#ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
- zval_copy_ctor(Z_REFVAL(stmt->result_bind[i].zv));
+ zval_copy_ctor(result);
#endif
} else {
- ZVAL_NULL(Z_REFVAL(stmt->result_bind[i].zv));
+ ZVAL_NULL(result);
}
}
}
@@ -890,19 +895,22 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, unsigned
i
for (i = 0; i < field_count; i++) {
if (stmt->result_bind[i].bound == TRUE) {
zval *data = &result->unbuf->last_row_data[i];
+ zval *result = &stmt->result_bind[i].zv;
+
+ ZVAL_DEREF(result);
/*
stmt->result_bind[i].zv has been already destructed
in result->unbuf->m.free_last_data()
*/
#ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
- zval_dtor(Z_REFVAL(stmt->result_bind[i].zv));
+ zval_dtor(result);
#endif
if (!Z_ISNULL_P(data)) {
if ((Z_TYPE_P(data) == IS_STRING) &&
(meta->fields[i].max_length < (unsigned long) Z_STRLEN_P(data))) {
meta->fields[i].max_length = Z_STRLEN_P(data);
}
- ZVAL_COPY_VALUE(Z_REFVAL(stmt->result_bind[i].zv), data);
+ ZVAL_COPY_VALUE(result, data);
/* copied data, thus also the ownership. Thus null data */
ZVAL_NULL(data);
}
@@ -1071,22 +1079,26 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, unsigned
int f
for (i = 0; i < field_count; i++) {
if (stmt->result_bind[i].bound == TRUE) {
zval *data = &result->unbuf->last_row_data[i];
+ zval *result = &stmt->result_bind[i].zv;
+
+ ZVAL_DEREF(result);
/*
stmt->result_bind[i].zv has been already destructed
in result->unbuf->m.free_last_data()
*/
#ifndef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
- zval_dtor(Z_REFVAL(stmt->result_bind[i].zv));
+ zval_dtor(result);
#endif
DBG_INF_FMT("i=%u bound_var=%p type=%u refc=%u", i, &stmt->result_bind[i].zv,
Z_TYPE_P(data), Z_REFCOUNTED(stmt->result_bind[i].zv)?
Z_REFCOUNT(stmt->result_bind[i].zv) : 0);
+
if (!Z_ISNULL_P(data)) {
if ((Z_TYPE_P(data) == IS_STRING) &&
(meta->fields[i].max_length < (unsigned long) Z_STRLEN_P(data))) {
meta->fields[i].max_length = Z_STRLEN_P(data);
}
- ZVAL_COPY_VALUE(Z_REFVAL(stmt->result_bind[i].zv), data);
+ ZVAL_COPY_VALUE(result, data);
/* copied data, thus also the ownership. Thus null data */
ZVAL_NULL(data);
}
@@ -1183,8 +1195,10 @@ MYSQLND_METHOD(mysqlnd_stmt, fetch)(MYSQLND_STMT * const s, zend_bool * const
fe
*/
for (i = 0; i < stmt->result->field_count; i++) {
if (stmt->result_bind[i].bound == TRUE) {
- zval_dtor(Z_REFVAL(stmt->result_bind[i].zv));
- ZVAL_NULL(Z_REFVAL(stmt->result_bind[i].zv));
+ zval *result = &stmt->result_bind[i].zv;
+ ZVAL_DEREF(result);
+ zval_dtor(result);
+ ZVAL_NULL(result);
}
}
stmt->result_zvals_separated_once = TRUE;
@@ -1503,7 +1517,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_one_parameter)(MYSQLND_STMT * const s,
unsigne
/* Prevent from freeing */
/* Don't update is_ref, or we will leak during conversion */
- Z_ADDREF_P(zv);
+ Z_TRY_ADDREF_P(zv);
DBG_INF("Binding");
/* Release what we had, if we had */
zval_ptr_dtor(&stmt->param_bind[param_no].zv);
@@ -1588,6 +1602,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const s,
for (i = 0; i < stmt->field_count; i++) {
/* Prevent from freeing */
Z_TRY_ADDREF(stmt->result_bind[i].zv);
+
DBG_INF_FMT("ref of %p = %u", &stmt->result_bind[i].zv,
Z_REFCOUNTED(stmt->result_bind[i].zv)? Z_REFCOUNT(stmt->result_bind[i].zv) : 0);
/*
@@ -2026,7 +2041,7 @@ mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const s TSRMLS_DC)
which the user has lost reference.
*/
#ifdef WE_DONT_COPY_IN_BUFFERED_AND_UNBUFFERED_BECAUSEOF_IS_REF
- ZVAL_NULL(stmt->result_bind[i].zv);
+ ZVAL_NULL(&stmt->result_bind[i].zv);
#endif
zval_ptr_dtor(&stmt->result_bind[i].zv);
}