]> granicus.if.org Git - php/commitdiff
Fix possible crashes, in case of OOM, due to half-baken
authorAndrey Hristov <andrey@php.net>
Thu, 27 May 2010 12:05:02 +0000 (12:05 +0000)
committerAndrey Hristov <andrey@php.net>
Thu, 27 May 2010 12:05:02 +0000 (12:05 +0000)
objects.

ext/mysqlnd/mysqlnd_result.c
ext/mysqlnd/mysqlnd_result_meta.c

index 5590375763dc01958cf4821d3cf6af079d41411c..8cf8abb1e8498a21ef106fa605d79a4505025e6f 100644 (file)
@@ -326,6 +326,10 @@ MYSQLND_METHOD(mysqlnd_res, read_result_metadata)(MYSQLND_RES * result, MYSQLND
        }
 
        result->meta = result->m.result_meta_init(result->field_count, result->persistent TSRMLS_CC);
+       if (!result->meta) {
+               SET_OOM_ERROR(conn->error_info);
+               DBG_RETURN(FAIL);
+       }
 
        /* 1. Read all fields metadata */
 
index 9f4220bb25ce221d52ec7625e868c869ef34ff87..377c1e03f21b2b749b4f3503056d69cdeb67ed58 100644 (file)
@@ -475,17 +475,30 @@ mysqlnd_result_meta_init(unsigned int field_count, zend_bool persistent TSRMLS_D
        MYSQLND_RES_METADATA *ret = mnd_pecalloc(1, alloc_size, persistent);
        DBG_ENTER("mysqlnd_result_meta_init");
        DBG_INF_FMT("persistent=%d", persistent);
-
-       ret->persistent = persistent;
-       ret->field_count = field_count;
-       /* +1 is to have empty marker at the end */
-       ret->fields = mnd_pecalloc(field_count + 1, sizeof(MYSQLND_FIELD), ret->persistent);
-       ret->zend_hash_keys = mnd_pecalloc(field_count, sizeof(struct mysqlnd_field_hash_key), ret->persistent);
-
-       ret->m = & mysqlnd_mysqlnd_res_meta_methods;
-       DBG_INF_FMT("meta=%p", ret);
-       DBG_RETURN(ret);
+       
+       do {
+               if (!ret) {
+                       break;
+               }
+               ret->m = & mysqlnd_mysqlnd_res_meta_methods;
+
+               ret->persistent = persistent;
+               ret->field_count = field_count;
+               /* +1 is to have empty marker at the end */
+               ret->fields = mnd_pecalloc(field_count + 1, sizeof(MYSQLND_FIELD), ret->persistent);
+               ret->zend_hash_keys = mnd_pecalloc(field_count, sizeof(struct mysqlnd_field_hash_key), ret->persistent);
+               if (!ret->fields || !ret->zend_hash_keys) {
+                       break;
+               }
+               DBG_INF_FMT("meta=%p", ret);
+               DBG_RETURN(ret);
+       } while (0);
+       if (ret) {
+               ret->m->free_metadata(ret TSRMLS_CC);
+       }
+       DBG_RETURN(NULL);
 }
+/* }}} */
 
 
 /* {{{ mysqlnd_res_meta_get_methods */