From ae9ac28ec229de056cc3387c84695c4a22ccf43e Mon Sep 17 00:00:00 2001 From: Andrey Hristov Date: Thu, 27 May 2010 12:05:02 +0000 Subject: [PATCH] Fix possible crashes, in case of OOM, due to half-baken objects. --- ext/mysqlnd/mysqlnd_result.c | 4 ++++ ext/mysqlnd/mysqlnd_result_meta.c | 33 +++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index 5590375763..8cf8abb1e8 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -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 */ diff --git a/ext/mysqlnd/mysqlnd_result_meta.c b/ext/mysqlnd/mysqlnd_result_meta.c index 9f4220bb25..377c1e03f2 100644 --- a/ext/mysqlnd/mysqlnd_result_meta.c +++ b/ext/mysqlnd/mysqlnd_result_meta.c @@ -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 */ -- 2.50.0