@@ -50,6 +50,25 @@ static const size_t DEF_SORT_KEYS_INDX_BUF_INCREMENT = 1048576;
5050
5151static const size_t DEF_UTF16_BUF_SIZE = 1024 ;
5252
53+ static void collator_copy_error (intl_error *dst, const intl_error *src)
54+ {
55+ intl_error_reset (dst);
56+ dst->code = src->code ;
57+ if (src->custom_error_message ) {
58+ dst->custom_error_message = zend_string_copy (src->custom_error_message );
59+ }
60+ }
61+
62+ static void collator_report_sort_error (Collator_object *co, const intl_error *sort_error)
63+ {
64+ collator_copy_error (COLLATOR_ERROR_P (co), sort_error);
65+ collator_copy_error (&INTL_G (g_error), sort_error);
66+
67+ if (INTL_G (use_exceptions) && INTL_G (g_error).custom_error_message ) {
68+ zend_throw_error_exception (IntlException_ce_ptr, INTL_G (g_error).custom_error_message , 0 , 0 );
69+ }
70+ }
71+
5372/* {{{ collator_regular_compare_function */
5473static int collator_regular_compare_function (zval *result, zval *op1, zval *op2)
5574{
@@ -236,6 +255,11 @@ static int collator_compare_func(Bucket *f, Bucket *s)
236255 zval *first = &f->val ;
237256 zval *second = &s->val ;
238257
258+ ZEND_ASSERT (INTL_G (current_collator_error) != nullptr );
259+ if ( EG (exception) || U_FAILURE ( INTL_ERROR_CODE (*INTL_G (current_collator_error)) ) ) {
260+ return 0 ;
261+ }
262+
239263 if ( INTL_G (compare_func)( &result, first, second) == FAILURE )
240264 return 0 ;
241265
@@ -300,6 +324,8 @@ static void collator_sort_internal( int renumber, INTERNAL_FUNCTION_PARAMETERS )
300324{
301325 UCollator* saved_collator;
302326 intl_error* saved_collator_error;
327+ intl_error sort_error;
328+ collator_compare_func_t saved_compare_func;
303329 zval* array = nullptr ;
304330 HashTable* hash = nullptr ;
305331 zend_array* sorted = nullptr ;
@@ -322,9 +348,6 @@ static void collator_sort_internal( int renumber, INTERNAL_FUNCTION_PARAMETERS )
322348 RETURN_THROWS ();
323349 }
324350
325- /* Set 'compare function' according to sort flags. */
326- INTL_G (compare_func) = collator_get_compare_function ( sort_flags );
327-
328351 hash = Z_ARRVAL_P ( array );
329352
330353 /* Copy array, so the in-place modifications will not be visible to the callback function */
@@ -337,23 +360,38 @@ static void collator_sort_internal( int renumber, INTERNAL_FUNCTION_PARAMETERS )
337360 }
338361 COLLATOR_CHECK_STATUS ( co, " Error converting hash from UTF-8 to UTF-16" );
339362
363+ intl_error_init ( &sort_error );
364+
340365 /* Save specified collator in the request-global (?) variable. */
341366 saved_collator = INTL_G ( current_collator );
342367 saved_collator_error = INTL_G ( current_collator_error );
368+ saved_compare_func = INTL_G ( compare_func );
343369 INTL_G ( current_collator ) = co->ucoll ;
344- INTL_G ( current_collator_error ) = COLLATOR_ERROR_P ( co );
370+ INTL_G ( current_collator_error ) = &sort_error;
371+ INTL_G ( compare_func ) = collator_get_compare_function ( sort_flags );
345372
346373 /* Sort specified array. */
347374 zend_hash_sort ( sorted, collator_compare_func, renumber );
348375
349376 /* Restore saved collator. */
350377 INTL_G ( current_collator ) = saved_collator;
351378 INTL_G ( current_collator_error ) = saved_collator_error;
379+ INTL_G ( compare_func ) = saved_compare_func;
352380
353- if ( U_FAILURE ( COLLATOR_ERROR_CODE ( co ) ) ) {
381+ if ( EG (exception) ) {
382+ zend_array_destroy ( sorted );
383+ intl_error_reset ( &sort_error );
384+ RETURN_THROWS ();
385+ }
386+
387+ if ( U_FAILURE ( INTL_ERROR_CODE (sort_error) ) ) {
354388 zend_array_destroy ( sorted );
389+ collator_report_sort_error (co, &sort_error);
390+ intl_error_reset ( &sort_error );
391+ RETURN_FALSE ;
355392 }
356- COLLATOR_CHECK_STATUS ( co, " Error comparing array values" );
393+
394+ intl_error_reset ( &sort_error );
357395
358396 /* Convert strings in the specified array back to UTF-8. */
359397 collator_convert_hash_from_utf16_to_utf8 ( sorted, COLLATOR_ERROR_CODE_P ( co ) );
0 commit comments