diff options
Diffstat (limited to 'ext/intl/msgformat/msgformat_helpers.cpp')
-rw-r--r-- | ext/intl/msgformat/msgformat_helpers.cpp | 161 |
1 files changed, 78 insertions, 83 deletions
diff --git a/ext/intl/msgformat/msgformat_helpers.cpp b/ext/intl/msgformat/msgformat_helpers.cpp index c4456d54f3..46ebe25a17 100644 --- a/ext/intl/msgformat/msgformat_helpers.cpp +++ b/ext/intl/msgformat/msgformat_helpers.cpp @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -83,6 +83,10 @@ U_CFUNC int32_t umsg_format_arg_count(UMessageFormat *fmt) return fmt_count; } +static void arg_types_dtor(zval *el) { + efree(Z_PTR_P(el)); +} + static HashTable *umsg_get_numeric_types(MessageFormatter_object *mfo, intl_error& err TSRMLS_DC) { @@ -104,12 +108,11 @@ static HashTable *umsg_get_numeric_types(MessageFormatter_object *mfo, /* Hash table will store Formattable::Type objects directly, * so no need for destructor */ ALLOC_HASHTABLE(ret); - zend_hash_init(ret, parts_count, NULL, NULL, 0); + zend_hash_init(ret, parts_count, NULL, arg_types_dtor, 0); for (int i = 0; i < parts_count; i++) { const Formattable::Type t = types[i]; - if (zend_hash_index_update(ret, (ulong)i, (void*)&t, sizeof(t), NULL) - == FAILURE) { + if (zend_hash_index_update_mem(ret, (zend_ulong)i, (void*)&t, sizeof(t)) == NULL) { intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR, "Write to argument types hash table failed", 0 TSRMLS_CC); break; @@ -152,7 +155,7 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo, /* Hash table will store Formattable::Type objects directly, * so no need for destructor */ ALLOC_HASHTABLE(ret); - zend_hash_init(ret, 32, NULL, NULL, 0); + zend_hash_init(ret, 32, NULL, arg_types_dtor, 0); parts_count = mp.countParts(); @@ -180,12 +183,11 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo, if (name_part.getType() == UMSGPAT_PART_TYPE_ARG_NAME) { UnicodeString argName = mp.getSubstring(name_part); - if (zend_hash_find(ret, (char*)argName.getBuffer(), argName.length(), - (void**)&storedType) == FAILURE) { + if ((storedType = (Formattable::Type*)zend_hash_str_find_ptr(ret, (char*)argName.getBuffer(), argName.length())) == NULL) { /* not found already; create new entry in HT */ Formattable::Type bogusType = Formattable::kObject; - if (zend_hash_update(ret, (char*)argName.getBuffer(), argName.length(), - (void*)&bogusType, sizeof(bogusType), (void**)&storedType) == FAILURE) { + if ((storedType = (Formattable::Type*)zend_hash_str_update_mem(ret, (char*)argName.getBuffer(), argName.length(), + (void*)&bogusType, sizeof(bogusType))) == NULL) { intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR, "Write to argument types hash table failed", 0 TSRMLS_CC); continue; @@ -198,17 +200,18 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo, "Found part with negative number", 0 TSRMLS_CC); continue; } - if (zend_hash_index_find(ret, (ulong)argNumber, (void**)&storedType) - == FAILURE) { + if ((storedType = (Formattable::Type*)zend_hash_index_find_ptr(ret, (zend_ulong)argNumber)) == NULL) { /* not found already; create new entry in HT */ Formattable::Type bogusType = Formattable::kObject; - if (zend_hash_index_update(ret, (ulong)argNumber, (void*)&bogusType, - sizeof(bogusType), (void**)&storedType) == FAILURE) { + if ((storedType = (Formattable::Type*)zend_hash_index_update_mem(ret, (zend_ulong)argNumber, (void*)&bogusType, sizeof(bogusType))) == NULL) { intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR, "Write to argument types hash table failed", 0 TSRMLS_CC); continue; } } + } else { + intl_errors_set(&err, U_INVALID_FORMAT_ERROR, "Invalid part type encountered", 0 TSRMLS_CC); + continue; } UMessagePatternArgType argType = p.getArgType(); @@ -341,10 +344,9 @@ static void umsg_set_timezone(MessageFormatter_object *mfo, } if (used_tz == NULL) { - zval nullzv = zval_used_for_init, - *zvptr = &nullzv; - used_tz = timezone_process_timezone_argument(&zvptr, &err, - "msgfmt_format" TSRMLS_CC); + zval nullzv, *zvptr = &nullzv; + ZVAL_NULL(zvptr); + used_tz = timezone_process_timezone_argument(zvptr, &err, "msgfmt_format" TSRMLS_CC); if (used_tz == NULL) { continue; } @@ -382,32 +384,24 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, farg_names.resize(arg_count); int argNum = 0; - HashPosition pos; - zval **elem; + zval *elem; // Key related variables - int key_type; - char *str_index; - uint str_len; - ulong num_index; - - for (zend_hash_internal_pointer_reset_ex(args, &pos); - U_SUCCESS(err.code) && - (key_type = zend_hash_get_current_key_ex( - args, &str_index, &str_len, &num_index, 0, &pos), - zend_hash_get_current_data_ex(args, (void **)&elem, &pos) - ) == SUCCESS; - zend_hash_move_forward_ex(args, &pos), argNum++) - { + zend_string *str_index; + zend_ulong num_index; + + ZEND_HASH_FOREACH_KEY_VAL(args, num_index, str_index, elem) { Formattable& formattable = fargs[argNum]; UnicodeString& key = farg_names[argNum]; Formattable::Type argType = Formattable::kObject, //unknown *storedArgType = NULL; - + if (!U_SUCCESS(err.code)) { + break; + } /* Process key and retrieve type */ - if (key_type == HASH_KEY_IS_LONG) { + if (str_index == NULL) { /* includes case where index < 0 because it's exposed as unsigned */ - if (num_index > (ulong)INT32_MAX) { + if (num_index > (zend_ulong)INT32_MAX) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found negative or too large array key", 0 TSRMLS_CC); continue; @@ -417,21 +411,20 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, int32_t len = u_sprintf(temp, "%u", (uint32_t)num_index); key.append(temp, len); - zend_hash_index_find(types, (ulong)num_index, (void**)&storedArgType); + storedArgType = (Formattable::Type*)zend_hash_index_find_ptr(types, (zend_ulong)num_index); } else { //string; assumed to be in UTF-8 - intl_stringFromChar(key, str_index, str_len-1, &err.code); + intl_stringFromChar(key, str_index->val, str_index->len, &err.code); if (U_FAILURE(err.code)) { char *message; spprintf(&message, 0, - "Invalid UTF-8 data in argument key: '%s'", str_index); + "Invalid UTF-8 data in argument key: '%s'", str_index->val); intl_errors_set(&err, err.code, message, 1 TSRMLS_CC); efree(message); continue; } - zend_hash_find(types, (char*)key.getBuffer(), key.length(), - (void**)&storedArgType); + storedArgType = (Formattable::Type*)zend_hash_str_find_ptr(types, (char*)key.getBuffer(), key.length()); } if (storedArgType != NULL) { @@ -454,12 +447,12 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, UnicodeString *text = new UnicodeString(); intl_stringFromChar(*text, - Z_STRVAL_PP(elem), Z_STRLEN_PP(elem), &err.code); + Z_STRVAL_P(elem), Z_STRLEN_P(elem), &err.code); if (U_FAILURE(err.code)) { char *message; spprintf(&message, 0, "Invalid UTF-8 data in string argument: " - "'%s'", Z_STRVAL_PP(elem)); + "'%s'", Z_STRVAL_P(elem)); intl_errors_set(&err, err.code, message, 1 TSRMLS_CC); efree(message); delete text; @@ -471,16 +464,16 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, case Formattable::kDouble: { double d; - if (Z_TYPE_PP(elem) == IS_DOUBLE) { - d = Z_DVAL_PP(elem); - } else if (Z_TYPE_PP(elem) == IS_LONG) { - d = (double)Z_LVAL_PP(elem); + if (Z_TYPE_P(elem) == IS_DOUBLE) { + d = Z_DVAL_P(elem); + } else if (Z_TYPE_P(elem) == IS_LONG) { + d = (double)Z_LVAL_P(elem); } else { SEPARATE_ZVAL_IF_NOT_REF(elem); - convert_scalar_to_number(*elem TSRMLS_CC); - d = (Z_TYPE_PP(elem) == IS_DOUBLE) - ? Z_DVAL_PP(elem) - : (double)Z_LVAL_PP(elem); + convert_scalar_to_number(elem TSRMLS_CC); + d = (Z_TYPE_P(elem) == IS_DOUBLE) + ? Z_DVAL_P(elem) + : (double)Z_LVAL_P(elem); } formattable.setDouble(d); break; @@ -489,27 +482,27 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, { int32_t tInt32 = 0; retry_klong: - if (Z_TYPE_PP(elem) == IS_DOUBLE) { - if (Z_DVAL_PP(elem) > (double)INT32_MAX || - Z_DVAL_PP(elem) < (double)INT32_MIN) { + if (Z_TYPE_P(elem) == IS_DOUBLE) { + if (Z_DVAL_P(elem) > (double)INT32_MAX || + Z_DVAL_P(elem) < (double)INT32_MIN) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found PHP float with absolute value too large for " "32 bit integer argument", 0 TSRMLS_CC); } else { - tInt32 = (int32_t)Z_DVAL_PP(elem); + tInt32 = (int32_t)Z_DVAL_P(elem); } - } else if (Z_TYPE_PP(elem) == IS_LONG) { - if (Z_LVAL_PP(elem) > INT32_MAX || - Z_LVAL_PP(elem) < INT32_MIN) { + } else if (Z_TYPE_P(elem) == IS_LONG) { + if (Z_LVAL_P(elem) > INT32_MAX || + Z_LVAL_P(elem) < INT32_MIN) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found PHP integer with absolute value too large " "for 32 bit integer argument", 0 TSRMLS_CC); } else { - tInt32 = (int32_t)Z_LVAL_PP(elem); + tInt32 = (int32_t)Z_LVAL_P(elem); } } else { SEPARATE_ZVAL_IF_NOT_REF(elem); - convert_scalar_to_number(*elem TSRMLS_CC); + convert_scalar_to_number(elem TSRMLS_CC); goto retry_klong; } formattable.setLong(tInt32); @@ -519,21 +512,21 @@ retry_klong: { int64_t tInt64 = 0; retry_kint64: - if (Z_TYPE_PP(elem) == IS_DOUBLE) { - if (Z_DVAL_PP(elem) > (double)U_INT64_MAX || - Z_DVAL_PP(elem) < (double)U_INT64_MIN) { + if (Z_TYPE_P(elem) == IS_DOUBLE) { + if (Z_DVAL_P(elem) > (double)U_INT64_MAX || + Z_DVAL_P(elem) < (double)U_INT64_MIN) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found PHP float with absolute value too large for " "64 bit integer argument", 0 TSRMLS_CC); } else { - tInt64 = (int64_t)Z_DVAL_PP(elem); + tInt64 = (int64_t)Z_DVAL_P(elem); } - } else if (Z_TYPE_PP(elem) == IS_LONG) { + } else if (Z_TYPE_P(elem) == IS_LONG) { /* assume long is not wider than 64 bits */ - tInt64 = (int64_t)Z_LVAL_PP(elem); + tInt64 = (int64_t)Z_LVAL_P(elem); } else { SEPARATE_ZVAL_IF_NOT_REF(elem); - convert_scalar_to_number(*elem TSRMLS_CC); + convert_scalar_to_number(elem TSRMLS_CC); goto retry_kint64; } formattable.setInt64(tInt64); @@ -541,7 +534,7 @@ retry_kint64: } case Formattable::kDate: { - double dd = intl_zval_to_millis(*elem, &err, "msgfmt_format" TSRMLS_CC); + double dd = intl_zval_to_millis(elem, &err, "msgfmt_format" TSRMLS_CC); if (U_FAILURE(err.code)) { char *message, *key_char; int key_len; @@ -568,15 +561,16 @@ retry_kint64: /* We couldn't find any information about the argument in the pattern, this * means it's an extra argument. So convert it to a number if it's a number or * bool or null and to a string if it's anything else except arrays . */ - switch (Z_TYPE_PP(elem)) { + switch (Z_TYPE_P(elem)) { case IS_DOUBLE: - formattable.setDouble(Z_DVAL_PP(elem)); + formattable.setDouble(Z_DVAL_P(elem)); break; - case IS_BOOL: + case IS_TRUE: + case IS_FALSE: convert_to_long_ex(elem); /* Intentional fallthrough */ case IS_LONG: - formattable.setInt64((int64_t)Z_LVAL_PP(elem)); + formattable.setInt64((int64_t)Z_LVAL_P(elem)); break; case IS_NULL: formattable.setInt64((int64_t)0); @@ -602,7 +596,8 @@ retry_kint64: } } } - } // visiting each argument + argNum++; + } ZEND_HASH_FOREACH_END(); // visiting each argument if (U_FAILURE(err.code)) { return; @@ -633,7 +628,7 @@ retry_kint64: #define cleanup_zvals() for(int j=i;j>=0;j--) { zval_ptr_dtor((*args)+i); } -U_CFUNC void umsg_parse_helper(UMessageFormat *fmt, int *count, zval ***args, UChar *source, int source_len, UErrorCode *status) +U_CFUNC void umsg_parse_helper(UMessageFormat *fmt, int *count, zval **args, UChar *source, int source_len, UErrorCode *status) { UnicodeString srcString(source, source_len); Formattable *fargs = ((const MessageFormat*)fmt)->parse(srcString, *count, *status); @@ -642,7 +637,7 @@ U_CFUNC void umsg_parse_helper(UMessageFormat *fmt, int *count, zval ***args, UC return; } - *args = (zval **)safe_emalloc(*count, sizeof(zval *), 0); + *args = (zval *)safe_emalloc(*count, sizeof(zval), 0); // assign formattables to varargs for(int32_t i = 0; i < *count; i++) { @@ -652,28 +647,26 @@ U_CFUNC void umsg_parse_helper(UMessageFormat *fmt, int *count, zval ***args, UC char *stmp; int stmp_len; - ALLOC_INIT_ZVAL((*args)[i]); - switch(fargs[i].getType()) { case Formattable::kDate: aDate = ((double)fargs[i].getDate())/U_MILLIS_PER_SECOND; - ZVAL_DOUBLE((*args)[i], aDate); + ZVAL_DOUBLE(&(*args)[i], aDate); break; case Formattable::kDouble: - ZVAL_DOUBLE((*args)[i], (double)fargs[i].getDouble()); + ZVAL_DOUBLE(&(*args)[i], (double)fargs[i].getDouble()); break; case Formattable::kLong: - ZVAL_LONG((*args)[i], fargs[i].getLong()); + ZVAL_LONG(&(*args)[i], fargs[i].getLong()); break; case Formattable::kInt64: aInt64 = fargs[i].getInt64(); - if(aInt64 > LONG_MAX || aInt64 < -LONG_MAX) { - ZVAL_DOUBLE((*args)[i], (double)aInt64); + if(aInt64 > ZEND_LONG_MAX || aInt64 < -ZEND_LONG_MAX) { + ZVAL_DOUBLE(&(*args)[i], (double)aInt64); } else { - ZVAL_LONG((*args)[i], (long)aInt64); + ZVAL_LONG(&(*args)[i], (zend_long)aInt64); } break; @@ -684,7 +677,9 @@ U_CFUNC void umsg_parse_helper(UMessageFormat *fmt, int *count, zval ***args, UC cleanup_zvals(); return; } - ZVAL_STRINGL((*args)[i], stmp, stmp_len, 0); + ZVAL_STRINGL(&(*args)[i], stmp, stmp_len); + //??? + efree(stmp); break; case Formattable::kObject: |