]> granicus.if.org Git - php/commitdiff
Handle OOM when resizing blocks during data fetch
authorAndrey Hristov <andrey@php.net>
Mon, 3 May 2010 14:16:04 +0000 (14:16 +0000)
committerAndrey Hristov <andrey@php.net>
Mon, 3 May 2010 14:16:04 +0000 (14:16 +0000)
ext/mysqlnd/mysqlnd_block_alloc.c
ext/mysqlnd/mysqlnd_structs.h
ext/mysqlnd/mysqlnd_wireprotocol.c

index 41c3af6f06b7649648109b20f2bd62ba98f1cf6c..498d4b390b230a790c401453fd9e99ab4e5a1c1c 100644 (file)
@@ -53,7 +53,7 @@ mysqlnd_mempool_free_chunk(MYSQLND_MEMORY_POOL_CHUNK * chunk, zend_bool cache_it
 
 
 /* {{{ mysqlnd_mempool_resize_chunk */
-static void
+static enum_func_status
 mysqlnd_mempool_resize_chunk(MYSQLND_MEMORY_POOL_CHUNK * chunk, unsigned int size TSRMLS_DC)
 {
        DBG_ENTER("mysqlnd_mempool_resize_chunk");
@@ -68,6 +68,9 @@ mysqlnd_mempool_resize_chunk(MYSQLND_MEMORY_POOL_CHUNK * chunk, unsigned int siz
                        if ((chunk->size + pool->free_size) < size) {
                                zend_uchar *new_ptr;
                                new_ptr = mnd_malloc(size);
+                               if (!new_ptr) {
+                                       DBG_RETURN(FAIL);
+                               }
                                memcpy(new_ptr, chunk->ptr, chunk->size);
                                chunk->ptr = new_ptr;
                                pool->free_size += chunk->size;
@@ -85,6 +88,9 @@ mysqlnd_mempool_resize_chunk(MYSQLND_MEMORY_POOL_CHUNK * chunk, unsigned int siz
                        } else {
                                zend_uchar *new_ptr;
                                new_ptr = mnd_malloc(size);
+                               if (!new_ptr) {
+                                       DBG_RETURN(FAIL);
+                               }
                                memcpy(new_ptr, chunk->ptr, chunk->size);
                                chunk->ptr = new_ptr;
                                chunk->size = size;
@@ -95,7 +101,7 @@ mysqlnd_mempool_resize_chunk(MYSQLND_MEMORY_POOL_CHUNK * chunk, unsigned int siz
        } else {
                chunk->ptr = mnd_realloc(chunk->ptr, size);
        }
-       DBG_VOID_RETURN;
+       DBG_RETURN(PASS);
 }
 /* }}} */
 
index 401c3b045493c69da799761358607917c1bbcf40..a74d7d6d2b118de4520805a9fe75861b52073b9c 100644 (file)
@@ -48,7 +48,7 @@ struct st_mysqlnd_memory_pool_chunk
        MYSQLND_MEMORY_POOL     *pool;
        zend_uchar                      *ptr;
        unsigned int            size;
-       void                            (*resize_chunk)(MYSQLND_MEMORY_POOL_CHUNK * chunk, unsigned int size TSRMLS_DC);
+       enum_func_status        (*resize_chunk)(MYSQLND_MEMORY_POOL_CHUNK * chunk, unsigned int size TSRMLS_DC);
        void                            (*free_chunk)(MYSQLND_MEMORY_POOL_CHUNK * chunk, zend_bool cache_it TSRMLS_DC);
        zend_bool                       from_pool;
 };
index 3eb9159227b54283eefa82dcae5dfe4c0352e19a..6e0adf56208e86ba120b82f3b5c31d0d6b7b4166 100644 (file)
@@ -1149,7 +1149,11 @@ php_mysqlnd_read_row_ex(MYSQLND * conn, MYSQLND_MEMORY_POOL * result_set_memory_
                          We need a trailing \0 for the last string, in case of text-mode,
                          to be able to implement read-only variables.
                        */
-                       (*buffer)->resize_chunk((*buffer), *data_size + 1 TSRMLS_CC);
+                       if (FAIL == (*buffer)->resize_chunk((*buffer), *data_size + 1 TSRMLS_CC)) {
+                               SET_OOM_ERROR(conn->error_info);
+                               ret = FAIL;
+                               break;
+                       }
                        /* The position could have changed, recalculate */
                        p = (*buffer)->ptr + (*data_size - header.size);
                }