diff options
| author | Xinchen Hui <laruence@php.net> | 2014-06-20 13:08:40 +0800 |
|---|---|---|
| committer | Xinchen Hui <laruence@php.net> | 2014-06-20 13:08:40 +0800 |
| commit | e091a91f4337f79c4314b18706dfd277ce1c01fc (patch) | |
| tree | 76798bd0775a7784b8ac7752c611bf88ce373236 /ext/mysqlnd/mysqlnd_ps.c | |
| parent | 80108a16072c335050cfa778456ef667f480cf91 (diff) | |
| download | php-git-e091a91f4337f79c4314b18706dfd277ce1c01fc.tar.gz | |
Fixed bugs in binding result
Diffstat (limited to 'ext/mysqlnd/mysqlnd_ps.c')
| -rw-r--r-- | ext/mysqlnd/mysqlnd_ps.c | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index b114296130..b638863621 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); } |
