Commit 0920f2a2516 for php.net
commit 0920f2a251640761785c70a39f8ed0c4959a08cc
Author: David CARLIER <devnexen@gmail.com>
Date: Mon Aug 3 20:01:08 2026 +0100
ext/intl: get_icu_value_internal() to reduce manual memory manageme… (#19433)
diff --git a/ext/intl/locale/locale_methods.cpp b/ext/intl/locale/locale_methods.cpp
index 87a08d96c62..bb4cd123649 100644
--- a/ext/intl/locale/locale_methods.cpp
+++ b/ext/intl/locale/locale_methods.cpp
@@ -16,6 +16,8 @@
#include <config.h>
#endif
+#include <memory>
+
#include <unicode/ustring.h>
#include <unicode/udata.h>
#include <unicode/putil.h>
@@ -116,7 +118,7 @@ static const char * const LOC_GRANDFATHERED[] = {
"zh-min-nan",
"zh-wuu",
"zh-xiang",
- NULL
+ nullptr
};
/* Based on the IANA language subtag registry (File-Date: 2021-08-06)
@@ -125,20 +127,20 @@ static const char * const LOC_GRANDFATHERED[] = {
* tags listed in LOC_GRANDFATHERED. This is in sync with the array
* LOC_GRANDFATHERED, i.e., the offsets of the grandfathered tags match the
* offsets of the preferred value. If a value in LOC_PREFERRED_GRANDFATHERED is
- * NULL, then the matching offset in LOC_GRANDFATHERED has no preferred value.
+ * nullptr, then the matching offset in LOC_GRANDFATHERED has no preferred value.
*/
static const char * const LOC_PREFERRED_GRANDFATHERED[] = {
"jbo",
- NULL,
+ nullptr,
"en-GB-oxendict",
"ami",
"bnn",
- NULL,
- NULL,
+ nullptr,
+ nullptr,
"hak",
"tlh",
"lb",
- NULL,
+ nullptr,
"nv",
"pwn",
"tao",
@@ -174,11 +176,17 @@ static const char * const LOC_PREFERRED_GRANDFATHERED[] = {
"gan",
"cmn",
"hak",
- NULL,
+ nullptr,
"nan",
"wuu",
"hsn",
- NULL
+ nullptr
+};
+
+struct char_deleter {
+ void operator()(void *p) const {
+ efree(p);
+ }
};
/* returns true if a is an ID separator, false otherwise */
@@ -202,7 +210,7 @@ static const char * const LOC_PREFERRED_GRANDFATHERED[] = {
static int16_t findOffset(const char* const* list, const char* key)
{
const char* const* anchor = list;
- while (*list != NULL) {
+ while (*list != nullptr) {
if (strcasecmp(key, *list) == 0) {
return (int16_t)(list - anchor);
}
@@ -216,14 +224,14 @@ static int16_t findOffset(const char* const* list, const char* key)
static char* getPreferredTag(const char* gf_tag)
{
- char* result = NULL;
+ char* result = nullptr;
zend_off_t grOffset = 0;
grOffset = findOffset( LOC_GRANDFATHERED ,gf_tag);
if(grOffset < 0) {
- return NULL;
+ return nullptr;
}
- if( LOC_PREFERRED_GRANDFATHERED[grOffset] != NULL ){
+ if( LOC_PREFERRED_GRANDFATHERED[grOffset] != nullptr ){
/* return preferred tag */
result = estrdup( LOC_PREFERRED_GRANDFATHERED[grOffset] );
} else {
@@ -316,7 +324,7 @@ U_CFUNC PHP_NAMED_FUNCTION(zif_locale_set_default)
{
zend_string* locale_name;
zend_string *ini_name;
- char *default_locale = NULL;
+ char *default_locale = nullptr;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_PATH_STR(locale_name)
@@ -330,7 +338,7 @@ U_CFUNC PHP_NAMED_FUNCTION(zif_locale_set_default)
ini_name = zend_string_init(LOCALE_INI_NAME, sizeof(LOCALE_INI_NAME) - 1, 0);
zend_alter_ini_entry(ini_name, locale_name, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
zend_string_release_ex(ini_name, 0);
- if (default_locale != NULL) {
+ if (default_locale != nullptr) {
zend_string_release_ex(locale_name, 0);
}
@@ -345,16 +353,16 @@ 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 = NULL;
+ zend_string* tag_value = nullptr;
int32_t tag_value_len = 512;
- char* mod_loc_name = NULL;
+ char* mod_loc_name = nullptr;
int32_t buflen = 512;
UErrorCode status = U_ZERO_ERROR;
if (UNEXPECTED(strlen(loc_name) > INTL_MAX_LOCALE_LEN)) {
- return NULL;
+ return nullptr;
}
if( strcmp(tag_name, LOC_CANONICALIZE_TAG) != 0 ){
@@ -364,8 +372,8 @@ static zend_string* get_icu_value_internal( const char* loc_name , const char* t
if( strcmp(tag_name , LOC_LANG_TAG)==0 ){
return zend_string_init(loc_name, strlen(loc_name), 0);
} else {
- /* Since Grandfathered , no value , do nothing , return NULL */
- return NULL;
+ /* Since Grandfathered , no value , do nothing , return nullptr */
+ return nullptr;
}
}
@@ -383,7 +391,7 @@ static zend_string* get_icu_value_internal( const char* loc_name , const char* t
if( singletonPos == 0){
/* singleton at start of script, region , variant etc.
* or invalid singleton at start of language */
- return NULL;
+ return nullptr;
} else if( singletonPos > 0 ){
/* singleton at some position except at start
* strip off the singleton and rest of the loc_name */
@@ -393,7 +401,7 @@ static zend_string* get_icu_value_internal( const char* loc_name , const char* t
} /* end of if != LOC_CANONICAL_TAG */
- if( mod_loc_name == NULL){
+ if( mod_loc_name == nullptr){
mod_loc_name = estrdup(loc_name );
}
@@ -437,7 +445,7 @@ static zend_string* get_icu_value_internal( const char* loc_name , const char* t
if( mod_loc_name ){
efree( mod_loc_name);
}
- return NULL;
+ return nullptr;
}
} while( buflen > tag_value_len );
@@ -450,7 +458,7 @@ static zend_string* get_icu_value_internal( const char* loc_name , const char* t
if( mod_loc_name ){
efree( mod_loc_name);
}
- return NULL;
+ return nullptr;
} else {
*result = 1;
}
@@ -471,17 +479,17 @@ static zend_string* get_icu_value_internal( const char* loc_name , const char* t
static void get_icu_value_src_php( const char* tag_name, INTERNAL_FUNCTION_PARAMETERS)
{
- char* loc_name = NULL;
+ char* loc_name = nullptr;
size_t loc_name_len = 0;
- zend_string* tag_value = NULL;
+ zend_string* tag_value = nullptr;
int result = 0;
- char* msg = NULL;
+ char* msg = nullptr;
UErrorCode status = U_ZERO_ERROR;
- intl_error_reset( NULL );
+ intl_error_reset( nullptr );
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_PATH(loc_name, loc_name_len)
@@ -513,7 +521,7 @@ static void get_icu_value_src_php( const char* tag_name, INTERNAL_FUNCTION_PARAM
/* Error encountered while fetching the value */
if( result ==0) {
spprintf(&msg , 0, "unable to get locale %s", tag_name );
- intl_error_set( NULL, status, msg);
+ intl_error_set( nullptr, status, msg);
efree(msg);
RETURN_NULL();
}
@@ -548,26 +556,26 @@ U_CFUNC PHP_FUNCTION(locale_get_primary_language )
}}} */
static void get_icu_disp_value_src_php( const char* tag_name, INTERNAL_FUNCTION_PARAMETERS)
{
- char* loc_name = NULL;
+ char* loc_name = nullptr;
size_t loc_name_len = 0;
- char* disp_loc_name = NULL;
+ char* disp_loc_name = nullptr;
size_t disp_loc_name_len = 0;
int free_loc_name = 0;
- UChar* disp_name = NULL;
+ std::unique_ptr<UChar, char_deleter> disp_name;
int32_t disp_name_len = 0;
- char* mod_loc_name = NULL;
+ std::unique_ptr<char, char_deleter> mod_loc_name;
int32_t buflen = 512;
UErrorCode status = U_ZERO_ERROR;
zend_string* u8str;
- char* msg = NULL;
+ char* msg = nullptr;
- intl_error_reset( NULL );
+ intl_error_reset( nullptr );
ZEND_PARSE_PARAMETERS_START(1, 2)
Z_PARAM_PATH(loc_name, loc_name_len)
@@ -577,7 +585,7 @@ static void get_icu_disp_value_src_php( const char* tag_name, INTERNAL_FUNCTION_
if (UNEXPECTED(loc_name_len > ULOC_FULLNAME_CAPACITY)) {
/* See bug 67397: overlong locale names cause trouble in uloc_getDisplayName */
- intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "name too long");
+ intl_error_set( nullptr, U_ILLEGAL_ARGUMENT_ERROR, "name too long");
RETURN_FALSE;
}
@@ -590,16 +598,16 @@ static void get_icu_disp_value_src_php( const char* tag_name, INTERNAL_FUNCTION_
int grOffset = findOffset( LOC_GRANDFATHERED , loc_name );
if( grOffset >= 0 ){
if( strcmp(tag_name , LOC_LANG_TAG)==0 ){
- mod_loc_name = getPreferredTag( loc_name );
+ mod_loc_name = std::unique_ptr<char, char_deleter>(getPreferredTag( loc_name ));
} else {
- /* Since Grandfathered, no value, do nothing, return NULL */
+ /* Since Grandfathered, no value, do nothing, return nullptr */
RETURN_FALSE;
}
}
} /* end of if != LOC_CANONICAL_TAG */
- if( mod_loc_name==NULL ){
- mod_loc_name = estrdup( loc_name );
+ if( mod_loc_name==nullptr ){
+ mod_loc_name = std::unique_ptr<char, char_deleter>(estrdup( loc_name ));
}
/* Check if disp_loc_name passed , if not use default locale */
@@ -610,19 +618,23 @@ static void get_icu_disp_value_src_php( const char* tag_name, INTERNAL_FUNCTION_
/* Get the disp_value for the given locale */
do{
- disp_name = reinterpret_cast<UChar *>(erealloc( disp_name , buflen * sizeof(UChar) ));
+ 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 ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status);
+ 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 ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status);
+ 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 ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status);
+ 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 ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status);
+ 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 ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status);
+ buflen = uloc_getDisplayName ( p_mod_loc_name , disp_loc_name , p_disp_name , disp_name_len , &status);
}
/* U_STRING_NOT_TERMINATED_WARNING is admissible here; don't look for it */
@@ -635,36 +647,26 @@ static void get_icu_disp_value_src_php( const char* tag_name, INTERNAL_FUNCTION_
}
spprintf(&msg, 0, "unable to get locale %s", tag_name );
- intl_error_set( NULL, status, msg);
+ intl_error_set( nullptr, status, msg);
efree(msg);
- if( disp_name){
- efree( disp_name );
- }
- if( mod_loc_name){
- efree( mod_loc_name );
- }
if (free_loc_name) {
efree((void *)disp_loc_name);
- disp_loc_name = NULL;
+ disp_loc_name = nullptr;
}
RETURN_FALSE;
}
} while( buflen > disp_name_len );
- if( mod_loc_name){
- efree( mod_loc_name );
- }
if (free_loc_name) {
efree((void *)disp_loc_name);
- disp_loc_name = NULL;
+ disp_loc_name = nullptr;
}
/* Convert display locale name from UTF-16 to UTF-8. */
- u8str = intl_convert_utf16_to_utf8(disp_name, buflen, &status );
- efree( disp_name );
+ u8str = intl_convert_utf16_to_utf8(disp_name.get(), buflen, &status );
if( !u8str )
{
spprintf(&msg, 0, "error converting display name for %s to UTF-8", tag_name );
- intl_error_set( NULL, status, msg);
+ intl_error_set( nullptr, status, msg);
efree(msg);
RETURN_FALSE;
}
@@ -678,23 +680,23 @@ static void get_icu_disp_value_src_php( const char* tag_name, INTERNAL_FUNCTION_
}}} */
static void get_icu_disp_keyword_value_src_php(const char* tag_name, INTERNAL_FUNCTION_PARAMETERS)
{
- char* loc_name = NULL;
+ char* loc_name = nullptr;
size_t loc_name_len = 0;
- char* keyword_name = NULL;
+ char* keyword_name = nullptr;
size_t keyword_name_len = 0;
- char* disp_loc_name = NULL;
+ char* disp_loc_name = nullptr;
size_t disp_loc_name_len = 0;
int free_loc_name = 0;
- UChar* disp_name = NULL;
+ UChar* disp_name = nullptr;
int32_t disp_name_len = 0;
int32_t buflen = 512;
UErrorCode status = U_ZERO_ERROR;
zend_string* u8str;
- char* msg = NULL;
+ char* msg = nullptr;
- intl_error_reset( NULL );
+ intl_error_reset( nullptr );
if (strcmp(tag_name, DISP_KEYWORD) == 0) {
ZEND_PARSE_PARAMETERS_START(1, 2)
@@ -711,7 +713,7 @@ static void get_icu_disp_keyword_value_src_php(const char* tag_name, INTERNAL_FU
ZEND_PARSE_PARAMETERS_END();
if (UNEXPECTED(loc_name_len > ULOC_FULLNAME_CAPACITY)) {
- intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "name too long");
+ intl_error_set( nullptr, U_ILLEGAL_ARGUMENT_ERROR, "name too long");
RETURN_FALSE;
}
@@ -743,14 +745,14 @@ static void get_icu_disp_keyword_value_src_php(const char* tag_name, INTERNAL_FU
}
spprintf(&msg, 0, "unable to get locale %s", tag_name);
- intl_error_set( NULL, status, msg);
+ 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 = NULL;
+ disp_loc_name = nullptr;
}
RETURN_FALSE;
}
@@ -758,14 +760,14 @@ static void get_icu_disp_keyword_value_src_php(const char* tag_name, INTERNAL_FU
if (free_loc_name) {
efree((void *)disp_loc_name);
- disp_loc_name = NULL;
+ disp_loc_name = nullptr;
}
u8str = intl_convert_utf16_to_utf8(disp_name, buflen, &status);
efree(disp_name);
if (!u8str) {
spprintf(&msg, 0, "error converting display name for %s to UTF-8", tag_name);
- intl_error_set( NULL, status, msg);
+ intl_error_set( nullptr, status, msg);
efree(msg);
RETURN_FALSE;
}
@@ -838,16 +840,15 @@ U_CFUNC PHP_FUNCTION(locale_get_display_keyword_value)
*/
PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_get_keywords)
{
- UEnumeration* e = NULL;
+ UEnumeration* e = nullptr;
UErrorCode status = U_ZERO_ERROR;
- const char* kw_key = NULL;
+ const char* kw_key = nullptr;
int32_t kw_key_len = 0;
- char* loc_name = NULL;
+ char* loc_name = nullptr;
size_t loc_name_len = 0;
-
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_PATH(loc_name, loc_name_len)
ZEND_PARSE_PARAMETERS_END();
@@ -860,7 +861,7 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_get_keywords)
/* Get the keywords */
e = uloc_openKeywords( loc_name, &status );
- if( e != NULL ) {
+ if( e != nullptr ) {
/*
ICU expects the buffer to be allocated before calling the function
and so the buffer size has been explicitly specified
@@ -871,7 +872,7 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_get_keywords)
/* Traverse it, filling the return array. */
array_init( return_value );
- while( ( kw_key = uenum_next( e, &kw_key_len, &status ) ) != NULL ){
+ 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);
@@ -885,7 +886,7 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_get_keywords)
kw_value_str = zend_string_truncate(kw_value_str, kw_value_len, 0);
}
if (U_FAILURE(status)) {
- intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "Error encountered while getting the keyword value for the keyword");
+ 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 );
}
@@ -896,7 +897,7 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_get_keywords)
add_assoc_str( return_value, (char *)kw_key, kw_value_str);
} /* end of while */
- } /* end of if e!=NULL */
+ } /* end of if e!=nullptr */
uenum_close( e );
}
@@ -921,7 +922,7 @@ static int append_key_value(smart_str* loc_name, HashTable* hash_arr, const char
{
zval *ele_value;
- if ((ele_value = zend_hash_str_find_deref(hash_arr , key_name, strlen(key_name))) != NULL ) {
+ if ((ele_value = zend_hash_str_find_deref(hash_arr , key_name, strlen(key_name))) != nullptr ) {
if(Z_TYPE_P(ele_value)!= IS_STRING ){
/* element value is not a string */
return FAILURE;
@@ -964,7 +965,7 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr,
int isFirstSubtag = 0;
/* Variant/ Extlang/Private etc. */
- if ((ele_value = zend_hash_str_find_deref( hash_arr , key_name , strlen(key_name))) != NULL) {
+ if ((ele_value = zend_hash_str_find_deref( hash_arr , key_name , strlen(key_name))) != nullptr) {
if( Z_TYPE_P(ele_value) == IS_STRING ){
add_prefix( loc_name , key_name);
@@ -1008,7 +1009,7 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr,
isFirstSubtag = 0;
for( i=0 ; i< max_value; i++ ){
snprintf( cur_key_name , 30, "%s%d", key_name , i);
- if ((ele_value = zend_hash_str_find_deref( hash_arr , cur_key_name , strlen(cur_key_name))) != NULL) {
+ if ((ele_value = zend_hash_str_find_deref( hash_arr , cur_key_name , strlen(cur_key_name))) != nullptr) {
if( Z_TYPE_P(ele_value)!= IS_STRING ){
/* variant is not a string */
return FAILURE;
@@ -1034,9 +1035,9 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr,
*/
static int handleAppendResult( int result, smart_str* loc_name)
{
- intl_error_reset( NULL );
+ intl_error_reset( nullptr );
if( result == FAILURE) {
- intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ intl_error_set( nullptr, U_ILLEGAL_ARGUMENT_ERROR,
"parameter array element is not a string");
smart_str_free(loc_name);
return 0;
@@ -1052,13 +1053,12 @@ static int handleAppendResult( int result, smart_str* loc_name)
* }}} */
PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_compose)
{
- smart_str loc_name_s = {NULL, 0};
+ smart_str loc_name_s = {nullptr, 0};
smart_str *loc_name = &loc_name_s;
- zval* arr = NULL;
- HashTable* hash_arr = NULL;
+ zval* arr = nullptr;
+ HashTable* hash_arr = nullptr;
int result = 0;
-
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ARRAY(arr)
ZEND_PARSE_PARAMETERS_END();
@@ -1125,15 +1125,15 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_compose)
/*{{{
* Parses the locale and returns private subtags if existing
-* else returns NULL
+* else returns nullptr
* e.g. for locale='en_US-x-prv1-prv2-prv3'
* returns a pointer to the string 'prv1-prv2-prv3'
*/
static zend_string* get_private_subtags(const char* loc_name)
{
- zend_string* result = NULL;
+ zend_string* result = nullptr;
size_t len = 0;
- const char* mod_loc_name =NULL;
+ const char* mod_loc_name =nullptr;
if( loc_name && (len = strlen(loc_name)) > 0 ){
zend_off_t singletonPos = 0;
@@ -1142,7 +1142,7 @@ static zend_string* get_private_subtags(const char* loc_name)
if( (*(mod_loc_name+singletonPos)=='x') || (*(mod_loc_name+singletonPos)=='X') ){
/* private subtag start found */
if( singletonPos + 2 == len){
- /* loc_name ends with '-x-' ; return NULL */
+ /* loc_name ends with '-x-' ; return nullptr */
}
else{
/* result = mod_loc_name + singletonPos +2; */
@@ -1170,10 +1170,10 @@ static zend_string* get_private_subtags(const char* loc_name)
/* {{{ code used by locale_parse */
static int add_array_entry(const char* loc_name, zval* hash_arr, const char* key_name)
{
- zend_string* key_value = NULL;
- char* cur_key_name = NULL;
- char* token = NULL;
- char* last_ptr = NULL;
+ zend_string* key_value = nullptr;
+ std::unique_ptr<char, char_deleter> cur_key_name;
+ char* token = nullptr;
+ char* last_ptr = nullptr;
int result = 0;
int cur_result = 0;
@@ -1191,18 +1191,16 @@ static int add_array_entry(const char* loc_name, zval* hash_arr, const char* key
int cnt = 0;
/* Tokenize on the "_" or "-" */
token = php_strtok_r( key_value->val , DELIMITER ,&last_ptr);
- if( cur_key_name ){
- efree( cur_key_name);
- }
/* Over-allocates a few bytes for the integer so we don't have to reallocate. */
size_t cur_key_name_size = (sizeof("-2147483648") - 1) + strlen(key_name) + 1;
- cur_key_name = reinterpret_cast<char *>(emalloc(cur_key_name_size));
- snprintf( cur_key_name, cur_key_name_size , "%s%d", key_name , cnt++);
- add_assoc_string( hash_arr, cur_key_name , token);
+ cur_key_name.reset(reinterpret_cast<char *>(emalloc(cur_key_name_size)));
+ char *p_cur_key_name = cur_key_name.get();
+ snprintf( p_cur_key_name, cur_key_name_size , "%s%d", key_name , cnt++);
+ add_assoc_string( hash_arr, p_cur_key_name , token);
/* tokenize on the "_" or "-" and stop at singleton if any */
- while( (token = php_strtok_r(NULL , DELIMITER , &last_ptr)) && (strlen(token)>1) ){
- snprintf( cur_key_name , cur_key_name_size, "%s%d", key_name , cnt++);
- add_assoc_string( hash_arr, cur_key_name , token);
+ while( (token = php_strtok_r(nullptr , DELIMITER , &last_ptr)) && (strlen(token)>1) ){
+ snprintf( p_cur_key_name , cur_key_name_size, "%s%d", key_name , cnt++);
+ add_assoc_string( hash_arr, p_cur_key_name , token);
}
/*
if( strcmp(key_name, LOC_PRIVATE_TAG) == 0 ){
@@ -1220,10 +1218,6 @@ static int add_array_entry(const char* loc_name, zval* hash_arr, const char* key
zend_string_release_ex(key_value, 0);
}
}
-
- if( cur_key_name ){
- efree( cur_key_name);
- }
/*if( key_name != LOC_PRIVATE_TAG && key_value){*/
return cur_result;
}
@@ -1232,11 +1226,10 @@ static int add_array_entry(const char* loc_name, zval* hash_arr, const char* key
/* {{{ parses a locale-id into an array the different parts of it */
PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_parse)
{
- char* loc_name = NULL;
+ char* loc_name = nullptr;
size_t loc_name_len = 0;
int grOffset = 0;
-
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_PATH(loc_name, loc_name_len)
ZEND_PARSE_PARAMETERS_END();
@@ -1267,14 +1260,13 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_parse)
/* {{{ gets an array containing the list of variants, or null */
PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_get_all_variants)
{
- char* loc_name = NULL;
+ char* loc_name = nullptr;
size_t loc_name_len = 0;
int result = 0;
- char* token = NULL;
- zend_string* variant = NULL;
- char* saved_ptr = NULL;
-
+ char* token = nullptr;
+ zend_string* variant = nullptr;
+ char* saved_ptr = nullptr;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_PATH(loc_name, loc_name_len)
@@ -1301,7 +1293,7 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_get_all_variants)
token = php_strtok_r( variant->val , DELIMITER , &saved_ptr);
add_next_index_stringl( return_value, token , strlen(token));
/* tokenize on the "_" or "-" and stop at singleton if any */
- while( (token = php_strtok_r(NULL , DELIMITER, &saved_ptr)) && (strlen(token)>1) ){
+ while( (token = php_strtok_r(nullptr , DELIMITER, &saved_ptr)) && (strlen(token)>1) ){
add_next_index_stringl( return_value, token , strlen(token));
}
}
@@ -1317,8 +1309,8 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_get_all_variants)
/* {{{ Converts to lower case and also replaces all hyphens with the underscore */
static int strToMatch(const char* str ,char *retstr)
{
- char* anchor = NULL;
- const char* anchor1 = NULL;
+ char* anchor = nullptr;
+ const char* anchor1 = nullptr;
int result = 0;
if( (!str) || str[0] == '\0'){
@@ -1350,25 +1342,24 @@ static int strToMatch(const char* str ,char *retstr)
/* {{{ Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm */
PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_filter_matches)
{
- char* lang_tag = NULL;
+ char* lang_tag = nullptr;
size_t lang_tag_len = 0;
- char* loc_range = NULL;
+ char* loc_range = nullptr;
size_t loc_range_len = 0;
int result = 0;
char* token = 0;
- char* chrcheck = NULL;
+ char* chrcheck = nullptr;
- zend_string* can_lang_tag = NULL;
- zend_string* can_loc_range = NULL;
+ zend_string* can_lang_tag = nullptr;
+ zend_string* can_loc_range = nullptr;
- char* cur_lang_tag = NULL;
- char* cur_loc_range = NULL;
+ std::unique_ptr<char, char_deleter> cur_lang_tag;
+ std::unique_ptr<char, char_deleter> cur_loc_range;
bool boolCanonical = 0;
UErrorCode status = U_ZERO_ERROR;
-
ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_PATH(lang_tag, lang_tag_len)
Z_PARAM_PATH(loc_range, loc_range_len)
@@ -1392,7 +1383,7 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_filter_matches)
/* canonicalize loc_range */
can_loc_range=get_icu_value_internal( loc_range , LOC_CANONICALIZE_TAG , &result , 0);
if( result <=0) {
- intl_error_set(NULL, status, "unable to canonicalize loc_range");
+ intl_error_set(nullptr, status, "unable to canonicalize loc_range");
RETURN_FALSE;
}
@@ -1400,103 +1391,77 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_filter_matches)
can_lang_tag = get_icu_value_internal( lang_tag , LOC_CANONICALIZE_TAG , &result , 0);
if( result <=0) {
zend_string_release_ex( can_loc_range, false );
- intl_error_set(NULL, status, "unable to canonicalize lang_tag");
+ intl_error_set(nullptr, status, "unable to canonicalize lang_tag");
RETURN_FALSE;
}
/* Convert to lower case for case-insensitive comparison */
- cur_lang_tag = reinterpret_cast<char *>(ecalloc( 1, can_lang_tag->len + 1));
+ cur_lang_tag = std::unique_ptr<char, char_deleter>(reinterpret_cast<char *>(ecalloc( 1, can_lang_tag->len + 1)));
+ char *p_cur_lang_tag = cur_lang_tag.get();
/* Convert to lower case for case-insensitive comparison */
- result = strToMatch( can_lang_tag->val , cur_lang_tag);
+ result = strToMatch( can_lang_tag->val , p_cur_lang_tag);
if( result == 0) {
- efree( cur_lang_tag );
- zend_string_release_ex( can_lang_tag, 0 );
+ zend_string_release_ex( can_lang_tag, false );
RETURN_FALSE;
}
- cur_loc_range = reinterpret_cast<char *>(ecalloc( 1, can_loc_range->len + 1));
- result = strToMatch( can_loc_range->val , cur_loc_range );
+ cur_loc_range = std::unique_ptr<char, char_deleter>(reinterpret_cast<char *>(ecalloc( 1, can_loc_range->len + 1)));
+ char *p_cur_loc_range = cur_loc_range.get();
+ result = strToMatch( can_loc_range->val , p_cur_loc_range );
if( result == 0) {
- efree( cur_lang_tag );
- zend_string_release_ex( can_lang_tag, 0 );
- efree( cur_loc_range );
- zend_string_release_ex( can_loc_range, 0 );
+ zend_string_release_ex( can_lang_tag, false );
+ zend_string_release_ex( can_loc_range, false );
RETURN_FALSE;
}
/* check if prefix */
- token = strstr( cur_lang_tag , cur_loc_range );
+ token = strstr( p_cur_lang_tag , p_cur_loc_range );
- if( token && (token==cur_lang_tag) ){
+ if( token && (token==p_cur_lang_tag) ){
/* check if the char. after match is SEPARATOR */
chrcheck = token + can_loc_range->len;
if( isIDSeparator(*chrcheck) || isKeywordSeparator(*chrcheck) || isEndOfTag(*chrcheck) ){
- efree( cur_lang_tag );
- efree( cur_loc_range );
- if( can_lang_tag){
- zend_string_release_ex( can_lang_tag, 0 );
- }
- if( can_loc_range){
- zend_string_release_ex( can_loc_range, 0 );
- }
+ zend_string_release_ex( can_lang_tag, false );
+ zend_string_release_ex( can_loc_range, false );
RETURN_TRUE;
}
}
/* No prefix as loc_range */
- if( cur_lang_tag){
- efree( cur_lang_tag );
- }
- if( cur_loc_range){
- efree( cur_loc_range );
- }
- if( can_lang_tag){
- zend_string_release_ex( can_lang_tag, 0 );
- }
- if( can_loc_range){
- zend_string_release_ex( can_loc_range, 0 );
- }
+ zend_string_release_ex( can_lang_tag, false );
+ zend_string_release_ex( can_loc_range, false );
RETURN_FALSE;
} /* end of if isCanonical */
else{
/* Convert to lower case for case-insensitive comparison */
- cur_lang_tag = reinterpret_cast<char *>(ecalloc(1, lang_tag_len + 1));
+ cur_lang_tag = std::unique_ptr<char, char_deleter>(reinterpret_cast<char *>(ecalloc(1, lang_tag_len + 1)));
+ char *p_cur_lang_tag = cur_lang_tag.get();
- result = strToMatch( lang_tag , cur_lang_tag);
+ result = strToMatch( lang_tag , p_cur_lang_tag);
if( result == 0) {
- efree( cur_lang_tag );
RETURN_FALSE;
}
- cur_loc_range = reinterpret_cast<char *>(ecalloc(1, loc_range_len + 1));
- result = strToMatch( loc_range , cur_loc_range );
+ cur_loc_range = std::unique_ptr<char, char_deleter>(reinterpret_cast<char *>(ecalloc(1, loc_range_len + 1)));
+ char *p_cur_loc_range = cur_loc_range.get();
+ result = strToMatch( loc_range , p_cur_loc_range );
if( result == 0) {
- efree( cur_lang_tag );
- efree( cur_loc_range );
RETURN_FALSE;
}
/* check if prefix */
- token = strstr( cur_lang_tag , cur_loc_range );
+ token = strstr( p_cur_lang_tag , p_cur_loc_range );
- if( token && (token==cur_lang_tag) ){
+ if( token && (token==p_cur_lang_tag) ){
/* check if the char. after match is SEPARATOR */
chrcheck = token + loc_range_len;
if( isIDSeparator(*chrcheck) || isEndOfTag(*chrcheck) ){
- efree( cur_lang_tag );
- efree( cur_loc_range );
RETURN_TRUE;
}
}
/* No prefix as loc_range */
- if( cur_lang_tag){
- efree( cur_lang_tag );
- }
- if( cur_loc_range){
- efree( cur_loc_range );
- }
RETURN_FALSE;
}
@@ -1525,14 +1490,14 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr,
int cur_arr_len = 0;
int result = 0;
- zend_string* lang_tag = NULL;
- zval* ele_value = NULL;
+ zend_string* lang_tag = nullptr;
+ zval* ele_value = nullptr;
- char* cur_loc_range = NULL;
- zend_string* can_loc_range = NULL;
+ char* cur_loc_range = nullptr;
+ zend_string* can_loc_range = nullptr;
zend_off_t saved_pos = 0;
- zend_string* return_value = NULL;
+ zend_string* return_value = nullptr;
char **cur_arr = reinterpret_cast<char **>(ecalloc(zend_hash_num_elements(hash_arr)*2, sizeof(char *)));
ZEND_HASH_FOREACH_VAL(hash_arr, ele_value) {
@@ -1541,19 +1506,19 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr,
if(Z_TYPE_P(ele_value)!= IS_STRING) {
/* element value is not a string */
zend_argument_type_error(2, "must only contain string values");
- LOOKUP_CLEAN_RETURN(NULL);
+ LOOKUP_CLEAN_RETURN(nullptr);
}
if (zend_str_has_nul_byte(Z_STR_P(ele_value))) {
zend_argument_value_error(2, "must not contain any null bytes");
- LOOKUP_CLEAN_RETURN(NULL);
+ LOOKUP_CLEAN_RETURN(nullptr);
}
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, "unable to canonicalize lang_tag");
- LOOKUP_CLEAN_RETURN(NULL);
+ intl_error_set(nullptr, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag");
+ LOOKUP_CLEAN_RETURN(nullptr);
}
cur_arr[i+1] = Z_STRVAL_P(ele_value);
} ZEND_HASH_FOREACH_END(); /* end of for */
@@ -1562,19 +1527,19 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr,
if(canonicalize) {
for(i=0; i<cur_arr_len; i++) {
lang_tag = get_icu_value_internal(cur_arr[i*2], LOC_CANONICALIZE_TAG, &result, 0);
- if(result != 1 || lang_tag == NULL || !lang_tag->val[0]) {
+ if(result != 1 || lang_tag == nullptr || !lang_tag->val[0]) {
if(lang_tag) {
zend_string_release_ex(lang_tag, 0);
}
- intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag");
- LOOKUP_CLEAN_RETURN(NULL);
+ intl_error_set(nullptr, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag");
+ LOOKUP_CLEAN_RETURN(nullptr);
}
cur_arr[i*2] = reinterpret_cast<char *>(erealloc(cur_arr[i*2], lang_tag->len+1));
result = strToMatch(lang_tag->val, cur_arr[i*2]);
zend_string_release_ex(lang_tag, 0);
if(result == 0) {
- intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag");
- LOOKUP_CLEAN_RETURN(NULL);
+ intl_error_set(nullptr, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag");
+ LOOKUP_CLEAN_RETURN(nullptr);
}
}
@@ -1583,13 +1548,13 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr,
if(canonicalize) {
/* Canonicalize the loc_range */
can_loc_range = get_icu_value_internal(loc_range, LOC_CANONICALIZE_TAG, &result , 0);
- if( result != 1 || can_loc_range == NULL || !can_loc_range->val[0]) {
+ if( result != 1 || can_loc_range == nullptr || !can_loc_range->val[0]) {
/* Error */
- intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize loc_range");
+ intl_error_set(nullptr, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize loc_range");
if(can_loc_range) {
zend_string_release_ex(can_loc_range, 0);
}
- LOOKUP_CLEAN_RETURN(NULL);
+ LOOKUP_CLEAN_RETURN(nullptr);
} else {
loc_range = can_loc_range->val;
}
@@ -1603,15 +1568,15 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr,
}
if(result == 0) {
efree(cur_loc_range);
- intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag");
- LOOKUP_CLEAN_RETURN(NULL);
+ intl_error_set(nullptr, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag");
+ LOOKUP_CLEAN_RETURN(nullptr);
}
/* Lookup for the lang_tag match */
saved_pos = strlen(cur_loc_range);
while(saved_pos > 0) {
for(i=0; i< cur_arr_len; i++){
- if(cur_arr[i*2] != NULL && strlen(cur_arr[i*2]) == saved_pos && strncmp(cur_loc_range, cur_arr[i*2], saved_pos) == 0) {
+ if(cur_arr[i*2] != nullptr && strlen(cur_arr[i*2]) == saved_pos && strncmp(cur_loc_range, cur_arr[i*2], saved_pos) == 0) {
/* Match found */
char *str = canonicalize ? cur_arr[i*2] : cur_arr[i*2+1];
return_value = zend_string_init(str, strlen(str), 0);
@@ -1624,7 +1589,7 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr,
/* Match not found */
efree(cur_loc_range);
- LOOKUP_CLEAN_RETURN(NULL);
+ LOOKUP_CLEAN_RETURN(nullptr);
}
/* }}} */
@@ -1637,15 +1602,14 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr,
*/
PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_lookup)
{
- zend_string* fallback_loc_str = NULL;
- char* loc_range = NULL;
+ zend_string* fallback_loc_str = nullptr;
+ char* loc_range = nullptr;
size_t loc_range_len = 0;
- zval* arr = NULL;
- HashTable* hash_arr = NULL;
+ zval* arr = nullptr;
+ HashTable* hash_arr = nullptr;
bool boolCanonical = 0;
- zend_string* result_str = NULL;
-
+ zend_string* result_str = nullptr;
ZEND_PARSE_PARAMETERS_START(2, 4)
Z_PARAM_ARRAY(arr)
@@ -1677,13 +1641,13 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_lookup)
if (EG(exception)) {
RETURN_THROWS();
}
- if (U_FAILURE(intl_error_get_code(NULL))) {
+ if (U_FAILURE(intl_error_get_code(nullptr))) {
if (result_str) {
zend_string_release_ex(result_str, 0);
}
RETURN_NULL();
}
- if(result_str == NULL || ZSTR_VAL(result_str)[0] == '\0') {
+ if(result_str == nullptr || ZSTR_VAL(result_str)[0] == '\0') {
if( fallback_loc_str ) {
result_str = zend_string_copy(fallback_loc_str);
} else {
@@ -1699,7 +1663,7 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(locale_lookup)
U_CFUNC PHP_FUNCTION(locale_accept_from_http)
{
UEnumeration *available;
- char *http_accept = NULL;
+ char *http_accept = nullptr;
size_t http_accept_len;
UErrorCode status = U_ZERO_ERROR;
int len;
@@ -1718,17 +1682,17 @@ U_CFUNC PHP_FUNCTION(locale_accept_from_http)
end = strchr(start, ',');
len = end ? end-start : http_accept_len-(start-http_accept);
if (UNEXPECTED(len > ULOC_FULLNAME_CAPACITY)) {
- intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ intl_error_set( nullptr, U_ILLEGAL_ARGUMENT_ERROR,
"locale string too long");
RETURN_FALSE;
}
if(end) {
start = end+1;
}
- } while(end != NULL);
+ } while(end != nullptr);
}
- available = ures_openAvailableLocales(NULL, &status);
+ available = ures_openAvailableLocales(nullptr, &status);
INTL_CHECK_STATUS(status, "failed to retrieve locale list");
len = uloc_acceptLanguageFromHTTP(resultLocale, INTL_MAX_LOCALE_LEN,
&outResult, http_accept, available, &status);