diff --git a/Zend/tests/new_oom.inc b/Zend/tests/new_oom.inc new file mode 100644 index 0000000000000..fa62764310a94 --- /dev/null +++ b/Zend/tests/new_oom.inc @@ -0,0 +1,15 @@ +newInstanceWithoutConstructor(); + } +} catch (Throwable) { +} diff --git a/Zend/tests/new_oom.phpt b/Zend/tests/new_oom.phpt new file mode 100644 index 0000000000000..1e9b0593e6bea --- /dev/null +++ b/Zend/tests/new_oom.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test OOM on new of each class +--SKIPIF-- + +--FILE-- +&1"); + if ($output && preg_match('(^\nFatal error: Allowed memory size of [0-9]+ bytes exhausted[^\r\n]* \(tried to allocate [0-9]+ bytes\) in [^\r\n]+ on line [0-9]+$)', $output) !== 1) { + echo "Class $class failed\n"; + echo $output, "\n"; + } +} + +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 833afa0d0f579..f042c24b44936 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -1414,6 +1414,12 @@ static void dbh_free(pdo_dbh_t *dbh, bool free_persistent) static void pdo_dbh_free_storage(zend_object *std) { pdo_dbh_t *dbh = php_pdo_dbh_fetch_inner(std); + + /* dbh might be null if we OOMed during object initialization. */ + if (!dbh) { + return; + } + if (dbh->driver_data && dbh->methods && dbh->methods->rollback && pdo_is_in_transaction(dbh)) { dbh->methods->rollback(dbh); dbh->in_txn = false; diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 74dc7731fd152..74dc3b8c99fa1 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -295,12 +295,13 @@ static void spl_dllist_object_free_storage(zend_object *object) /* {{{ */ zend_object_std_dtor(&intern->std); - while (intern->llist->count > 0) { - spl_ptr_llist_pop(intern->llist, &tmp); - zval_ptr_dtor(&tmp); + if (intern->llist) { + while (intern->llist->count > 0) { + spl_ptr_llist_pop(intern->llist, &tmp); + zval_ptr_dtor(&tmp); + } + spl_ptr_llist_destroy(intern->llist); } - - spl_ptr_llist_destroy(intern->llist); SPL_LLIST_CHECK_DELREF(intern->traverse_pointer); } /* }}} */ diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c index 4f242d3a3c394..5d61741425185 100644 --- a/ext/spl/spl_heap.c +++ b/ext/spl/spl_heap.c @@ -372,6 +372,11 @@ static spl_ptr_heap *spl_ptr_heap_clone(spl_ptr_heap *from) { /* {{{ */ /* }}} */ static void spl_ptr_heap_destroy(spl_ptr_heap *heap) { /* {{{ */ + /* Heap might be null if we OOMed during object initialization. */ + if (!heap) { + return; + } + int i; for (i = 0; i < heap->count; ++i) { diff --git a/ext/xsl/php_xsl.c b/ext/xsl/php_xsl.c index 82e782d18f9d1..5ecb7fd9b0b68 100644 --- a/ext/xsl/php_xsl.c +++ b/ext/xsl/php_xsl.c @@ -59,11 +59,15 @@ void xsl_objects_free_storage(zend_object *object) zend_object_std_dtor(&intern->std); - zend_hash_destroy(intern->parameter); - FREE_HASHTABLE(intern->parameter); + if (intern->parameter) { + zend_hash_destroy(intern->parameter); + FREE_HASHTABLE(intern->parameter); + } - zend_hash_destroy(intern->registered_phpfunctions); - FREE_HASHTABLE(intern->registered_phpfunctions); + if (intern->registered_phpfunctions) { + zend_hash_destroy(intern->registered_phpfunctions); + FREE_HASHTABLE(intern->registered_phpfunctions); + } if (intern->node_list) { zend_hash_destroy(intern->node_list);