Skip to content

Commit 524c5f3

Browse files
committed
better logic
1 parent a5dd051 commit 524c5f3

7 files changed

Lines changed: 65 additions & 46 deletions

NEWS

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ PHP NEWS
2323

2424
- Intl:
2525
. Fixed Collator::sort(), collator_sort(), Collator::asort(), and
26-
collator_asort() to report string conversion errors through the intl error
27-
handler instead of emitting a warning and continuing with an empty string.
28-
(Weilin Du)
26+
collator_asort() to report UTF-8/UTF-16 conversion errors through the intl
27+
error handler instead of emitting a warning and continuing with an empty
28+
string. (Weilin Du)
2929
. Fixed grammatical issues in Normalizer invalid form and IntlCalendar time
3030
zone offset error messages. (Weilin Du)
3131

UPGRADING

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,10 @@ PHP 8.6 UPGRADE NOTES
7777
when the offset argument is not of type int instead of silently converting
7878
the value.
7979
. Collator::sort(), collator_sort(), Collator::asort(), and
80-
collator_asort() now report string conversion failures during comparison
81-
through the intl error mechanism and return false. With
82-
intl.use_exceptions enabled, these failures throw IntlException.
83-
Previously, these paths emitted a warning and compared the value as an
84-
empty string.
80+
collator_asort() now report UTF-8/UTF-16 conversion failures during
81+
comparison through the intl error mechanism and return false. With
82+
intl.use_exceptions enabled, these failures throw IntlException. Previously,
83+
these paths emitted a warning and compared the value as an empty string.
8584

8685
- PCNTL:
8786
. pcntl_alarm() now raises a ValueError if the seconds argument is

ext/intl/collator/collator_convert.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ static void collator_set_conversion_error(UErrorCode status, const char *message
4545
}
4646

4747
ZEND_ASSERT(INTL_G(current_collator_error) != nullptr);
48-
intl_error_set(INTL_G(current_collator_error), status, message);
48+
intl_error *err = INTL_G(current_collator_error);
49+
intl_error_reset(err);
50+
err->code = status;
51+
err->custom_error_message = zend_string_init(
52+
message, strlen(message), false);
4953
}
5054

5155
/* {{{ collator_convert_hash_item_from_utf8_to_utf16 */
@@ -223,19 +227,19 @@ U_CFUNC zval* collator_convert_object_to_string( zval* obj, zval *rv )
223227
/* cast_object failed => bail out. */
224228
zval_ptr_dtor( zstr );
225229
ZVAL_NULL( zstr );
226-
if( !EG(exception) ) {
227-
zend_throw_error(NULL, "Object of class %s could not be converted to string", ZSTR_VAL(Z_OBJCE_P(obj)->name));
230+
if( EG(exception) ) {
231+
return nullptr;
228232
}
229-
return nullptr;
233+
COLLATOR_CONVERT_RETURN_FAILED( obj );
230234
}
231235

