diff --git a/NEWS b/NEWS index 7b36fb246790..bee62cd8ac65 100644 --- a/NEWS +++ b/NEWS @@ -39,6 +39,8 @@ PHP NEWS for invalid display types. (Weilin Du) . Fixed Spoofchecker restriction-level APIs to only be exposed with ICU 53 and later. (Graham Campbell) + . Fixed Locale::lookup() and locale_lookup() to return NULL instead of the + fallback locale when a language tag cannot be canonicalized. (Weilin Du) - mysqli: . Fix stmt->query leak in mysqli_execute_query() validation errors. diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c index e7cc9d8364c9..b5d48257338a 100644 --- a/ext/intl/locale/locale_methods.c +++ b/ext/intl/locale/locale_methods.c @@ -1435,14 +1435,15 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, zend_argument_type_error(2, "must only contain string values"); LOOKUP_CLEAN_RETURN(NULL); } - cur_arr[cur_arr_len*2] = estrndup(Z_STRVAL_P(ele_value), Z_STRLEN_P(ele_value)); - result = strToMatch(Z_STRVAL_P(ele_value), cur_arr[cur_arr_len*2]); + i = cur_arr_len*2; + cur_arr[i] = estrndup(Z_STRVAL_P(ele_value), Z_STRLEN_P(ele_value)); + cur_arr_len++; + result = strToMatch(Z_STRVAL_P(ele_value), cur_arr[i]); if(result == 0) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize lang_tag", 0); LOOKUP_CLEAN_RETURN(NULL); } - cur_arr[cur_arr_len*2+1] = Z_STRVAL_P(ele_value); - cur_arr_len++ ; + cur_arr[i+1] = Z_STRVAL_P(ele_value); } ZEND_HASH_FOREACH_END(); /* end of for */ /* Canonicalize array elements */ @@ -1562,6 +1563,15 @@ PHP_FUNCTION(locale_lookup) } result_str = lookup_loc_range(loc_range, hash_arr, boolCanonical); + if (EG(exception)) { + RETURN_THROWS(); + } + if (U_FAILURE(intl_error_get_code(NULL))) { + if (result_str) { + zend_string_release_ex(result_str, 0); + } + RETURN_NULL(); + } if(result_str == NULL || ZSTR_VAL(result_str)[0] == '\0') { if( fallback_loc_str ) { result_str = zend_string_copy(fallback_loc_str); diff --git a/ext/intl/tests/locale_lookup_invalid_language_tag.phpt b/ext/intl/tests/locale_lookup_invalid_language_tag.phpt new file mode 100644 index 000000000000..6f7c7517f951 --- /dev/null +++ b/ext/intl/tests/locale_lookup_invalid_language_tag.phpt @@ -0,0 +1,35 @@ +--TEST-- +Locale::lookup() returns null for invalid language tags +--EXTENSIONS-- +intl +--FILE-- +getMessage(), PHP_EOL; +} + +try { + locale_lookup([''], 'de-DE', false, 'en-US'); +} catch (IntlException $e) { + echo $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +NULL +string(75) "lookup_loc_range: unable to canonicalize lang_tag: U_ILLEGAL_ARGUMENT_ERROR" +NULL +string(75) "lookup_loc_range: unable to canonicalize lang_tag: U_ILLEGAL_ARGUMENT_ERROR" +lookup_loc_range: unable to canonicalize lang_tag +lookup_loc_range: unable to canonicalize lang_tag