Commit baad24b7346 for php

commit baad24b73461edcb430887eef03348a897b44ab8
Author: David Carlier <devnexen@gmail.com>
Date:   Thu Nov 12 19:17:16 2026 +0000

    ext/intl: Use C++ idioms in locale_methods.cpp

    First step in moving ext/intl from C-style code towards C++.

    Replace the uloc_* buffer/retry loops with helpers that preflight the
    call and return an exactly sized zend_string or icu::UnicodeString.
    Also use LocalUEnumerationPointer, icu::Locale::getDefault() and C++
    casts. locale_add_likely_subtags() and locale_minimize_subtags() keep
    their ULOC_FULLNAME_CAPACITY buffer: older ICU (e.g. 74) accepts
    overlong input there and would otherwise return it instead of failing.

    The uloc_* accessors are kept: icu::Locale normalises the ID and would
    change results for existing inputs. Further C++ replacements need a
    newer ICU than the 57.1 minimum: Locale::addLikelySubtags(),
    minimizeSubtags() and std::string getKeywordValue() (ICU 63),
    LocaleMatcher for acceptFromHttp (ICU 65).

    Close GH-24681

diff --git a/ext/intl/locale/locale_methods.cpp b/ext/intl/locale/locale_methods.cpp
index 121265b4862..e0729096298 100644
--- a/ext/intl/locale/locale_methods.cpp
+++ b/ext/intl/locale/locale_methods.cpp
@@ -28,7 +28,7 @@
 #include "php_intl.h"
 #include "locale.h"
 #include "locale_class.h"
-#include "intl_convert.h"
+#include "intl_convertcpp.h"
 #include "intl_data.h"

 #include <zend_API.h>
@@ -189,6 +189,45 @@ struct char_deleter {
 	}
 };

+template <typename F>
+static zend_string *locale_icu_string(F &&f, UErrorCode &status)
+{
+	int32_t len = f(nullptr, 0, &status);
+	if (status != U_BUFFER_OVERFLOW_ERROR) {
+		return U_FAILURE(status) ? nullptr : ZSTR_EMPTY_ALLOC();
+	}
+
+	status = U_ZERO_ERROR;
+	zend_string *str = zend_string_alloc(len, 0);
+	len = f(ZSTR_VAL(str), len + 1, &status);
+	if (U_FAILURE(status)) {
+		zend_string_efree(str);
+		return nullptr;
+	}
+	ZSTR_VAL(str)[len] = '\0';
+	ZSTR_LEN(str) = len;
+	return str;
+}
+
+template <typename F>
+static bool locale_icu_ustring(F &&f, icu::UnicodeString &out, UErrorCode &status)
+{
+	int32_t len = f(nullptr, 0, &status);
+	if (status != U_BUFFER_OVERFLOW_ERROR) {
+		return U_SUCCESS(status);
+	}
+
+	status = U_ZERO_ERROR;
+	UChar *buf = out.getBuffer(len);
+	if (buf == nullptr) {
+		status = U_MEMORY_ALLOCATION_ERROR;
+		return false;
+	}
+	len = f(buf, len, &status);
+	out.releaseBuffer(U_SUCCESS(status) ? len : 0);
+	return U_SUCCESS(status);
+}
+
 /* returns true if a is an ID separator, false otherwise */
 #define isIDSeparator(a) (a == '_' || a == '-')
 #define isKeywordSeparator(a) (a == '@' )
