From ecd2624875af4b943f6817e0f63ee7d2c9192c5e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 17 Jan 2018 02:25:36 +0300 Subject: [PATCH] Avoid array duplication and in-place modification --- ext/intl/msgformat/msgformat_format.c | 11 +-------- ext/intl/msgformat/msgformat_helpers.cpp | 29 ++++++++++++------------ 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/ext/intl/msgformat/msgformat_format.c b/ext/intl/msgformat/msgformat_format.c index bfc9dbe3ac..f421991643 100644 --- a/ext/intl/msgformat/msgformat_format.c +++ b/ext/intl/msgformat/msgformat_format.c @@ -37,17 +37,8 @@ static void msgfmt_do_format(MessageFormatter_object *mfo, zval *args, zval *ret int count; UChar* formatted = NULL; int32_t formatted_len = 0; - HashTable *args_copy; - count = zend_hash_num_elements(Z_ARRVAL_P(args)); - - args_copy = zend_new_array(count); - zend_hash_copy(args_copy, Z_ARRVAL_P(args), (copy_ctor_func_t)zval_add_ref); - - umsg_format_helper(mfo, args_copy, &formatted, &formatted_len); - - zend_hash_destroy(args_copy); - efree(args_copy); + umsg_format_helper(mfo, Z_ARRVAL_P(args), &formatted, &formatted_len); if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) { if (formatted) { diff --git a/ext/intl/msgformat/msgformat_helpers.cpp b/ext/intl/msgformat/msgformat_helpers.cpp index a8b207ff73..5f39b34090 100644 --- a/ext/intl/msgformat/msgformat_helpers.cpp +++ b/ext/intl/msgformat/msgformat_helpers.cpp @@ -441,28 +441,31 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, switch (argType) { case Formattable::kString: { + zend_string *str, *tmp_str; + string_arg: /* This implicitly converts objects * Note that our vectors will leak if object conversion fails * and PHP ends up with a fatal error and calls longjmp * as a result of that. */ - convert_to_string_ex(elem); + str = zval_get_tmp_string(elem, &tmp_str); UnicodeString *text = new UnicodeString(); intl_stringFromChar(*text, - Z_STRVAL_P(elem), Z_STRLEN_P(elem), &err.code); + ZSTR_VAL(str), ZSTR_LEN(str), &err.code); if (U_FAILURE(err.code)) { char *message; spprintf(&message, 0, "Invalid UTF-8 data in string argument: " - "'%s'", Z_STRVAL_P(elem)); + "'%s'", ZSTR_VAL(str)); intl_errors_set(&err, err.code, message, 1); efree(message); delete text; continue; } formattable.adoptString(text); + zend_tmp_string_release(tmp_str); break; } case Formattable::kDouble: @@ -474,7 +477,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, case Formattable::kLong: { int32_t tInt32 = 0; -retry_klong: + if (Z_TYPE_P(elem) == IS_DOUBLE) { if (Z_DVAL_P(elem) > (double)INT32_MAX || Z_DVAL_P(elem) < (double)INT32_MIN) { @@ -494,9 +497,7 @@ retry_klong: tInt32 = (int32_t)Z_LVAL_P(elem); } } else { - SEPARATE_ZVAL_IF_NOT_REF(elem); - convert_scalar_to_number(elem); - goto retry_klong; + tInt32 = (int32_t)zval_get_long(elem); } formattable.setLong(tInt32); break; @@ -504,7 +505,7 @@ retry_klong: case Formattable::kInt64: { int64_t tInt64 = 0; -retry_kint64: + if (Z_TYPE_P(elem) == IS_DOUBLE) { if (Z_DVAL_P(elem) > (double)U_INT64_MAX || Z_DVAL_P(elem) < (double)U_INT64_MIN) { @@ -518,9 +519,7 @@ retry_kint64: /* assume long is not wider than 64 bits */ tInt64 = (int64_t)Z_LVAL_P(elem); } else { - SEPARATE_ZVAL_IF_NOT_REF(elem); - convert_scalar_to_number(elem); - goto retry_kint64; + tInt64 = (int64_t)zval_get_long(elem); } formattable.setInt64(tInt64); break; @@ -558,16 +557,16 @@ retry_kint64: case IS_DOUBLE: formattable.setDouble(Z_DVAL_P(elem)); break; - case IS_TRUE: - case IS_FALSE: - convert_to_long_ex(elem); - /* Intentional fallthrough */ case IS_LONG: formattable.setInt64((int64_t)Z_LVAL_P(elem)); break; case IS_NULL: + case IS_FALSE: formattable.setInt64((int64_t)0); break; + case IS_TRUE: + formattable.setInt64((int64_t)1); + break; case IS_STRING: case IS_OBJECT: goto string_arg; -- 2.40.0