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 | |
| parent | 80108a16072c335050cfa778456ef667f480cf91 (diff) | |
| download | php-git-e091a91f4337f79c4314b18706dfd277ce1c01fc.tar.gz | |
Fixed bugs in binding result
Diffstat (limited to 'ext/mysqlnd')
| -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);  			}  | 
