Skip to content

Commit

Permalink
Merge branch 'PHP-8.4'
Browse files Browse the repository at this point in the history
* PHP-8.4:
  NEWS for phpGH-17168
  ext/gettext/config.m4: symlink en_US.UTF-8 test bits to en_US for musl
  ext/gettext/tests: fix libintl return values under musl
  ext/gettext/gettext.c: handle NULLs from bindtextdomain()
  • Loading branch information
arnaud-lb committed Dec 19, 2024
2 parents 6a01549 + 73857e6 commit 4b1c3cf
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 13 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
# ------------------------------------------------------------------------------
Expand Down
12 changes: 12 additions & 0 deletions ext/gettext/config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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.])])])

Expand Down
13 changes: 11 additions & 2 deletions ext/gettext/gettext.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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")) {
Expand Down
28 changes: 19 additions & 9 deletions ext/gettext/tests/bug53251.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,28 @@ if (getenv('SKIP_REPEAT')) die('skip gettext leaks global state across requests'
?>
--FILE--
<?php
var_dump(is_string(bindtextdomain('foo', null)));
$results[] = is_string(bindtextdomain('foo', null));
$dir = bindtextdomain('foo', '.');
var_dump(bindtextdomain('foo', null) === $dir);
$results[] = bindtextdomain('foo', null) === $dir;
$results[] = bind_textdomain_codeset('foo', null);
$results[] = bind_textdomain_codeset('foo', 'UTF-8');
$results[] = bind_textdomain_codeset('foo', null);

var_dump(bind_textdomain_codeset('foo', null));
var_dump(bind_textdomain_codeset('foo', 'UTF-8'));
var_dump(bind_textdomain_codeset('foo', null));
$expected = [true, true, false, "UTF-8", "UTF-8"];

// musl's bindtextdomain() has no default directory to return when
// "foo" is unbound, so in the first call, you will get false instead
// of a string.
//
// 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
//
$expected_musl = [false, true, false, false, false];

var_dump($results === $expected || $results === $expected_musl);
?>
--EXPECT--
bool(true)
bool(true)
bool(false)
string(5) "UTF-8"
string(5) "UTF-8"
12 changes: 10 additions & 2 deletions ext/gettext/tests/gettext_bind_textdomain_codeset-retval.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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 [email protected]
Expand Down

0 comments on commit 4b1c3cf

Please sign in to comment.