From: Nikita Popov Date: Sat, 18 Jul 2015 18:04:22 +0000 (+0200) Subject: Correctly handle zend_hash_sort failure X-Git-Tag: php-7.0.0beta2~6^2~44 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=df031961adee32532ce9a05aaf98606519f6ccd3;p=php Correctly handle zend_hash_sort failure This can't actually happen right now, but should it become possible we won't be leaking everything anymore. --- diff --git a/ext/standard/array.c b/ext/standard/array.c index 96bee6a99c..8fbc3b35f0 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -621,6 +621,7 @@ PHP_FUNCTION(usort) { zval *array; zend_refcounted *arr; + zend_bool retval; PHP_ARRAY_CMP_FUNC_VARS; PHP_ARRAY_CMP_FUNC_BACKUP(); @@ -639,22 +640,20 @@ PHP_FUNCTION(usort) Z_ADDREF_P(array); arr = Z_COUNTED_P(array); - if (zend_hash_sort(Z_ARRVAL_P(array), php_array_user_compare, 1) == FAILURE) { - RETVAL_FALSE; - } else { - if (arr != Z_COUNTED_P(array)) { - php_error_docref(NULL, E_WARNING, "Array was modified by the user comparison function"); - if (--GC_REFCOUNT(arr) <= 0) { - _zval_dtor_func(arr ZEND_FILE_LINE_CC); - } - RETVAL_FALSE; - } else { - Z_DELREF_P(array); - RETVAL_TRUE; + retval = zend_hash_sort(Z_ARRVAL_P(array), php_array_user_compare, 1) != FAILURE; + + if (arr != Z_COUNTED_P(array)) { + php_error_docref(NULL, E_WARNING, "Array was modified by the user comparison function"); + if (--GC_REFCOUNT(arr) <= 0) { + _zval_dtor_func(arr ZEND_FILE_LINE_CC); } + retval = 0; + } else { + Z_DELREF_P(array); } PHP_ARRAY_CMP_FUNC_RESTORE(); + RETURN_BOOL(retval); } /* }}} */ @@ -664,6 +663,7 @@ PHP_FUNCTION(uasort) { zval *array; zend_refcounted *arr; + zend_bool retval; PHP_ARRAY_CMP_FUNC_VARS; PHP_ARRAY_CMP_FUNC_BACKUP(); @@ -682,22 +682,20 @@ PHP_FUNCTION(uasort) Z_ADDREF_P(array); arr = Z_COUNTED_P(array); - if (zend_hash_sort(Z_ARRVAL_P(array), php_array_user_compare, 0) == FAILURE) { - RETVAL_FALSE; - } else { - if (arr != Z_COUNTED_P(array)) { - php_error_docref(NULL, E_WARNING, "Array was modified by the user comparison function"); - if (--GC_REFCOUNT(arr) <= 0) { - _zval_dtor_func(arr ZEND_FILE_LINE_CC); - } - RETVAL_FALSE; - } else { - Z_DELREF_P(array); - RETVAL_TRUE; + retval = zend_hash_sort(Z_ARRVAL_P(array), php_array_user_compare, 0) != FAILURE; + + if (arr != Z_COUNTED_P(array)) { + php_error_docref(NULL, E_WARNING, "Array was modified by the user comparison function"); + if (--GC_REFCOUNT(arr) <= 0) { + _zval_dtor_func(arr ZEND_FILE_LINE_CC); } + retval = 0; + } else { + Z_DELREF_P(array); } PHP_ARRAY_CMP_FUNC_RESTORE(); + RETURN_BOOL(retval); } /* }}} */ @@ -750,6 +748,7 @@ PHP_FUNCTION(uksort) { zval *array; zend_refcounted *arr; + zend_bool retval; PHP_ARRAY_CMP_FUNC_VARS; PHP_ARRAY_CMP_FUNC_BACKUP(); @@ -768,22 +767,19 @@ PHP_FUNCTION(uksort) Z_ADDREF_P(array); arr = Z_COUNTED_P(array); - if (zend_hash_sort(Z_ARRVAL_P(array), php_array_user_key_compare, 0) == FAILURE) { - RETVAL_FALSE; - } else { - if (arr != Z_COUNTED_P(array)) { - php_error_docref(NULL, E_WARNING, "Array was modified by the user comparison function"); - if (--GC_REFCOUNT(arr) <= 0) { - _zval_dtor_func(arr ZEND_FILE_LINE_CC); - } - RETVAL_FALSE; - } else { - Z_DELREF_P(array); - RETVAL_TRUE; + retval = zend_hash_sort(Z_ARRVAL_P(array), php_array_user_key_compare, 0) != FAILURE; + if (arr != Z_COUNTED_P(array)) { + php_error_docref(NULL, E_WARNING, "Array was modified by the user comparison function"); + if (--GC_REFCOUNT(arr) <= 0) { + _zval_dtor_func(arr ZEND_FILE_LINE_CC); } + retval = 0; + } else { + Z_DELREF_P(array); } PHP_ARRAY_CMP_FUNC_RESTORE(); + RETURN_BOOL(retval); } /* }}} */