Skip to content

Commit

Permalink
feat: validate default_locale INI value upon setting it
Browse files Browse the repository at this point in the history
  • Loading branch information
ramsey committed Oct 12, 2023
1 parent 18c577c commit 1670424
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 1 deletion.
39 changes: 38 additions & 1 deletion src/php/ecma_intl.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
#include <php_ini.h>
#include <unicode/ucal.h>

static ZEND_INI_MH(onUpdateLocale);

PHP_INI_BEGIN()
PHP_INI_ENTRY(PHP_ECMA_INI_DEFAULT_LOCALE, "", PHP_INI_ALL, NULL)
PHP_INI_ENTRY(PHP_ECMA_INI_DEFAULT_LOCALE, "", PHP_INI_ALL, onUpdateLocale)
PHP_INI_END()

zend_module_entry ecma_intl_module_entry = {STANDARD_MODULE_HEADER,
Expand Down Expand Up @@ -108,3 +110,38 @@ PHP_MINFO_FUNCTION(ecma_intl)

DISPLAY_INI_ENTRIES();
}

static ZEND_INI_MH(onUpdateLocale)
{
zend_result result = FAILURE;

if (!new_value || (new_value && !ZSTR_VAL(new_value)[0])) {
return result;
}

char **available, *bestAvailable, *canonicalized;
size_t total, length;
ecma402_errorStatus *status;

available = (char **)malloc(sizeof(char *) * uloc_countAvailable());
bestAvailable = (char *)malloc(sizeof(char) * ULOC_FULLNAME_CAPACITY);
total = ecma402_intlAvailableLocales(available);

if (ecma402_bestAvailableLocale(available, total, ZSTR_VAL(new_value), bestAvailable, false) > 0) {
status = ecma402_initErrorStatus();
canonicalized = (char *)malloc(sizeof(char) * ULOC_FULLNAME_CAPACITY);
length = ecma402_canonicalizeUnicodeLocaleId(bestAvailable, canonicalized, status);

if (!ecma402_hasError(status) && length > 0) {
result = SUCCESS;
}

free(canonicalized);
ecma402_freeErrorStatus(status);
}

free(bestAvailable);
free(available);

return result;
}
2 changes: 2 additions & 0 deletions tests/phpt/ini-default_locale-005.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ declare(strict_types=1);

var_dump(ini_set('ecma_intl.default_locale', 'en-US'));
var_dump(ini_set('ecma_intl.default_locale', 'en_US'));
var_dump(ini_set('ecma_intl.default_locale', 'foobar'));
var_dump(ini_set('ecma_intl.default_locale', 'en-Latn-US'));
var_dump(ini_set('ecma_intl.default_locale', 'en-US-POSIX'));
var_dump(ini_set('ecma_intl.default_locale', 'en_US_POSIX'));
Expand All @@ -19,6 +20,7 @@ var_dump(ini_get('ecma_intl.default_locale'));
--EXPECT--
string(0) ""
string(5) "en-US"
bool(false)
string(5) "en_US"
string(10) "en-Latn-US"
string(11) "en-US-POSIX"
Expand Down
14 changes: 14 additions & 0 deletions tests/phpt/ini-default_locale-006.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
ecma_intl.default_locale has an empty string when set to an invalid value
--EXTENSIONS--
ecma_intl
--INI--
ecma_intl.default_locale=foobar
--FILE--
<?php
declare(strict_types=1);

var_dump(ini_get('ecma_intl.default_locale'));

--EXPECT--
string(0) ""

0 comments on commit 1670424

Please sign in to comment.