]> granicus.if.org Git - php/commitdiff
Avoid array duplication and in-place modification
authorDmitry Stogov <dmitry@zend.com>
Tue, 16 Jan 2018 23:25:36 +0000 (02:25 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 16 Jan 2018 23:25:36 +0000 (02:25 +0300)
ext/intl/msgformat/msgformat_format.c
ext/intl/msgformat/msgformat_helpers.cpp

index bfc9dbe3ac25afad2266521b101270ad0bdfbe6d..f42199164371c72afb9dea7bd16e904bb87749be 100644 (file)
@@ -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) {
index a8b207ff73ee99ce8a284e105792eef4561826c5..5f39b34090f9190ec52e53ef1e7142fe475d4811 100644 (file)
@@ -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;