]> granicus.if.org Git - php/commitdiff
Correctly handle zend_hash_sort failure
authorNikita Popov <nikic@php.net>
Sat, 18 Jul 2015 18:04:22 +0000 (20:04 +0200)
committerNikita Popov <nikic@php.net>
Sat, 18 Jul 2015 18:07:00 +0000 (20:07 +0200)
This can't actually happen right now, but should it become possible
we won't be leaking everything anymore.

ext/standard/array.c

index 96bee6a99c49025f5feef741e0927add4e1861d2..8fbc3b35f00a20c0cf318fd3b50dca87c47e1f0a 100644 (file)
@@ -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);
 }
 /* }}} */