@@ -283,7 +322,7 @@ static zend_off_t getSingletonPos(const char* str)

 	if( str && ((len=strlen(str))>0) ){
 		zend_off_t i = 0;
-		for( i=0; (size_t)i < len ; i++){
+		for( i=0; static_cast<size_t>(i) < len ; i++){
 			if( isIDSeparator(*(str+i)) ){
 				if( i==1){
 					/* string is of the form x-avy or a-prv1 */
@@ -291,7 +330,7 @@ static zend_off_t getSingletonPos(const char* str)
 					break;
 				} else {
 					/* delimiter found; check for singleton */
-					if( (size_t)i + 2 < len && isIDSeparator(*(str+i+2)) ){
+					if( static_cast<size_t>(i) + 2 < len && isIDSeparator(*(str+i+2)) ){
 						/* a singleton; so send the position of separator before singleton */
 						result = i+1;
 						break;
@@ -324,14 +363,14 @@ U_CFUNC PHP_NAMED_FUNCTION(zif_locale_set_default)
 {
 	zend_string* locale_name;
 	zend_string *ini_name;
-	char *default_locale = nullptr;
+	const char *default_locale = nullptr;

 	ZEND_PARSE_PARAMETERS_START(1, 1)
 		Z_PARAM_PATH_STR(locale_name)
 	ZEND_PARSE_PARAMETERS_END();

 	if (ZSTR_LEN(locale_name) == 0) {
-		default_locale = (char *)uloc_getDefault();
+		default_locale = icu::Locale::getDefault().getName();
 		locale_name = zend_string_init(default_locale, strlen(default_locale), 0);
 	}

@@ -353,12 +392,8 @@ U_CFUNC PHP_NAMED_FUNCTION(zif_locale_set_default)
 */
 static zend_string* get_icu_value_internal( const char* loc_name , const char* tag_name, int* result , int fromParseLocale)
 {
-	zend_string* tag_value	    = nullptr;
-	int32_t      tag_value_len  = 512;
-
 	char*        mod_loc_name   = nullptr;

-	int32_t      buflen         = 512;
 	UErrorCode   status         = U_ZERO_ERROR;

 	if (UNEXPECTED(strlen(loc_name) > INTL_MAX_LOCALE_LEN)) {
@@ -406,68 +441,40 @@ static zend_string* get_icu_value_internal( const char* loc_name , const char* t
 	}

 	/* Proceed to ICU */
-	do{
-		if (tag_value) {
-			tag_value = zend_string_realloc( tag_value , buflen, 0);
-		} else {
-			tag_value = zend_string_alloc( buflen, 0);
-		}
-		tag_value_len = buflen;
-
-		if( strcmp(tag_name , LOC_SCRIPT_TAG)==0 ){
-			buflen = uloc_getScript ( mod_loc_name , tag_value->val , tag_value_len , &status);
+	zend_string *tag_value = locale_icu_string([&](char *buf, int32_t cap, UErrorCode *err) -> int32_t {
+		if (strcmp(tag_name, LOC_SCRIPT_TAG) == 0) {
+			return uloc_getScript(mod_loc_name, buf, cap, err);
 		}
-		if( strcmp(tag_name , LOC_LANG_TAG )==0 ){
-			buflen = uloc_getLanguage ( mod_loc_name , tag_value->val , tag_value_len , &status);
+		if (strcmp(tag_name, LOC_LANG_TAG) == 0) {
+			return uloc_getLanguage(mod_loc_name, buf, cap, err);
 		}
-		if( strcmp(tag_name , LOC_REGION_TAG)==0 ){
-			buflen = uloc_getCountry ( mod_loc_name , tag_value->val , tag_value_len , &status);
+		if (strcmp(tag_name, LOC_REGION_TAG) == 0) {
+			return uloc_getCountry(mod_loc_name, buf, cap, err);
 		}
-		if( strcmp(tag_name , LOC_VARIANT_TAG)==0 ){
-			buflen = uloc_getVariant ( mod_loc_name , tag_value->val , tag_value_len , &status);
+		if (strcmp(tag_name, LOC_VARIANT_TAG) == 0) {
+			return uloc_getVariant(mod_loc_name, buf, cap, err);
 		}
-		if( strcmp(tag_name , LOC_CANONICALIZE_TAG)==0 ){
-			buflen = uloc_canonicalize ( mod_loc_name , tag_value->val , tag_value_len , &status);
+		if (strcmp(tag_name, LOC_CANONICALIZE_TAG) == 0) {
+			return uloc_canonicalize(mod_loc_name, buf, cap, err);
 		}
+		return 0;
+	}, status);
+	efree(mod_loc_name);

-		if( U_FAILURE( status ) ) {
-			if( status == U_BUFFER_OVERFLOW_ERROR ) {
-				status = U_ZERO_ERROR;
-				buflen++; /* add space for \0 */
-				continue;
-			}
-
-			/* Error in retrieving data */
-			*result = 0;
-			if( tag_value ){
-				zend_string_release_ex( tag_value, 0 );
-			}
-			if( mod_loc_name ){
-				efree( mod_loc_name);
-			}
-			return nullptr;
-		}
-	} while( buflen > tag_value_len );
+	if (tag_value == nullptr) {
+		/* Error in retrieving data */
+		*result = 0;
+		return nullptr;
+	}

-	if(  buflen ==0 ){
+	if (ZSTR_LEN(tag_value) == 0) {
 		/* No value found */
 		*result = -1;
-		if( tag_value ){
-			zend_string_release_ex( tag_value, 0 );
-		}
-		if( mod_loc_name ){
-			efree( mod_loc_name);
-		}
+		zend_string_release_ex(tag_value, 0);
 		return nullptr;
-	} else {
-		*result = 1;
-	}
-
-	if( mod_loc_name ){
-		efree( mod_loc_name);
 	}

-	tag_value->len = buflen;
+	*result = 1;
 	return tag_value;
 }
 /* }}} */
@@ -496,7 +503,7 @@ static void get_icu_value_src_php( const char* tag_name, INTERNAL_FUNCTION_PARAM
 	ZEND_PARSE_PARAMETERS_END();

 	if(loc_name_len == 0) {
-		loc_name = (char *)intl_locale_get_default();
+		loc_name = const_cast<char *>(intl_locale_get_default());
 		loc_name_len = strlen(loc_name);
 	}

@@ -563,12 +570,10 @@ static void get_icu_disp_value_src_php( const char* tag_name, INTERNAL_FUNCTION_
 	size_t      disp_loc_name_len   = 0;
 	int         free_loc_name       = 0;

-	std::unique_ptr<UChar, char_deleter> disp_name;
-	int32_t     disp_name_len  	= 0;
+	icu::UnicodeString disp_name;

 	std::unique_ptr<char, char_deleter> mod_loc_name;

-	int32_t     buflen          	= 512;
 	UErrorCode  status          	= U_ZERO_ERROR;

 	zend_string* u8str;
@@ -590,7 +595,7 @@ static void get_icu_disp_value_src_php( const char* tag_name, INTERNAL_FUNCTION_
 	}

 	if(loc_name_len == 0) {
-		loc_name = (char *)intl_locale_get_default();
+		loc_name = const_cast<char *>(intl_locale_get_default());
 	}

 	if( strcmp(tag_name, DISP_NAME) != 0 ){
@@ -617,52 +622,40 @@ static void get_icu_disp_value_src_php( const char* tag_name, INTERNAL_FUNCTION_
 	}

 	/* Get the disp_value for the given locale */
-	do{
-		auto tmp = reinterpret_cast<UChar *>(erealloc( disp_name.release() , buflen * sizeof(UChar)  ));
-		disp_name.reset(tmp);
-		disp_name_len = buflen;
-
-		auto p_mod_loc_name = mod_loc_name.get();
-		auto p_disp_name = disp_name.get();
-
-		if( strcmp(tag_name , LOC_LANG_TAG)==0 ){
-			buflen = uloc_getDisplayLanguage ( p_mod_loc_name , disp_loc_name , p_disp_name , disp_name_len , &status);
-		} else if( strcmp(tag_name , LOC_SCRIPT_TAG)==0 ){
-			buflen = uloc_getDisplayScript ( p_mod_loc_name , disp_loc_name , p_disp_name , disp_name_len , &status);
-		} else if( strcmp(tag_name , LOC_REGION_TAG)==0 ){
-			buflen = uloc_getDisplayCountry ( p_mod_loc_name , disp_loc_name , p_disp_name , disp_name_len , &status);
-		} else if( strcmp(tag_name , LOC_VARIANT_TAG)==0 ){
-			buflen = uloc_getDisplayVariant ( p_mod_loc_name , disp_loc_name , p_disp_name , disp_name_len , &status);
-		} else if( strcmp(tag_name , DISP_NAME)==0 ){
-			buflen = uloc_getDisplayName ( p_mod_loc_name , disp_loc_name , p_disp_name , disp_name_len , &status);
+	const char *p_mod_loc_name = mod_loc_name.get();
+	bool ok = locale_icu_ustring([&](UChar *buf, int32_t cap, UErrorCode *err) -> int32_t {
+		if (strcmp(tag_name, LOC_LANG_TAG) == 0) {
+			return uloc_getDisplayLanguage(p_mod_loc_name, disp_loc_name, buf, cap, err);
 		}
-
-		/* U_STRING_NOT_TERMINATED_WARNING is admissible here; don't look for it */
-		if( U_FAILURE( status ) )
-		{
-			if( status == U_BUFFER_OVERFLOW_ERROR )
-			{
-				status = U_ZERO_ERROR;
-				continue;
-			}
-
-			spprintf(&msg, 0, "unable to get locale %s", tag_name );
-			intl_error_set( nullptr, status, msg);
-			efree(msg);
-			if (free_loc_name) {
-				efree((void *)disp_loc_name);
-				disp_loc_name = nullptr;
-			}
-			RETURN_FALSE;
+		if (strcmp(tag_name, LOC_SCRIPT_TAG) == 0) {
+			return uloc_getDisplayScript(p_mod_loc_name, disp_loc_name, buf, cap, err);
 		}
-	} while( buflen > disp_name_len );
+		if (strcmp(tag_name, LOC_REGION_TAG) == 0) {
+			return uloc_getDisplayCountry(p_mod_loc_name, disp_loc_name, buf, cap, err);
+		}
+		if (strcmp(tag_name, LOC_VARIANT_TAG) == 0) {
+			return uloc_getDisplayVariant(p_mod_loc_name, disp_loc_name, buf, cap, err);
+		}
+		if (strcmp(tag_name, DISP_NAME) == 0) {
+			return uloc_getDisplayName(p_mod_loc_name, disp_loc_name, buf, cap, err);
+		}
+		return 0;
+	}, disp_name, status);

 	if (free_loc_name) {
-		efree((void *)disp_loc_name);
+		efree(disp_loc_name);
 		disp_loc_name = nullptr;
 	}
+
+	if (!ok) {
+		spprintf(&msg, 0, "unable to get locale %s", tag_name );
+		intl_error_set( nullptr, status, msg);
+		efree(msg);
+		RETURN_FALSE;
+	}
+
 	/* Convert display locale name from UTF-16 to UTF-8. */
-	u8str = intl_convert_utf16_to_utf8(disp_name.get(), buflen, &status );
+	u8str = intl_charFromString(disp_name, &status);
 	if( !u8str )
 	{
 		spprintf(&msg, 0, "error converting display name for %s to UTF-8", tag_name );
@@ -671,7 +664,7 @@ static void get_icu_disp_value_src_php( const char* tag_name, INTERNAL_FUNCTION_
 		RETURN_FALSE;
 	}

-	RETVAL_NEW_STR( u8str );
+	RETURN_STR( u8str );
 }
 /* }}} */

@@ -688,9 +681,7 @@ static void get_icu_disp_keyword_value_src_php(const char* tag_name, INTERNAL_FU
 	size_t      disp_loc_name_len   = 0;
 	int         free_loc_name       = 0;

-	UChar*      disp_name           = nullptr;
-	int32_t     disp_name_len       = 0;
-	int32_t     buflen              = 512;
+	icu::UnicodeString disp_name;
 	UErrorCode  status              = U_ZERO_ERROR;

 	zend_string* u8str;
@@ -718,7 +709,7 @@ static void get_icu_disp_keyword_value_src_php(const char* tag_name, INTERNAL_FU
 		}

 		if (loc_name_len == 0) {
-			loc_name = (char *)intl_locale_get_default();
+			loc_name = const_cast<char *>(intl_locale_get_default());
 		}
 	}

@@ -727,44 +718,26 @@ static void get_icu_disp_keyword_value_src_php(const char* tag_name, INTERNAL_FU
 		free_loc_name = 1;
 	}

-	do {
-		disp_name = reinterpret_cast<UChar *>(erealloc(disp_name, buflen * sizeof(UChar)));
-		disp_name_len = buflen;
-
+	bool ok = locale_icu_ustring([&](UChar *buf, int32_t cap, UErrorCode *err) -> int32_t {
 		if (strcmp(tag_name, DISP_KEYWORD) == 0) {
-			buflen = uloc_getDisplayKeyword(keyword_name, disp_loc_name, disp_name, disp_name_len, &status);
-		} else {
-			buflen = uloc_getDisplayKeywordValue(loc_name, keyword_name, disp_loc_name, disp_name, disp_name_len, &status);
+			return uloc_getDisplayKeyword(keyword_name, disp_loc_name, buf, cap, err);
 		}
-
-		/* U_STRING_NOT_TERMINATED_WARNING is admissible here; don't look for it */
-		if (U_FAILURE(status)) {
-			if (status == U_BUFFER_OVERFLOW_ERROR) {
-				status = U_ZERO_ERROR;
-				continue;
-			}
-
-			spprintf(&msg, 0, "unable to get locale %s", tag_name);
-			intl_error_set( nullptr, status, msg);
-			efree(msg);
-			if (disp_name) {
-				efree(disp_name);
-			}
-			if (free_loc_name) {
-				efree((void *)disp_loc_name);
-				disp_loc_name = nullptr;
-			}
-			RETURN_FALSE;
-		}
-	} while (buflen > disp_name_len);
+		return uloc_getDisplayKeywordValue(loc_name, keyword_name, disp_loc_name, buf, cap, err);
+	}, disp_name, status);

 	if (free_loc_name) {
-		efree((void *)disp_loc_name);
+		efree(disp_loc_name);
 		disp_loc_name = nullptr;
 	}

-	u8str = intl_convert_utf16_to_utf8(disp_name, buflen, &status);
-	efree(disp_name);
+	if (!ok) {
+		spprintf(&msg, 0, "unable to get locale %s", tag_name);
+		intl_error_set( nullptr, status, msg);
+		efree(msg);
+		RETURN_FALSE;
+	}
+
+	u8str = intl_charFromString(disp_name, &status);
 	if (!u8str) {
 		spprintf(&msg, 0, "error converting display name for %s to UTF-8", tag_name);
 		intl_error_set( nullptr, status, msg);
@@ -772,7 +745,7 @@ static void get_icu_disp_keyword_value_src_php(const char* tag_name, INTERNAL_FU
 		RETURN_FALSE;
 	}

-	RETVAL_NEW_STR(u8str);
+	RETURN_STR(u8str);
 }
 /* }}} */

@@ -840,7 +813,6 @@ U_CFUNC PHP_FUNCTION(locale_get_display_keyword_value)
  */
 PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_get_keywords)
 {
-	UEnumeration*   e        = nullptr;
 	UErrorCode      status   = U_ZERO_ERROR;

 	const char*	 	kw_key        = nullptr;
@@ -856,51 +828,30 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_get_keywords)
 	INTL_CHECK_LOCALE_LEN(loc_name_len);

 	if(loc_name_len == 0) {
-		loc_name = (char *)intl_locale_get_default();
+		loc_name = const_cast<char *>(intl_locale_get_default());
 	}

 	/* Get the keywords */
-	e = uloc_openKeywords( loc_name, &status );
-	if( e != nullptr ) {
-		/*
-		ICU expects the buffer to be allocated  before calling the function
-		and so the buffer size has been explicitly specified
-		ICU uloc.h #define 	ULOC_KEYWORD_AND_VALUES_CAPACITY   100
-		hence the kw_value buffer size is 100
-		*/
-
+	icu::LocalUEnumerationPointer e(uloc_openKeywords( loc_name, &status ));
+	if( e.isValid() ) {
 		/* Traverse it, filling the return array. */
 		array_init( return_value );

-		while( ( kw_key = uenum_next( e, &kw_key_len, &status ) ) != nullptr ){
-			int32_t kw_value_len = 100;
-			zend_string *kw_value_str = zend_string_alloc(kw_value_len, 0);
-
+		while( ( kw_key = uenum_next( e.getAlias(), &kw_key_len, &status ) ) != nullptr ){
 			/* Get the keyword value for each keyword */
-			kw_value_len=uloc_getKeywordValue( loc_name, kw_key, ZSTR_VAL(kw_value_str), kw_value_len, &status );
-			if (status == U_BUFFER_OVERFLOW_ERROR) {
-				status = U_ZERO_ERROR;
-				kw_value_str = zend_string_extend(kw_value_str, kw_value_len, 0);
-				kw_value_len=uloc_getKeywordValue( loc_name,kw_key, ZSTR_VAL(kw_value_str), kw_value_len+1, &status );
-			} else if(!U_FAILURE(status)) {
-				kw_value_str = zend_string_truncate(kw_value_str, kw_value_len, 0);
-			}
-			if (U_FAILURE(status)) {
+			zend_string *kw_value_str = locale_icu_string([&](char *buf, int32_t cap, UErrorCode *err) -> int32_t {
+				return uloc_getKeywordValue(loc_name, kw_key, buf, cap, err);
+			}, status);
+			if (kw_value_str == nullptr) {
 				intl_error_set( nullptr, U_ILLEGAL_ARGUMENT_ERROR, "Error encountered while getting the keyword value for the keyword");
-				if( kw_value_str){
-					zend_string_efree( kw_value_str );
-				}
 				zend_array_destroy(Z_ARR_P(return_value));
-				uenum_close( e );
 				RETURN_FALSE;
 			}

-			add_assoc_str( return_value, (char *)kw_key, kw_value_str);
+			add_assoc_str( return_value, kw_key, kw_value_str);
 		} /* end of while */

 	} /* end of if e!=nullptr */
-
-	uenum_close( e );
 }
 /* }}} */

@@ -1152,7 +1103,7 @@ static zend_string* get_private_subtags(const char* loc_name)
 				break;
 			}
 			else{
-				if((size_t)(singletonPos + 1) >= len){
+				if(static_cast<size_t>(singletonPos + 1) >= len){
 					/* String end */
 					break;
 				} else {
@@ -1238,14 +1189,14 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_parse)
 	INTL_CHECK_LOCALE_LEN(loc_name_len);

 	if(loc_name_len == 0) {
-		loc_name = (char *)intl_locale_get_default();
+		loc_name = const_cast<char *>(intl_locale_get_default());
 	}

 	array_init( return_value );

 	grOffset =  findOffset( LOC_GRANDFATHERED , loc_name );
 	if( grOffset >= 0 ){
-		add_assoc_string( return_value , LOC_GRANDFATHERED_LANG_TAG, (char *)loc_name);
+		add_assoc_string( return_value , LOC_GRANDFATHERED_LANG_TAG, loc_name);
 	}
 	else{
 		/* Not grandfathered */
@@ -1274,7 +1225,7 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_get_all_variants)
 	ZEND_PARSE_PARAMETERS_END();

 	if(loc_name_len == 0) {
-		loc_name = (char *)intl_locale_get_default();
+		loc_name = const_cast<char *>(intl_locale_get_default());
 		loc_name_len = strlen(loc_name);
 	}

@@ -1369,7 +1320,7 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_filter_matches)
 	ZEND_PARSE_PARAMETERS_END();

 	if(loc_range_len == 0) {
-		loc_range = (char *)intl_locale_get_default();
+		loc_range = const_cast<char *>(intl_locale_get_default());
 		loc_range_len = strlen(loc_range);
 	}

@@ -1625,7 +1576,7 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_lookup)
 			loc_range = ZSTR_VAL(fallback_loc_str);
 			loc_range_len = ZSTR_LEN(fallback_loc_str);
 		} else {
-			loc_range = (char *)intl_locale_get_default();
+			loc_range = const_cast<char *>(intl_locale_get_default());
 			loc_range_len = strlen(loc_range);
 		}
 	}
@@ -1768,7 +1719,7 @@ U_CFUNC PHP_FUNCTION(locale_is_right_to_left)
 	ZEND_PARSE_PARAMETERS_END();

 	if (!locale_len) {
-		locale = (char *)intl_locale_get_default();
+		locale = const_cast<char *>(intl_locale_get_default());
 	}

 	RETURN_BOOL(uloc_isRightToLeft(locale));
@@ -1785,7 +1736,7 @@ U_CFUNC PHP_FUNCTION(locale_add_likely_subtags)
 	ZEND_PARSE_PARAMETERS_END();

 	if (!locale_len) {
-		locale = (char *)intl_locale_get_default();
+		locale = const_cast<char *>(intl_locale_get_default());
 	}

 	const int32_t maximized_locale_len = uloc_addLikelySubtags(locale, maximized_locale, sizeof(maximized_locale), &status);
@@ -1808,7 +1759,7 @@ U_CFUNC PHP_FUNCTION(locale_minimize_subtags)
 	ZEND_PARSE_PARAMETERS_END();

 	if (!locale_len) {
-		locale = (char *)intl_locale_get_default();
+		locale = const_cast<char *>(intl_locale_get_default());
 	}

 	const int32_t minimized_locale_len = uloc_minimizeSubtags(locale, minimized_locale, sizeof(minimized_locale), &status);