andrey                                   Fri, 21 May 2010 13:37:18 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=299579

Log:
Check set->data for validity before using it.
Prevents crashes after OOM.

Changed paths:
    U   php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c
    U   php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c

Modified: php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c   2010-05-21 
13:06:52 UTC (rev 299578)
+++ php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c   2010-05-21 
13:37:18 UTC (rev 299579)
@@ -186,34 +186,37 @@
        DBG_ENTER("mysqlnd_res::free_buffered_data");
        DBG_INF_FMT("Freeing "MYSQLND_LLU_SPEC" row(s)", set->row_count);

-       DBG_INF_FMT("before: real_usage=%lu  usage=%lu", zend_memory_usage(TRUE 
TSRMLS_CC), zend_memory_usage(FALSE TSRMLS_CC));
-       for (row = set->row_count - 1; row >= 0; row--) {
-               zval **current_row = set->data + row * field_count;
-               MYSQLND_MEMORY_POOL_CHUNK *current_buffer = 
set->row_buffers[row];
-               int col;
+       DBG_INF("Freeing data & row_buffer");
+       if (set->data) {

-               for (col = field_count - 1; col >= 0; --col) {
-                       zend_bool copy_ctor_called;
-                       if (current_row[0] == NULL) {
-                               break;/* row that was never initialized */
-                       }
+               DBG_INF_FMT("before: real_usage=%lu  usage=%lu", 
zend_memory_usage(TRUE TSRMLS_CC), zend_memory_usage(FALSE TSRMLS_CC));
+               for (row = set->row_count - 1; row >= 0; row--) {
+                       zval **current_row = set->data + row * field_count;
+                       MYSQLND_MEMORY_POOL_CHUNK *current_buffer = 
set->row_buffers[row];
+                       int col;
+
+                       for (col = field_count - 1; col >= 0; --col) {
+                               zend_bool copy_ctor_called;
+                               if (current_row == NULL || current_row[0] == 
NULL) {
+                                       break;/* row that was never initialized 
*/
+                               }
                        mysqlnd_palloc_zval_ptr_dtor(&(current_row[col]), 
result->type, &copy_ctor_called TSRMLS_CC);
 #if MYSQLND_DEBUG_MEMORY
-                       DBG_INF_FMT("Copy_ctor_called=%d", copy_ctor_called);
+                               DBG_INF_FMT("Copy_ctor_called=%d", 
copy_ctor_called);
 #endif
-                       MYSQLND_INC_GLOBAL_STATISTIC(copy_ctor_called? 
STAT_COPY_ON_WRITE_PERFORMED:
+                               MYSQLND_INC_GLOBAL_STATISTIC(copy_ctor_called? 
STAT_COPY_ON_WRITE_PERFORMED:
                                                                                
                                   STAT_COPY_ON_WRITE_SAVED);
-               }
+                       }
 #if MYSQLND_DEBUG_MEMORY
-               DBG_INF("Freeing current_row & current_buffer");
+                       DBG_INF("Freeing current_row & current_buffer");
 #endif
-               current_buffer->free_chunk(current_buffer TSRMLS_CC);
-       }
-       DBG_INF("Freeing data & row_buffer");
-       if (set->data) {
+                       current_buffer->free_chunk(current_buffer TSRMLS_CC);
+               }
+
                mnd_pefree(set->data, set->persistent);
                set->data = NULL;
        }
+
        if (set->row_buffers) {
                mnd_pefree(set->row_buffers, set->persistent);
                set->row_buffers        = NULL;

Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c
===================================================================
--- php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c      2010-05-21 13:06:52 UTC 
(rev 299578)
+++ php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c      2010-05-21 13:37:18 UTC 
(rev 299579)
@@ -186,34 +186,37 @@
        DBG_ENTER("mysqlnd_res::free_buffered_data");
        DBG_INF_FMT("Freeing "MYSQLND_LLU_SPEC" row(s)", set->row_count);

-       DBG_INF_FMT("before: real_usage=%lu  usage=%lu", zend_memory_usage(TRUE 
TSRMLS_CC), zend_memory_usage(FALSE TSRMLS_CC));
-       for (row = set->row_count - 1; row >= 0; row--) {
-               zval **current_row = set->data + row * field_count;
-               MYSQLND_MEMORY_POOL_CHUNK *current_buffer = 
set->row_buffers[row];
-               int col;
+       DBG_INF("Freeing data & row_buffer");
+       if (set->data) {

-               for (col = field_count - 1; col >= 0; --col) {
-                       zend_bool copy_ctor_called;
-                       if (current_row[0] == NULL) {
-                               break;/* row that was never initialized */
-                       }
+               DBG_INF_FMT("before: real_usage=%lu  usage=%lu", 
zend_memory_usage(TRUE TSRMLS_CC), zend_memory_usage(FALSE TSRMLS_CC));
+               for (row = set->row_count - 1; row >= 0; row--) {
+                       zval **current_row = set->data + row * field_count;
+                       MYSQLND_MEMORY_POOL_CHUNK *current_buffer = 
set->row_buffers[row];
+                       int col;
+
+                       for (col = field_count - 1; col >= 0; --col) {
+                               zend_bool copy_ctor_called;
+                               if (current_row == NULL || current_row[0] == 
NULL) {
+                                       break;/* row that was never initialized 
*/
+                               }
                        mysqlnd_palloc_zval_ptr_dtor(&(current_row[col]), 
result->type, &copy_ctor_called TSRMLS_CC);
 #if MYSQLND_DEBUG_MEMORY
-                       DBG_INF_FMT("Copy_ctor_called=%d", copy_ctor_called);
+                               DBG_INF_FMT("Copy_ctor_called=%d", 
copy_ctor_called);
 #endif
-                       MYSQLND_INC_GLOBAL_STATISTIC(copy_ctor_called? 
STAT_COPY_ON_WRITE_PERFORMED:
+                               MYSQLND_INC_GLOBAL_STATISTIC(copy_ctor_called? 
STAT_COPY_ON_WRITE_PERFORMED:
                                                                                
                                   STAT_COPY_ON_WRITE_SAVED);
-               }
+                       }
 #if MYSQLND_DEBUG_MEMORY
-               DBG_INF("Freeing current_row & current_buffer");
+                       DBG_INF("Freeing current_row & current_buffer");
 #endif
-               current_buffer->free_chunk(current_buffer TSRMLS_CC);
-       }
-       DBG_INF("Freeing data & row_buffer");
-       if (set->data) {
+                       current_buffer->free_chunk(current_buffer TSRMLS_CC);
+               }
+
                mnd_pefree(set->data, set->persistent);
                set->data = NULL;
        }
+
        if (set->row_buffers) {
                mnd_pefree(set->row_buffers, set->persistent);
                set->row_buffers        = NULL;

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to