]> granicus.if.org Git - php/commitdiff
Fixed bugs in binding result
authorXinchen Hui <laruence@php.net>
Fri, 20 Jun 2014 05:08:40 +0000 (13:08 +0800)
committerXinchen Hui <laruence@php.net>
Fri, 20 Jun 2014 05:08:40 +0000 (13:08 +0800)
ext/mysqlnd/mysqlnd_ps.c

index b114296130879900228cb442e00c11f43bf5cb44..b63886362162af6825f9f46552dfdad9476ca628 100644 (file)
@@ -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), &current_row[i]);
+                                                       ZVAL_COPY_VALUE(result, &current_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);
                        }