andrey                                   Mon, 03 May 2010 19:32:07 +0000

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

Log:
Handle OOM in mysqlnd_res::store_result_fetch_data

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-03 
19:31:50 UTC (rev 298928)
+++ php/php-src/branches/PHP_5_3/ext/mysqlnd/mysqlnd_result.c   2010-05-03 
19:32:07 UTC (rev 298929)
@@ -1080,8 +1080,18 @@
                                conn->thread_id, binary_protocol, to_cache);

        result->stored_data     = set = mnd_pecalloc(1, 
sizeof(MYSQLND_RES_BUFFERED), to_cache);
+       if (!set) {
+               SET_OOM_ERROR(conn->error_info);
+               ret = FAIL;
+               goto end;
+       }
        if (free_rows) {
                set->row_buffers = mnd_pemalloc(free_rows * 
sizeof(MYSQLND_MEMORY_POOL_CHUNK *), to_cache);
+               if (!set->row_buffers) {
+                       SET_OOM_ERROR(conn->error_info);
+                       ret = FAIL;
+                       goto end;
+               }
        }
        set->persistent = to_cache;
        set->references = 1;
@@ -1091,6 +1101,11 @@

        /* non-persistent */
        row_packet = conn->protocol->m.get_row_packet(conn->protocol, FALSE 
TSRMLS_CC);
+       if (!row_packet) {
+               SET_OOM_ERROR(conn->error_info);
+               ret = FAIL;
+               goto end;
+       }
        row_packet->result_set_memory_pool = result->result_set_memory_pool;
        row_packet->field_count = meta->field_count;
        row_packet->binary_protocol = binary_protocol;
@@ -1103,10 +1118,17 @@
        while (FAIL != (ret = PACKET_READ(row_packet, conn)) && 
!row_packet->eof) {
                if (!free_rows) {
                        uint64_t total_allocated_rows = free_rows = next_extend 
= next_extend * 11 / 10; /* extend with 10% */
+                       MYSQLND_MEMORY_POOL_CHUNK ** new_row_buffers;
                        total_allocated_rows += set->row_count;
-                       set->row_buffers = mnd_perealloc(set->row_buffers,
-                                                                               
         total_allocated_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *),
-                                                                               
         set->persistent);
+                       new_row_buffers = mnd_perealloc(set->row_buffers,
+                                                                               
        total_allocated_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *),
+                                                                               
        set->persistent);
+                       if (!new_row_buffers) {
+                               SET_OOM_ERROR(conn->error_info);
+                               ret = FAIL;
+                               goto end;
+                       }
+                       set->row_buffers = new_row_buffers;
                }
                free_rows--;
                set->row_buffers[set->row_count] = row_packet->row_buffer;
@@ -1128,6 +1150,11 @@
        if (set->row_count) {
                /* if pecalloc is used valgrind barks gcc version 4.3.1 
20080507 (prerelease) [gcc-4_3-branch revision 135036] (SUSE Linux) */
                set->data = mnd_pemalloc(set->row_count * meta->field_count * 
sizeof(zval *), to_cache);
+               if (!set->data) {
+                       SET_OOM_ERROR(conn->error_info);
+                       ret = FAIL;
+                       goto end;
+               }
                memset(set->data, 0, set->row_count * meta->field_count * 
sizeof(zval *));
        }

@@ -1163,6 +1190,7 @@
                /* libmysql's documentation says it should be so for SELECT 
statements */
                conn->upsert_status.affected_rows = set->row_count;
        }
+end:
        PACKET_FREE(row_packet);

        DBG_INF_FMT("ret=%s row_count=%u warnings=%u server_status=%u", ret == 
PASS? "PASS":"FAIL",

Modified: php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c
===================================================================
--- php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c      2010-05-03 19:31:50 UTC 
(rev 298928)
+++ php/php-src/trunk/ext/mysqlnd/mysqlnd_result.c      2010-05-03 19:32:07 UTC 
(rev 298929)
@@ -1080,8 +1080,18 @@
                                conn->thread_id, binary_protocol, to_cache);

        result->stored_data     = set = mnd_pecalloc(1, 
sizeof(MYSQLND_RES_BUFFERED), to_cache);
+       if (!set) {
+               SET_OOM_ERROR(conn->error_info);
+               ret = FAIL;
+               goto end;
+       }
        if (free_rows) {
                set->row_buffers = mnd_pemalloc(free_rows * 
sizeof(MYSQLND_MEMORY_POOL_CHUNK *), to_cache);
+               if (!set->row_buffers) {
+                       SET_OOM_ERROR(conn->error_info);
+                       ret = FAIL;
+                       goto end;
+               }
        }
        set->persistent = to_cache;
        set->references = 1;
@@ -1091,6 +1101,11 @@

        /* non-persistent */
        row_packet = conn->protocol->m.get_row_packet(conn->protocol, FALSE 
TSRMLS_CC);
+       if (!row_packet) {
+               SET_OOM_ERROR(conn->error_info);
+               ret = FAIL;
+               goto end;
+       }
        row_packet->result_set_memory_pool = result->result_set_memory_pool;
        row_packet->field_count = meta->field_count;
        row_packet->binary_protocol = binary_protocol;
@@ -1103,10 +1118,17 @@
        while (FAIL != (ret = PACKET_READ(row_packet, conn)) && 
!row_packet->eof) {
                if (!free_rows) {
                        uint64_t total_allocated_rows = free_rows = next_extend 
= next_extend * 11 / 10; /* extend with 10% */
+                       MYSQLND_MEMORY_POOL_CHUNK ** new_row_buffers;
                        total_allocated_rows += set->row_count;
-                       set->row_buffers = mnd_perealloc(set->row_buffers,
-                                                                               
         total_allocated_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *),
-                                                                               
         set->persistent);
+                       new_row_buffers = mnd_perealloc(set->row_buffers,
+                                                                               
        total_allocated_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *),
+                                                                               
        set->persistent);
+                       if (!new_row_buffers) {
+                               SET_OOM_ERROR(conn->error_info);
+                               ret = FAIL;
+                               goto end;
+                       }
+                       set->row_buffers = new_row_buffers;
                }
                free_rows--;
                set->row_buffers[set->row_count] = row_packet->row_buffer;
@@ -1128,6 +1150,11 @@
        if (set->row_count) {
                /* if pecalloc is used valgrind barks gcc version 4.3.1 
20080507 (prerelease) [gcc-4_3-branch revision 135036] (SUSE Linux) */
                set->data = mnd_pemalloc(set->row_count * meta->field_count * 
sizeof(zval *), to_cache);
+               if (!set->data) {
+                       SET_OOM_ERROR(conn->error_info);
+                       ret = FAIL;
+                       goto end;
+               }
                memset(set->data, 0, set->row_count * meta->field_count * 
sizeof(zval *));
        }

@@ -1163,6 +1190,7 @@
                /* libmysql's documentation says it should be so for SELECT 
statements */
                conn->upsert_status.affected_rows = set->row_count;
        }
+end:
        PACKET_FREE(row_packet);

        DBG_INF_FMT("ret=%s row_count=%u warnings=%u server_status=%u", ret == 
PASS? "PASS":"FAIL",

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

Reply via email to