232236
/* Object wasn't successfully converted => bail out. */
233237
if( zstr == nullptr )
234238
{
235-
if( !EG(exception) ) {
236-
zend_throw_error(NULL, "Object of class %s could not be converted to string", ZSTR_VAL(Z_OBJCE_P(obj)->name));
239+
if( EG(exception) ) {
240+
return nullptr;
237241
}
238-
return nullptr;
242+
COLLATOR_CONVERT_RETURN_FAILED( obj );
239243
}
240244

241245
/* Convert the string to UTF-16. */

ext/intl/collator/collator_sort.cpp

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,14 @@ static const size_t DEF_SORT_KEYS_INDX_BUF_INCREMENT = 1048576;
5050

5151
static 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-
6253
static void collator_report_sort_error(Collator_object *co, const intl_error *sort_error)
6354
{
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);
55+
if (sort_error->custom_error_message) {
56+
intl_errors_set(
57+
COLLATOR_ERROR_P(co), sort_error->code,
58+
ZSTR_VAL(sort_error->custom_error_message));
59+
} else {
60+
intl_errors_set_code(COLLATOR_ERROR_P(co), sort_error->code);
6961
}
7062
}
7163

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Collator::sort() reports comparison conversion errors through intl.error_level
3+
--EXTENSIONS--
4+
intl
5+
--FILE--
6+
<?php
7+
class BadErrorLevelString {
8+
public function __toString(): string {
9+
return "\xFF";
10+
}
11+
}
12+
13+
ini_set("intl.error_level", E_WARNING);
14+
ini_set("intl.use_exceptions", 0);
15+
16+
$coll = new Collator('en_US');
17+
$array = ['b', new BadErrorLevelString(), 'a'];
18+
19+
var_dump($coll->sort($array, Collator::SORT_STRING));
20+
var_dump($coll->getErrorCode() === U_INVALID_CHAR_FOUND);
21+
echo $coll->getErrorMessage(), PHP_EOL;
22+
?>
23+
--EXPECTF--
24+
Deprecated: ini_set(): Using a value different than 0 for intl.error_level is deprecated, as the intl.error_level INI setting is deprecated. Instead the intl.use_exceptions INI setting should be enabled to throw exceptions on errors or intl_get_error_code()/intl_get_error_message() should be used to manually deal with errors in %s on line %d
25+
26+
Warning: Collator::sort(): Error converting string from UTF-8 to UTF-16 in %s on line %d
27+
bool(false)
28+
bool(true)
29+
Collator::sort(): Error converting string from UTF-8 to UTF-16: U_INVALID_CHAR_FOUND
Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,36 @@
11
--TEST--
2-
Collator::sort() conversion failure must survive a re-entrant Collator call
2+
Collator::sort() conversion failure must survive a re-entrant Collator call in __toString()
33
--EXTENSIONS--
44
intl
55
--FILE--
66
<?php
7-
class Bad {
8-
public function __toString(): string {
9-
return "\xFF";
10-
}
11-
}
12-
13-
class Toucher {
7+
class BadAfterReentry {
148
public static Collator $coll;
9+
public static bool $called = false;
1510

1611
public function __toString(): string {
17-
if (self::$coll->getErrorCode() !== U_ZERO_ERROR) {
18-
self::$coll->getLocale(Locale::VALID_LOCALE);
19-
}
20-
return 'z';
12+
self::$called = true;
13+
self::$coll->getLocale(Locale::VALID_LOCALE);
14+
return "\xFF";
2115
}
2216
}
2317

2418
$coll = new Collator('en_US');
25-
Toucher::$coll = $coll;
19+
BadAfterReentry::$coll = $coll;
2620

27-
$array = ['a', new Bad(), 'b', new Toucher()];
21+
$array = ['a', new BadAfterReentry(), 'b'];
2822

2923
var_dump($coll->sort($array, Collator::SORT_STRING));
24+
var_dump(BadAfterReentry::$called);
3025
var_dump($coll->getErrorCode() === U_INVALID_CHAR_FOUND);
3126
echo $coll->getErrorMessage(), PHP_EOL;
32-
var_dump($array[0], $array[1] instanceof Bad, $array[2], $array[3] instanceof Toucher);
27+
var_dump($array[0], $array[1] instanceof BadAfterReentry, $array[2]);
3328
?>
3429
--EXPECT--
3530
bool(false)
3631
bool(true)
32+
bool(true)
3733
Collator::sort(): Error converting string from UTF-8 to UTF-16: U_INVALID_CHAR_FOUND
3834
string(1) "a"
3935
bool(true)
4036
string(1) "b"
41-
bool(true)

ext/intl/tests/collator_sort_tostring_throws.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ foreach ([Collator::SORT_REGULAR, Collator::SORT_STRING] as $flag) {
3131

3232
$array = ['b', new NoToString(), 'a'];
3333
try {
34-
var_dump($coll->sort($array, Collator::SORT_REGULAR));
34+
var_dump($coll->sort($array, Collator::SORT_STRING));
3535
} catch (Throwable $e) {
3636
echo get_class($e), ': ', $e->getMessage(), PHP_EOL;
3737
}

0 commit comments

Comments
 (0)