Skip to content

Commit 9999a0c

Browse files
committed
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 phpGH-13555
1 parent 29a39eb commit 9999a0c

File tree

5 files changed

+40
-2
lines changed

5 files changed

+40
-2
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.2.18
44

5+
- Gettext:
6+
- Fixed sigabrt raised with dcgettext/dcngettext calls with gettext 0.22.5
7+
with category set to LC_ALL. (David Carlier)
8+
59
- MySQLnd:
610
. Fix GH-13452 (Fixed handshake response [mysqlnd]). (Saki Takamachi)
711

UPGRADING

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@ PHP 8.2 UPGRADE NOTES
218218
dba_fetch(string|array $key, $skip, $dba): string|false
219219
is still accepted, but it is recommended to use the new standard variant.
220220

221+
- Gettext:
222+
. dcgettext/dcngettext throw now an exception if the category's argument if set to
223+
`LC_ALL`.
224+
221225
- MBString
222226
. mb_check_encoding() now checks input encoding more strictly for
223227
certain text encodings, including ISO-2022-JP and UTF-7.

ext/gettext/gettext.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#ifdef HAVE_LIBINTL
2424

2525
#include <stdio.h>
26+
#include <locale.h>
2627
#include "ext/standard/info.h"
2728
#include "php_gettext.h"
2829
#include "gettext_arginfo.h"
@@ -61,6 +62,12 @@ ZEND_GET_MODULE(php_gettext)
6162
RETURN_THROWS(); \
6263
}
6364

65+
#define PHP_DCGETTEXT_CATEGORY_CHECK(_arg_num, category) \
66+
if (category == LC_ALL) { \
67+
zend_argument_value_error(_arg_num, "cannot be LC_ALL"); \
68+
RETURN_THROWS(); \
69+
}
70+
6471
PHP_MINFO_FUNCTION(php_gettext)
6572
{
6673
php_info_print_table_start();
@@ -146,6 +153,7 @@ PHP_FUNCTION(dcgettext)
146153

147154
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain))
148155
PHP_GETTEXT_LENGTH_CHECK(2, ZSTR_LEN(msgid))
156+
PHP_DCGETTEXT_CATEGORY_CHECK(3, category)
149157

150158
msgstr = dcgettext(ZSTR_VAL(domain), ZSTR_VAL(msgid), category);
151159

@@ -260,6 +268,7 @@ PHP_FUNCTION(dcngettext)
260268
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, domain_len)
261269
PHP_GETTEXT_LENGTH_CHECK(2, msgid1_len)
262270
PHP_GETTEXT_LENGTH_CHECK(3, msgid2_len)
271+
PHP_DCGETTEXT_CATEGORY_CHECK(5, category)
263272

264273
msgstr = dcngettext(domain, msgid1, msgid2, count, category);
265274

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
dcgettext with LC_ALL is undefined behavior.
3+
--EXTENSIONS--
4+
gettext
5+
--FILE--
6+
<?php
7+
try {
8+
dcgettext('dngettextTest', 'item', LC_ALL);
9+
} catch (ValueError $e) {
10+
echo $e->getMessage() . PHP_EOL;
11+
}
12+
13+
try {
14+
dcngettext('dngettextTest', 'item', 'item2', 1, LC_ALL);
15+
} catch (ValueError $e) {
16+
echo $e->getMessage();
17+
}
18+
?>
19+
--EXPECTF--
20+
dcgettext(): Argument #3 ($category) cannot be LC_ALL
21+
dcngettext(): Argument #5 ($category) cannot be LC_ALL

ext/gettext/tests/dcngettext.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ if (!function_exists("dcngettext")) die("skip dcngettext() doesn't exist");
1111

1212
var_dump(dcngettext(1,1,1,1,1));
1313
var_dump(dcngettext("test","test","test",1,1));
14-
var_dump(dcngettext("test","test","test",0,0));
14+
var_dump(dcngettext("test","test","test",0,1));
1515
var_dump(dcngettext("test","test","test",-1,-1));
1616
var_dump(dcngettext("","","",1,1));
17-
var_dump(dcngettext("","","",0,0));
17+
var_dump(dcngettext("","","",0,1));
1818

1919
echo "Done\n";
2020
?>

0 commit comments

Comments
 (0)