summaryrefslogtreecommitdiff
path: root/ext/intl
diff options
context:
space:
mode:
authorPhilip Hofstetter <phofstetter@sensational.ch>2020-10-09 11:55:33 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-10-12 16:42:41 +0200
commit74cf2eb83fc664cbad2d619fd2662bee770d8f81 (patch)
treedcdb7249cafa83980040846b550b415c7b3c36b1 /ext/intl
parent216d6a024aeee19a7bd532d0ddaad2a4aff7e097 (diff)
downloadphp-git-74cf2eb83fc664cbad2d619fd2662bee770d8f81.tar.gz
intl: report more information about message pattern parse errors
The message patterns can be pretty complex, so reporting a generic U_PARSE_ERROR without any additional information makes it needlessly hard to fix erroneous patterns. This commit makes use of the additional UParseError* parameter to umsg_open to retrieve more details about the parse error to report that to the user via intl_get_error_message() Additional improve error reporting from the IntlMessage constructor. Previously, all possible failures when calling IntlMessage::__construct() would be masked away with a generic "Constructor failed" message. This would include invalid patterns. This commit makes sure that the underlying error that caused the constructor failure is reported as part of the IntlException error message. Closes GH-6325.
Diffstat (limited to 'ext/intl')
-rw-r--r--ext/intl/msgformat/msgformat.c21
-rw-r--r--ext/intl/msgformat/msgformat_format.c18
-rw-r--r--ext/intl/tests/msgfmt_fail2.phpt16
3 files changed, 44 insertions, 11 deletions
diff --git a/ext/intl/msgformat/msgformat.c b/ext/intl/msgformat/msgformat.c
index 2439b5855a..edf69dc52c 100644
--- a/ext/intl/msgformat/msgformat.c
+++ b/ext/intl/msgformat/msgformat.c
@@ -36,6 +36,7 @@ static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_constructor)
int spattern_len = 0;
zval* object;
MessageFormatter_object* mfo;
+ UParseError parse_error;
int zpp_flags = is_constructor ? ZEND_PARSE_PARAMS_THROW : 0;
intl_error_reset( NULL );
@@ -79,12 +80,26 @@ static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_constructor)
(mfo)->mf_data.orig_format_len = pattern_len;
/* Create an ICU message formatter. */
- MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, locale, NULL, &INTL_DATA_ERROR_CODE(mfo));
+ MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, locale, &parse_error, &INTL_DATA_ERROR_CODE(mfo));
if(spattern) {
efree(spattern);
}
+ if (INTL_DATA_ERROR_CODE( mfo ) == U_PATTERN_SYNTAX_ERROR) {
+ char *msg = NULL;
+ smart_str parse_error_str;
+ parse_error_str = intl_parse_error_to_string( &parse_error );
+ spprintf( &msg, 0, "pattern syntax error (%s)", parse_error_str.s? ZSTR_VAL(parse_error_str.s) : "unknown parser error" );
+ smart_str_free( &parse_error_str );
+
+ intl_error_set_code( NULL, INTL_DATA_ERROR_CODE( mfo ) );
+ intl_errors_set_custom_msg( INTL_DATA_ERROR_P( mfo ), msg, 1 );
+
+ efree( msg );
+ return FAILURE;
+ }
+
INTL_CTOR_CHECK_STATUS(mfo, "msgfmt_create: message formatter creation failed");
return SUCCESS;
}
@@ -116,7 +131,9 @@ PHP_METHOD( MessageFormatter, __construct )
return_value = ZEND_THIS;
if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1) == FAILURE) {
if (!EG(exception)) {
- zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0);
+ zend_string *err = intl_error_get_message(NULL);
+ zend_throw_exception(IntlException_ce_ptr, ZSTR_VAL(err), intl_error_get_code(NULL));
+ zend_string_release_ex(err, 0);
}
}
zend_restore_error_handling(&error_handling);
diff --git a/ext/intl/msgformat/msgformat_format.c b/ext/intl/msgformat/msgformat_format.c
index a11c167a4b..a0a410cf0d 100644
--- a/ext/intl/msgformat/msgformat_format.c
+++ b/ext/intl/msgformat/msgformat_format.c
@@ -94,6 +94,7 @@ PHP_FUNCTION( msgfmt_format_message )
size_t slocale_len = 0;
MessageFormatter_object mf;
MessageFormatter_object *mfo = &mf;
+ UParseError parse_error;
/* Parse parameters. */
if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "ssa",
@@ -136,10 +137,25 @@ PHP_FUNCTION( msgfmt_format_message )
#endif
/* Create an ICU message formatter. */
- MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, slocale, NULL, &INTL_DATA_ERROR_CODE(mfo));
+ MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, slocale, &parse_error, &INTL_DATA_ERROR_CODE(mfo));
if(spattern && spattern_len) {
efree(spattern);
}
+
+ if (INTL_DATA_ERROR_CODE( mfo ) == U_PATTERN_SYNTAX_ERROR) {
+ char *msg = NULL;
+ smart_str parse_error_str;
+ parse_error_str = intl_parse_error_to_string( &parse_error );
+ spprintf( &msg, 0, "pattern syntax error (%s)", parse_error_str.s? ZSTR_VAL(parse_error_str.s) : "unknown parser error" );
+ smart_str_free( &parse_error_str );
+
+ intl_error_set_code( NULL, INTL_DATA_ERROR_CODE( mfo ) );
+ intl_errors_set_custom_msg( INTL_DATA_ERROR_P( mfo ), msg, 1 );
+
+ efree( msg );
+ RETURN_FALSE;
+ }
+
INTL_METHOD_CHECK_STATUS(mfo, "Creating message formatter failed");
msgfmt_do_format(mfo, args, return_value);
diff --git a/ext/intl/tests/msgfmt_fail2.phpt b/ext/intl/tests/msgfmt_fail2.phpt
index 0016de4bb7..0d4a52a64f 100644
--- a/ext/intl/tests/msgfmt_fail2.phpt
+++ b/ext/intl/tests/msgfmt_fail2.phpt
@@ -96,12 +96,12 @@ Warning: msgfmt_create() expects exactly 2 parameters, 1 given in %s on line %d
Warning: MessageFormatter::create() expects exactly 2 parameters, 1 given in %s on line %d
'msgfmt_create: unable to parse input parameters: U_ILLEGAL_ARGUMENT_ERROR'
-IntlException: Constructor failed in %smsgfmt_fail2.php on line %d
+IntlException: msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR in %s on line %d
'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR'
'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR'
'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR'
-IntlException: Constructor failed in %smsgfmt_fail2.php on line %d
+IntlException: msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR in %s on line %d
'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR'
'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR'
'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR'
@@ -115,17 +115,17 @@ Warning: MessageFormatter::create() expects parameter 1 to be string, array give
Warning: msgfmt_create() expects parameter 1 to be string, array given in %s on line %d
'msgfmt_create: unable to parse input parameters: U_ILLEGAL_ARGUMENT_ERROR'
-IntlException: Constructor failed in %smsgfmt_fail2.php on line %d
-'msgfmt_create: message formatter creation failed: U_PATTERN_SYNTAX_ERROR'
-'msgfmt_create: message formatter creation failed: U_PATTERN_SYNTAX_ERROR'
-'msgfmt_create: message formatter creation failed: U_PATTERN_SYNTAX_ERROR'
+IntlException: pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR in %s on line %d
+'pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR'
+'pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR'
+'pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR'
-IntlException: Constructor failed in %smsgfmt_fail2.php on line %d
+IntlException: msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES in %s on line %d
'msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES'
'msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES'
'msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES'
-IntlException: Constructor failed in %smsgfmt_fail2.php on line %d
+IntlException: msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND in %s on line %d
'msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND'
'msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND'
'msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND'