|
|
|
@ -768,6 +768,7 @@ static int php_array_user_key_compare(const void *a, const void *b TSRMLS_DC) /* |
|
|
|
PHP_FUNCTION(uksort) |
|
|
|
{ |
|
|
|
zval *array; |
|
|
|
int refcount; |
|
|
|
PHP_ARRAY_CMP_FUNC_VARS; |
|
|
|
|
|
|
|
PHP_ARRAY_CMP_FUNC_BACKUP(); |
|
|
|
@ -777,13 +778,31 @@ PHP_FUNCTION(uksort) |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
/* Clear the is_ref flag, so the attemts to modify the array in user |
|
|
|
* comaprison function will create a copy of array and won't affect the |
|
|
|
* original array. The fact of modification is detected using refcount |
|
|
|
* comparison. The result of sorting in such case is undefined and the |
|
|
|
* function returns FALSE. |
|
|
|
*/ |
|
|
|
Z_UNSET_ISREF_P(array); |
|
|
|
refcount = Z_REFCOUNT_P(array); |
|
|
|
|
|
|
|
if (zend_hash_sort(Z_ARRVAL_P(array), zend_qsort, php_array_user_key_compare, 0 TSRMLS_CC) == FAILURE) { |
|
|
|
PHP_ARRAY_CMP_FUNC_RESTORE(); |
|
|
|
RETURN_FALSE; |
|
|
|
RETVAL_FALSE; |
|
|
|
} else { |
|
|
|
if (refcount > Z_REFCOUNT_P(array)) { |
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array was modified by the user comparison function"); |
|
|
|
RETVAL_FALSE; |
|
|
|
} else { |
|
|
|
RETVAL_TRUE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (Z_REFCOUNT_P(array) > 1) { |
|
|
|
Z_SET_ISREF_P(array); |
|
|
|
} |
|
|
|
|
|
|
|
PHP_ARRAY_CMP_FUNC_RESTORE(); |
|
|
|
RETURN_TRUE; |
|
|
|
} |
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|