diff options
author | Andrey Hristov <andrey@php.net> | 2010-05-27 12:05:02 +0000 |
---|---|---|
committer | Andrey Hristov <andrey@php.net> | 2010-05-27 12:05:02 +0000 |
commit | ae9ac28ec229de056cc3387c84695c4a22ccf43e (patch) | |
tree | 24a8d2b3451626154b6b6c10c0f1bb26828ae948 | |
parent | 95d4f2ac66059c97172ebd2ed8f08fbaa0c6e390 (diff) | |
download | php-git-ae9ac28ec229de056cc3387c84695c4a22ccf43e.tar.gz |
Fix possible crashes, in case of OOM, due to half-baken
objects.
-rw-r--r-- | ext/mysqlnd/mysqlnd_result.c | 4 | ||||
-rw-r--r-- | 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 */ |