ext/gettext: dcgettext/dcngettext sigabrt on macOs.

the man page states `the locale facet is determined by the category argument,  which  should  be
 one of the LC_xxx constants defined in the <locale.h> header, excluding LC_ALL`,
since the 0.22.5 release, sanity checks had been strenghtened leading to
an abort with the Zend/tests/arginfo_zpp_mismatch.phpt test setting the
category to 0 which is LC_ALL on macOs.

close GH-13555
This commit is contained in:
David Carlier 2024-02-28 22:43:04 +00:00
parent 29a39eb782
commit 9999a0cb75
5 changed files with 40 additions and 2 deletions

4
NEWS
View File

@ -2,6 +2,10 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 8.2.18
- Gettext:
- Fixed sigabrt raised with dcgettext/dcngettext calls with gettext 0.22.5
with category set to LC_ALL. (David Carlier)
- MySQLnd:
. Fix GH-13452 (Fixed handshake response [mysqlnd]). (Saki Takamachi)

View File

@ -218,6 +218,10 @@ PHP 8.2 UPGRADE NOTES
dba_fetch(string|array $key, $skip, $dba): string|false
is still accepted, but it is recommended to use the new standard variant.
- Gettext:
. dcgettext/dcngettext throw now an exception if the category's argument if set to
`LC_ALL`.
- MBString
. mb_check_encoding() now checks input encoding more strictly for
certain text encodings, including ISO-2022-JP and UTF-7.

View File

@ -23,6 +23,7 @@
#ifdef HAVE_LIBINTL
#include <stdio.h>
#include <locale.h>
#include "ext/standard/info.h"
#include "php_gettext.h"
#include "gettext_arginfo.h"
@ -61,6 +62,12 @@ ZEND_GET_MODULE(php_gettext)
RETURN_THROWS(); \
}
#define PHP_DCGETTEXT_CATEGORY_CHECK(_arg_num, category) \
if (category == LC_ALL) { \
zend_argument_value_error(_arg_num, "cannot be LC_ALL"); \
RETURN_THROWS(); \
}
PHP_MINFO_FUNCTION(php_gettext)
{
php_info_print_table_start();
@ -146,6 +153,7 @@ PHP_FUNCTION(dcgettext)
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain))
PHP_GETTEXT_LENGTH_CHECK(2, ZSTR_LEN(msgid))
PHP_DCGETTEXT_CATEGORY_CHECK(3, category)
msgstr = dcgettext(ZSTR_VAL(domain), ZSTR_VAL(msgid), category);
@ -260,6 +268,7 @@ PHP_FUNCTION(dcngettext)
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, domain_len)
PHP_GETTEXT_LENGTH_CHECK(2, msgid1_len)
PHP_GETTEXT_LENGTH_CHECK(3, msgid2_len)
PHP_DCGETTEXT_CATEGORY_CHECK(5, category)
msgstr = dcngettext(domain, msgid1, msgid2, count, category);

View File

@ -0,0 +1,21 @@
--TEST--
dcgettext with LC_ALL is undefined behavior.
--EXTENSIONS--
gettext
--FILE--
<?php
try {
dcgettext('dngettextTest', 'item', LC_ALL);
} catch (ValueError $e) {
echo $e->getMessage() . PHP_EOL;
}
try {
dcngettext('dngettextTest', 'item', 'item2', 1, LC_ALL);
} catch (ValueError $e) {
echo $e->getMessage();
}
?>
--EXPECTF--
dcgettext(): Argument #3 ($category) cannot be LC_ALL
dcngettext(): Argument #5 ($category) cannot be LC_ALL

View File

@ -11,10 +11,10 @@ if (!function_exists("dcngettext")) die("skip dcngettext() doesn't exist");
var_dump(dcngettext(1,1,1,1,1));
var_dump(dcngettext("test","test","test",1,1));
var_dump(dcngettext("test","test","test",0,0));
var_dump(dcngettext("test","test","test",0,1));
var_dump(dcngettext("test","test","test",-1,-1));
var_dump(dcngettext("","","",1,1));
var_dump(dcngettext("","","",0,0));
var_dump(dcngettext("","","",0,1));
echo "Done\n";
?>