diff --git a/runtime-light/stdlib/string/string-functions.h b/runtime-light/stdlib/string/string-functions.h index aa6b147dde..38e13702d7 100644 --- a/runtime-light/stdlib/string/string-functions.h +++ b/runtime-light/stdlib/string/string-functions.h @@ -17,12 +17,12 @@ inline string f$prepare_search_query(const string& query) noexcept { inline Optional f$setlocale(int64_t category, const string& locale) noexcept { const int32_t i32category{static_cast(category)}; - if (k2::uselocale(i32category, {locale.c_str(), locale.size()}) != k2::errno_ok) { + if (const std::string_view sv_locale{locale.c_str(), locale.size()}; sv_locale != "0" && k2::uselocale(i32category, sv_locale) != k2::errno_ok) { return false; } const auto opt_locale_name{k2::current_locale_name(i32category)}; if (!opt_locale_name.has_value()) [[unlikely]] { return false; } - return opt_locale_name->data(); + return string{opt_locale_name->data(), static_cast(opt_locale_name->size())}; } diff --git a/tests/phpt/dl/1048_setlocale.php b/tests/phpt/dl/1048_setlocale.php new file mode 100644 index 0000000000..8d55e989f4 --- /dev/null +++ b/tests/phpt/dl/1048_setlocale.php @@ -0,0 +1,94 @@ +@ok + " . setlocale(LC_CTYPE, "0")); + var_dump("LC_NUMERIC 0 -> " . setlocale(LC_NUMERIC, "0")); + var_dump("LC_TIME 0 -> " . setlocale(LC_TIME, "0")); + var_dump("LC_COLLATE 0 -> " . setlocale(LC_COLLATE, "0")); + var_dump("LC_MONETARY 0 -> " . setlocale(LC_MONETARY, "0")); + var_dump("LC_ALL 0 -> " . setlocale(LC_ALL, "0")); +} + +function setlocale_return_empty() { + var_dump("setlocale_empty"); + + var_dump("LC_CTYPE \"\" -> " . setlocale(LC_CTYPE, "")); + var_dump("LC_NUMERIC \"\" -> " . setlocale(LC_NUMERIC, "")); + var_dump("LC_TIME \"\" -> " . setlocale(LC_TIME, "")); + var_dump("LC_COLLATE \"\" -> " . setlocale(LC_COLLATE, "")); + var_dump("LC_MONETARY \"\" -> " . setlocale(LC_MONETARY, "")); + var_dump("LC_ALL \"\" -> " . setlocale(LC_ALL, "")); + + var_dump("check other (1)"); + setlocale_zero(); +} + +function setlocale_return_set_ru_RU_CP1251() { + var_dump("setlocale_set_ru_RU_CP1251"); + + var_dump("LC_ALL \"\" -> " . setlocale(LC_ALL, "")); // unset all + + var_dump("LC_CTYPE ru_RU.CP1251 -> " . setlocale(LC_CTYPE, "ru_RU.CP1251")); + var_dump("LC_CTYPE 0 -> " . setlocale(LC_CTYPE, "0")); + + var_dump("LC_NUMERIC ru_RU.CP1251 -> " . setlocale(LC_NUMERIC, "ru_RU.CP1251")); + var_dump("LC_NUMERIC 0 -> " . setlocale(LC_NUMERIC, "0")); + + var_dump("LC_TIME ru_RU.CP1251 -> " . setlocale(LC_TIME, "ru_RU.CP1251")); + var_dump("LC_TIME 0 -> " . setlocale(LC_TIME, "0")); + + var_dump("LC_COLLATE ru_RU.CP1251 -> " . setlocale(LC_COLLATE, "ru_RU.CP1251")); + var_dump("LC_COLLATE 0 -> " . setlocale(LC_COLLATE, "0")); + + var_dump("LC_MONETARY ru_RU.CP1251 -> " . setlocale(LC_MONETARY, "ru_RU.CP1251")); + var_dump("LC_MONETARY 0 -> " . setlocale(LC_MONETARY, "0")); + + var_dump("LC_ALL 0 -> " . setlocale(LC_ALL, "0")); + + var_dump("LC_ALL \"\" -> " . setlocale(LC_ALL, "")); // unset all + + var_dump("check other (2)"); + setlocale_zero(); + + var_dump("LC_ALL ru_RU.CP1251 -> " . setlocale(LC_ALL, "ru_RU.CP1251")); + + var_dump("check other (3)"); + setlocale_zero(); + + var_dump("LC_ALL \"\" -> " . setlocale(LC_ALL, "")); // unset all +} + +function setlocale_return_correct_LC_ALL_changes() { + var_dump("setlocale_correct_LC_ALL_changes"); + + var_dump("LC_ALL en_US.UTF-8 -> " . setlocale(LC_ALL, "en_US.UTF-8")); + var_dump("LC_ALL 0 -> " . setlocale(LC_ALL, "0")); + + var_dump("LC_COLLATE ru_RU.CP1251 -> " . setlocale(LC_COLLATE, "ru_RU.CP1251")); + var_dump("LC_ALL 0 -> " . setlocale(LC_ALL, "0")); + + var_dump("LC_COLLATE en_US.UTF-8 -> " . setlocale(LC_COLLATE, "en_US.UTF-8")); + var_dump("LC_ALL 0 -> " . setlocale(LC_ALL, "0")); +} + + +function setlocale_numeric_cp1251() { + function printf_numeric() { + printf("%.2f\n", 1234.56); + } + + var_dump("setlocale_numeric_cp1251"); + setlocale(LC_NUMERIC, 'ru_RU.CP1251'); + printf_numeric(); + setlocale(LC_NUMERIC, 'C'); + printf_numeric(); +} + + +setlocale_return_empty(); +setlocale_return_set_ru_RU_CP1251(); +setlocale_return_correct_LC_ALL_changes(); +setlocale_numeric_cp1251();