From 183f51d8448fcff07903fe5db5633a6123ae1209 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 28 Feb 2024 22:43:04 +0000 Subject: [PATCH] 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 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. --- ext/gettext/gettext.c | 9 +++++++++ ext/gettext/tests/dcgettext_lcall.phpt | 21 +++++++++++++++++++++ ext/gettext/tests/dcngettext.phpt | 4 ++-- 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 ext/gettext/tests/dcgettext_lcall.phpt diff --git a/ext/gettext/gettext.c b/ext/gettext/gettext.c index 05f41552c63fc..e7928795b279d 100644 --- a/ext/gettext/gettext.c +++ b/ext/gettext/gettext.c @@ -23,6 +23,7 @@ #ifdef HAVE_LIBINTL #include +#include #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); diff --git a/ext/gettext/tests/dcgettext_lcall.phpt b/ext/gettext/tests/dcgettext_lcall.phpt new file mode 100644 index 0000000000000..004ae89409eca --- /dev/null +++ b/ext/gettext/tests/dcgettext_lcall.phpt @@ -0,0 +1,21 @@ +--TEST-- +dcgettext with LC_ALL is undefined behavior. +--EXTENSIONS-- +gettext +--FILE-- +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 diff --git a/ext/gettext/tests/dcngettext.phpt b/ext/gettext/tests/dcngettext.phpt index 715281ec8296b..2f356b1cf0c6a 100644 --- a/ext/gettext/tests/dcngettext.phpt +++ b/ext/gettext/tests/dcngettext.phpt @@ -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"; ?>