diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | ext/standard/string.c | 21 | ||||
-rw-r--r-- | ext/standard/tests/strings/setlocale-win32.phpt | 25 |
3 files changed, 47 insertions, 0 deletions
@@ -27,6 +27,7 @@ PHP NEWS - Standard: . Fixed bug #77135 (Extract with EXTR_SKIP should skip $this). (Craig Duncan, Dmitry) + . Fixed bug ##77937 (preg_match failed). (cmb, Anatol) - Zip: . Fixed bug #76345 (zip.h not found). (Michael Maroszek) diff --git a/ext/standard/string.c b/ext/standard/string.c index ce90848561..2907c2253b 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -4513,7 +4513,28 @@ PHP_FUNCTION(setlocale) } } +# ifndef PHP_WIN32 retval = php_my_setlocale(cat, loc ? ZSTR_VAL(loc) : NULL); +# else + if (loc) { + /* BC: don't try /^[a-z]{2}_[A-Z]{2}($|\..*)/ except for /^u[ks]_U[KS]$/ */ + char *locp = ZSTR_VAL(loc); + if (ZSTR_LEN(loc) >= 5 && locp[2] == '_' + && locp[0] >= 'a' && locp[0] <= 'z' && locp[1] >= 'a' && locp[1] <= 'z' + && locp[3] >= 'A' && locp[3] <= 'Z' && locp[4] >= 'A' && locp[4] <= 'Z' + && (locp[5] == '\0' || locp[5] == '.') + && !(locp[0] == 'u' && (locp[1] == 'k' || locp[1] == 's') + && locp[3] == 'U' && (locp[4] == 'K' || locp[4] == 'S') + && locp[5] == '\0') + ) { + retval = NULL; + } else { + retval = php_my_setlocale(cat, ZSTR_VAL(loc)); + } + } else { + retval = php_my_setlocale(cat, NULL); + } +# endif zend_update_current_locale(); if (retval) { if (loc) { diff --git a/ext/standard/tests/strings/setlocale-win32.phpt b/ext/standard/tests/strings/setlocale-win32.phpt new file mode 100644 index 0000000000..fcfbce3579 --- /dev/null +++ b/ext/standard/tests/strings/setlocale-win32.phpt @@ -0,0 +1,25 @@ +--TEST-- +Unix locale names are rejected on Windows, except for some special cases +--SKIPIF-- +<?php +if (substr(PHP_OS, 0, 3) != 'WIN') die('skip this test is for Windows platforms only'); +?> +--FILE-- +<?php +var_dump(setlocale(LC_ALL, 'de_DE')); +var_dump(setlocale(LC_ALL, 'de_DE.UTF-8')); +// the following are supposed to be accepted +var_dump(setlocale(LC_ALL, 'uk_UK')); +var_dump(setlocale(LC_ALL, 'uk_US')); +var_dump(setlocale(LC_ALL, 'us_UK')); +var_dump(setlocale(LC_ALL, 'us_US')); +?> +===DONE=== +--EXPECT-- +bool(false) +bool(false) +string(27) "English_United Kingdom.1252" +string(26) "English_United States.1252" +string(27) "English_United Kingdom.1252" +string(26) "English_United States.1252" +===DONE=== |