Skip to content

Commit ca5667b

Browse files
authored
ext/intl: prevent creation of invalid UConverter instance (#19396)
1 parent abe75ca commit ca5667b

File tree

4 files changed

+41
-13
lines changed

4 files changed

+41
-13
lines changed

ext/intl/converter/converter.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "../intl_error.h"
2525
#include "../intl_common.h"
2626
#include "converter_arginfo.h"
27+
#include "php_intl.h"
2728

2829
typedef struct _php_converter_object {
2930
UConverter *src, *dest;
@@ -370,7 +371,10 @@ static bool php_converter_set_encoding(php_converter_object *objval,
370371
/* Should never happen */
371372
actual_encoding = "(unknown)";
372373
}
373-
php_error_docref(NULL, E_WARNING, "Ambiguous encoding specified, using %s", actual_encoding);
374+
char *msg;
375+
spprintf(&msg, 0, "Ambiguous encoding specified, using %s", actual_encoding);
376+
intl_error_set(NULL, error, msg);
377+
efree(msg);
374378
} else if (U_FAILURE(error)) {
375379
if (objval) {
376380
THROW_UFAILURE(objval, error);
@@ -530,10 +534,23 @@ PHP_METHOD(UConverter, __construct) {
530534
Z_PARAM_STRING_OR_NULL(src, src_len)
531535
ZEND_PARSE_PARAMETERS_END();
532536

533-
php_converter_set_encoding(objval, &(objval->src), src, src_len );
534-
php_converter_set_encoding(objval, &(objval->dest), dest, dest_len);
537+
const bool old_use_exception = INTL_G(use_exceptions);
538+
const zend_long old_error_level = INTL_G(error_level);
539+
INTL_G(use_exceptions) = true;
540+
INTL_G(error_level) = 0;
541+
if (UNEXPECTED(!php_converter_set_encoding(objval, &(objval->src), src, src_len))) {
542+
ZEND_ASSERT(EG(exception));
543+
goto cleanup;
544+
}
545+
if (UNEXPECTED(!php_converter_set_encoding(objval, &(objval->dest), dest, dest_len))) {
546+
ZEND_ASSERT(EG(exception));
547+
goto cleanup;
548+
}
535549
php_converter_resolve_callback(&objval->to_cache, Z_OBJ_P(ZEND_THIS), ZEND_STRL("toUCallback"));
536550
php_converter_resolve_callback(&objval->from_cache, Z_OBJ_P(ZEND_THIS), ZEND_STRL("fromUCallback"));
551+
cleanup:
552+
INTL_G(use_exceptions) = old_use_exception;
553+
INTL_G(error_level) = old_error_level;
537554
}
538555
/* }}} */
539556

ext/intl/tests/bug75317.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
Bug #75317 (UConverter::setDestinationEncoding changes source instead of destinatination)
2+
Bug #75317 (UConverter::setDestinationEncoding changes source instead of destination)
33
--EXTENSIONS--
44
intl
55
--FILE--
Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
--TEST--
22
Basic UConverter::convert() usage
3-
--INI--
4-
intl.error_level = E_WARNING
53
--EXTENSIONS--
64
intl
75
--FILE--
86
<?php
9-
$c = new UConverter('utf-8', "\x80");
10-
var_dump($c);
11-
?>
12-
--EXPECTF--
13-
Warning: UConverter::__construct(): returned error 4: U_FILE_ACCESS_ERROR in %s on line %d
14-
object(UConverter)#%d (0) {
7+
try {
8+
$c = new UConverter("\x80", 'utf-8');
9+
var_dump($c);
10+
} catch (Throwable $e) {
11+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
12+
}
13+
try {
14+
$c = new UConverter('utf-8', "\x80");
15+
var_dump($c);
16+
} catch (Throwable $e) {
17+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
1518
}
19+
?>
20+
--EXPECT--
21+
IntlException: UConverter::__construct(): returned error 4: U_FILE_ACCESS_ERROR
22+
IntlException: UConverter::__construct(): returned error 4: U_FILE_ACCESS_ERROR

ext/intl/tests/uconverter_bug66873.phpt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@ Bug #66873 - crash in UConverter with invalid encoding
44
intl
55
--FILE--
66
<?php
7+
try {
78
$o = new UConverter(1, 1);
89
$o->toUCallback(1, 1, 1, $b);
910
var_dump($o->getErrorCode());
11+
} catch (Throwable $e) {
12+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
13+
}
1014
?>
1115
--EXPECT--
12-
int(27)
16+
IntlException: UConverter::__construct(): returned error 4: U_FILE_ACCESS_ERROR

0 commit comments

Comments
 (0)