From 0a2b2de99a7de9a308662eca07e6778b632cbfa9 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Mon, 10 Jul 2023 11:23:49 +0100 Subject: [PATCH] ext/intl: Fix memory leak in MessageFormatter::format() --- ext/intl/msgformat/msgformat_format.c | 34 ++++++++++++++++----------- ext/intl/tests/gh11658.phpt | 15 ++++++++++++ 2 files changed, 35 insertions(+), 14 deletions(-) create mode 100644 ext/intl/tests/gh11658.phpt diff --git a/ext/intl/msgformat/msgformat_format.c b/ext/intl/msgformat/msgformat_format.c index 1a28b557dc1ed..098c6a2b92286 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 ); - - intl_error_set_code( NULL, INTL_DATA_ERROR_CODE( mfo ) ); - intl_errors_set_custom_msg( INTL_DATA_ERROR_P( mfo ), msg, 1 ); - - efree( msg ); + /* 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 ); + + 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 0000000000000..b29786255cacb --- /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)