Skip to content

Commit 2e66c35

Browse files
committed
Detect broken setlocale on musl
1 parent 8358827 commit 2e66c35

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

ext/standard/config.m4

+18
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,24 @@ if test "$ac_cv_strptime_decl_fails" = "yes"; then
368368
AC_DEFINE([HAVE_STRPTIME_DECL_FAILS], 1, [whether strptime() declaration fails])
369369
fi
370370

371+
dnl musl has a badly broken setlocale() implementation that always reports success.
372+
AC_CACHE_CHECK([whether setlocale() is broken], ac_cv_setlocale_broken, [
373+
AC_RUN_IFELSE([AC_LANG_SOURCE([[
374+
#include <locale.h>
375+
int main() {
376+
return setlocale(LC_CTYPE, "This locale certainly does not exist") == NULL;
377+
}
378+
]])],[
379+
ac_cv_setlocale_broken=yes
380+
],[
381+
ac_cv_setlocale_broken=no
382+
],[
383+
ac_cv_setlocale_broken=no
384+
])])
385+
if test "$ac_cv_setlocale_broken" = "yes"; then
386+
AC_DEFINE([HAVE_BROKEN_SETLOCALE], 1, [whether setlocale() is broken])
387+
fi
388+
371389
dnl
372390
dnl Check for arc4random on BSD systems
373391
dnl

ext/standard/string.c

+9
Original file line numberDiff line numberDiff line change
@@ -4662,6 +4662,15 @@ PHP_FUNCTION(setlocale)
46624662

46634663
# ifndef PHP_WIN32
46644664
retval = php_my_setlocale(cat, loc ? ZSTR_VAL(loc) : NULL);
4665+
# if HAVE_BROKEN_SETLOCALE
4666+
/* musl libc always reports success for setlocale().
4667+
* Manually whitelist the allowed locales "", "C" and "C.UTF-8" instead. */
4668+
if (retval && loc && ZSTR_LEN(loc) != 0
4669+
&& !zend_string_equals_literal(loc, "C")
4670+
&& !zend_string_equals_literal(loc, "C.UTF-8")) {
4671+
retval = NULL;
4672+
}
4673+
# endif
46654674
# else
46664675
if (loc) {
46674676
/* BC: don't try /^[a-z]{2}_[A-Z]{2}($|\..*)/ except for /^u[ks]_U[KS]$/ */

0 commit comments

Comments
 (0)