Fix #53251: bindtextdomain with null dir doesn't return old value

Apparently, users expect `bindtextdomain` and `bind_textdomain_codeset`
with `null` as second argument to work like their C counterparts,
namely to return the previously set value.  Thus, we support that.

Closes GH-6631.
This commit is contained in:
Christoph M. Becker 2021-01-22 13:08:51 +01:00
parent 527bcb1e2e
commit d319098b24
5 changed files with 40 additions and 9 deletions

4
NEWS
View file

@ -2,6 +2,10 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2021, PHP 8.0.3
- Gettext:
. Fixed bug #53251 (bindtextdomain with null dir doesn't return old value).
(cmb)
- Opcache:
. Fixed bug #80634 (write_property handler of internal classes is skipped on
preloaded JITted code). (Dmitry)

View file

@ -163,11 +163,11 @@ PHP_FUNCTION(dcgettext)
/* {{{ Bind to the text domain domain_name, looking for translations in dir. Returns the current domain */
PHP_FUNCTION(bindtextdomain)
{
char *domain, *dir;
char *domain, *dir = NULL;
size_t domain_len, dir_len;
char *retval, dir_name[MAXPATHLEN];
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &domain, &domain_len, &dir, &dir_len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss!", &domain, &domain_len, &dir, &dir_len) == FAILURE) {
RETURN_THROWS();
}
@ -178,6 +178,10 @@ PHP_FUNCTION(bindtextdomain)
RETURN_THROWS();
}
if (dir == NULL) {
RETURN_STRING(bindtextdomain(domain, NULL));
}
if (dir[0] != '\0' && strcmp(dir, "0")) {
if (!VCWD_REALPATH(dir, dir_name)) {
RETURN_FALSE;
@ -272,10 +276,10 @@ PHP_FUNCTION(dcngettext)
/* {{{ Specify the character encoding in which the messages from the DOMAIN message catalog will be returned. */
PHP_FUNCTION(bind_textdomain_codeset)
{
char *domain, *codeset, *retval = NULL;
char *domain, *codeset = NULL, *retval = NULL;
size_t domain_len, codeset_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &domain, &domain_len, &codeset, &codeset_len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss!", &domain, &domain_len, &codeset, &codeset_len) == FAILURE) {
RETURN_THROWS();
}

View file

@ -13,7 +13,7 @@ function dgettext(string $domain, string $message): string {}
function dcgettext(string $domain, string $message, int $category): string {}
function bindtextdomain(string $domain, string $directory): string|false {}
function bindtextdomain(string $domain, ?string $directory): string|false {}
#ifdef HAVE_NGETTEXT
function ngettext(string $singular, string $plural, int $count): string {}
@ -28,5 +28,5 @@ function dcngettext(string $domain, string $singular, string $plural, int $count
#endif
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
function bind_textdomain_codeset(string $domain, string $codeset): string|false {}
function bind_textdomain_codeset(string $domain, ?string $codeset): string|false {}
#endif

View file

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 7d0fe93cb15576756edc5aad71deadae67046690 */
* Stub hash: 3fbd90b87dfcbc5a1a0a2aea8d0cc45516e221ce */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_textdomain, 0, 1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, domain, IS_STRING, 1)
@ -24,7 +24,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_bindtextdomain, 0, 2, MAY_BE_STRING|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, domain, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, directory, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, directory, IS_STRING, 1)
ZEND_END_ARG_INFO()
#if defined(HAVE_NGETTEXT)
@ -57,7 +57,7 @@ ZEND_END_ARG_INFO()
#if defined(HAVE_BIND_TEXTDOMAIN_CODESET)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_bind_textdomain_codeset, 0, 2, MAY_BE_STRING|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, domain, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, codeset, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, codeset, IS_STRING, 1)
ZEND_END_ARG_INFO()
#endif

View file

@ -0,0 +1,23 @@
--TEST--
Bug #53251 (bindtextdomain with null dir doesn't return old value)
--SKIPIF--
<?php
if (!extension_loaded('gettext')) die('skip gettext extension not available');
?>
--FILE--
<?php
var_dump(is_string(bindtextdomain('foo', null)));
$dir = bindtextdomain('foo', '.');
var_dump(bindtextdomain('foo', null) === $dir);
var_dump(bind_textdomain_codeset('foo', null));
var_dump(bind_textdomain_codeset('foo', 'UTF-8'));
var_dump(bind_textdomain_codeset('foo', null));
?>
--EXPECT--
bool(true)
bool(true)
bool(false)
string(5) "UTF-8"
string(5) "UTF-8"