diff --git a/NEWS b/NEWS index edca1748f63..0859ac0f333 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,9 @@ PHP NEWS . Added zend_call_stack_get implementation for OpenBSD. (David Carlier) . Fixed oss-fuzz #60411 (Fix double-compilation of arrow-functions). (ilutov) +- Intl: + . Fix memory leak in MessageFormatter::format() on failure. (Girgias) + - LDAP: . Deprecate calling ldap_connect() with separate hostname and port. (heiglandreas) diff --git a/ext/intl/msgformat/msgformat_format.c b/ext/intl/msgformat/msgformat_format.c index 1a28b557dc1..098c6a2b922 100644 --- a/ext/intl/msgformat/msgformat_format.c +++ b/ext/intl/msgformat/msgformat_format.c @@ -125,21 +125,27 @@ PHP_FUNCTION( msgfmt_format_message ) 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 ); + /* Cannot use INTL_METHOD_CHECK_STATUS() as we need to free the message object formatter */ + if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) { + 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 ); + intl_error_set_code( NULL, INTL_DATA_ERROR_CODE( mfo ) ); + intl_errors_set_custom_msg( INTL_DATA_ERROR_P( mfo ), msg, 1 ); - efree( msg ); + efree( msg ); + } else { + intl_errors_set_custom_msg( INTL_DATA_ERROR_P(mfo), "Creating message formatter failed", 0 ); + } + /* Reset custom error message as this is a static method that has no object */ + intl_errors_reset(INTL_DATA_ERROR_P(mfo)); + umsg_close(MSG_FORMAT_OBJECT(mfo)); RETURN_FALSE; - } - - INTL_METHOD_CHECK_STATUS(mfo, "Creating message formatter failed"); + } msgfmt_do_format(mfo, args, return_value); diff --git a/ext/intl/tests/gh11658.phpt b/ext/intl/tests/gh11658.phpt new file mode 100644 index 00000000000..b29786255ca --- /dev/null +++ b/ext/intl/tests/gh11658.phpt @@ -0,0 +1,15 @@ +--TEST-- +GitHub #11658 MessageFormatter::format() leaks memory +--EXTENSIONS-- +intl +--FILE-- + +--EXPECTF-- +Warning: MessageFormatter::formatMessage(): pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}") in %s on line %d +bool(false)