Skip to content

Commit

Permalink
ext/gettext/tests: fix libintl return values under musl
Browse files Browse the repository at this point in the history
Musl has two quirks that are leading to failed internationalization
tests. First is that the return value of bindtextdomain(..., NULL)
will always be false, rather than an "implementation-defined default
directory," because musl does not have an implementation-defined
default directory. One test needs a special case for this.

Second is that the musl implementation of bind_textdomain_codeset()
always returns NULL. The POSIX-correctness of this is debatable, but
it is roughly equivalent to correct, because musl only support UTF-8,
so the NULL value indicating that the codeset is unchanged from the
locale's codeset (UTF-8) is accurate.

PHP's bind_textdomain_codeset() function however treats NULL as
failure, unconditionally:

  * php/doc-en#4311
  * php#17163

This unfortunately causes false to be returned consistently on musl --
even when nothing unexpected has happened -- and naturally this is
affecting several tests. For now we change two tests to accept "false"
in addition to "UTF-8" so that they may pass on musl. If PHP's
bind_textdomain_codeset() is updated to differentiate between NULL and
NULL-with-errno-set, these tests can also be updated once again to
reject the NULL-with-errno result.

This partially addresses GH php#13696
  • Loading branch information
orlitzky committed Dec 18, 2024
1 parent 83b700e commit eebd90d
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 11 deletions.
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 or $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 or $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 eebd90d

Please sign in to comment.