diff --git a/.gitignore b/.gitignore index d54334f599a..52dde98ed43 100644 --- a/.gitignore +++ b/.gitignore @@ -177,6 +177,9 @@ php /ext/*/configure.ac /ext/*/run-tests.php +# Generated by ./configure if libc might be musl +/ext/gettext/tests/locale/en_US + # ------------------------------------------------------------------------------ # Generated by Windows build system # ------------------------------------------------------------------------------ diff --git a/NEWS b/NEWS index 83a3337c652..b146ee5eb5e 100644 --- a/NEWS +++ b/NEWS @@ -44,6 +44,10 @@ PHP NEWS . Fixed bug GH-16255 (Unexpected nan value in ext/gd/libgd/gd_filter.c). (nielsdos, cmb) +- Gettext: + . Fixed bug GH-17202 (Segmentation fault ext/gettext/gettext.c + bindtextdomain()). (Michael Orlitzky) + - Iconv: . Fixed bug GH-17047 (UAF on iconv filter failure). (nielsdos) diff --git a/ext/gettext/config.m4 b/ext/gettext/config.m4 index e46acf09285..ae3eaf38761 100644 --- a/ext/gettext/config.m4 +++ b/ext/gettext/config.m4 @@ -23,6 +23,18 @@ if test "$PHP_GETTEXT" != "no"; then [AC_CHECK_LIB([c], [bindtextdomain], [ GETTEXT_LIBS= GETTEXT_CHECK_IN_LIB=c + + dnl If libintl.h is provided by libc, it's possible that libc is musl. + dnl The gettext family of functions under musl ignores the codeset + dnl suffix on directories like "en_US.UTF-8"; instead they look only + dnl in "en_US". To accomodate that, we symlink some test data from one + dnl to the other. + AC_MSG_NOTICE([symlinking en_US.UTF-8 messages to en_US in case you are on musl]) + _linkdest="${srcdir%/}"/ext/gettext/tests/locale/en_US + AS_IF([test ! -e "${_linkdest}"],[ + ln -s en_US.UTF-8 "${_linkdest}" + ]) + ], [AC_MSG_FAILURE([Unable to find required intl library for gettext.])])]) diff --git a/ext/gettext/gettext.c b/ext/gettext/gettext.c index ebf9bd76718..53eaf797545 100644 --- a/ext/gettext/gettext.c +++ b/ext/gettext/gettext.c @@ -180,7 +180,7 @@ PHP_FUNCTION(dcgettext) PHP_FUNCTION(bindtextdomain) { zend_string *domain, *dir = NULL; - char *retval, dir_name[MAXPATHLEN]; + char *retval, dir_name[MAXPATHLEN], *btd_result; ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR(domain) @@ -191,7 +191,16 @@ PHP_FUNCTION(bindtextdomain) PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain)) if (dir == NULL) { - RETURN_STRING(bindtextdomain(ZSTR_VAL(domain), NULL)); + btd_result = bindtextdomain(ZSTR_VAL(domain), NULL); + if (btd_result == NULL) { + /* POSIX-compliant implementations can return + * NULL if an error occured. On musl you will + * also get NULL if the domain is not yet + * bound, because musl has no default directory + * to return in that case. */ + RETURN_FALSE; + } + RETURN_STRING(btd_result); } if (ZSTR_LEN(dir) != 0 && !zend_string_equals_literal(dir, "0")) { diff --git a/ext/gettext/tests/bug53251.phpt b/ext/gettext/tests/bug53251.phpt index 6f37642925d..d568be6bc07 100644 --- a/ext/gettext/tests/bug53251.phpt +++ b/ext/gettext/tests/bug53251.phpt @@ -8,18 +8,28 @@ if (getenv('SKIP_REPEAT')) die('skip gettext leaks global state across requests' ?> --FILE-- --EXPECT-- bool(true) -bool(true) -bool(false) -string(5) "UTF-8" -string(5) "UTF-8" diff --git a/ext/gettext/tests/gettext_bind_textdomain_codeset-retval.phpt b/ext/gettext/tests/gettext_bind_textdomain_codeset-retval.phpt index cd07db1a942..44957ad8d70 100644 --- a/ext/gettext/tests/gettext_bind_textdomain_codeset-retval.phpt +++ b/ext/gettext/tests/gettext_bind_textdomain_codeset-retval.phpt @@ -15,14 +15,22 @@ gettext } catch (ValueError $e) { echo $e->getMessage() . PHP_EOL; } - var_dump(bind_textdomain_codeset('messages', "UTF-8")); + + // bind_textdomain_codeset() always returns false on musl + // because musl only supports UTF-8. For more information: + // + // * https://github.com/php/doc-en/issues/4311, + // * https://github.com/php/php-src/issues/17163 + // + $result = bind_textdomain_codeset('messages', "UTF-8"); + var_dump($result === false || $result === "UTF-8"); echo "Done\n"; ?> --EXPECT-- bind_textdomain_codeset(): Argument #1 ($domain) must not be empty bind_textdomain_codeset(): Argument #1 ($domain) must not be empty -string(5) "UTF-8" +bool(true) Done --CREDITS-- Florian Holzhauer fh-pt@fholzhauer.de