Skip to content

Commit 5823a96

Browse files
committed
ext/gettext: update arguments handling.
using zend_string whenever relevant too. Close GH-13582.
1 parent 782af7a commit 5823a96

File tree

4 files changed

+99
-68
lines changed

4 files changed

+99
-68
lines changed

ext/gettext/gettext.c

Lines changed: 82 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,20 @@ PHP_MINFO_FUNCTION(php_gettext)
8181
/* {{{ Set the textdomain to "domain". Returns the current domain */
8282
PHP_FUNCTION(textdomain)
8383
{
84-
char *domain_name = NULL, *retval;
84+
char *domain_name = NULL, *retval = NULL;
8585
zend_string *domain = NULL;
8686

87-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S!", &domain) == FAILURE) {
88-
RETURN_THROWS();
89-
}
87+
ZEND_PARSE_PARAMETERS_START(0, 1)
88+
Z_PARAM_OPTIONAL
89+
Z_PARAM_STR_OR_NULL(domain)
90+
ZEND_PARSE_PARAMETERS_END();
9091

9192
if (domain != NULL) {
9293
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain))
93-
}
94-
95-
if (domain != NULL && !zend_string_equals_literal(domain, "0")) {
94+
if (zend_string_equals_literal(domain, "0")) {
95+
zend_argument_value_error(1, "cannot be zero");
96+
RETURN_THROWS();
97+
}
9698
domain_name = ZSTR_VAL(domain);
9799
}
98100

@@ -105,7 +107,7 @@ PHP_FUNCTION(textdomain)
105107
/* {{{ Return the translation of msgid for the current domain, or msgid unaltered if a translation does not exist */
106108
PHP_FUNCTION(gettext)
107109
{
108-
char *msgstr;
110+
char *msgstr = NULL;
109111
zend_string *msgid;
110112

111113
ZEND_PARSE_PARAMETERS_START(1, 1)
@@ -126,12 +128,13 @@ PHP_FUNCTION(gettext)
126128
/* {{{ Return the translation of msgid for domain_name, or msgid unaltered if a translation does not exist */
127129
PHP_FUNCTION(dgettext)
128130
{
129-
char *msgstr;
131+
char *msgstr = NULL;
130132
zend_string *domain, *msgid;
131133

132-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &domain, &msgid) == FAILURE) {
133-
RETURN_THROWS();
134-
}
134+
ZEND_PARSE_PARAMETERS_START(2, 2)
135+
Z_PARAM_STR(domain)
136+
Z_PARAM_STR(msgid)
137+
ZEND_PARSE_PARAMETERS_END();
135138

136139
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain))
137140
PHP_GETTEXT_LENGTH_CHECK(2, ZSTR_LEN(msgid))
@@ -149,13 +152,15 @@ PHP_FUNCTION(dgettext)
149152
/* {{{ Return the translation of msgid for domain_name and category, or msgid unaltered if a translation does not exist */
150153
PHP_FUNCTION(dcgettext)
151154
{
152-
char *msgstr;
155+
char *msgstr = NULL;
153156
zend_string *domain, *msgid;
154157
zend_long category;
155158

156-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SSl", &domain, &msgid, &category) == FAILURE) {
157-
RETURN_THROWS();
158-
}
159+
ZEND_PARSE_PARAMETERS_START(3, 3)
160+
Z_PARAM_STR(domain)
161+
Z_PARAM_STR(msgid)
162+
Z_PARAM_LONG(category)
163+
ZEND_PARSE_PARAMETERS_END();
159164

160165
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain))
161166
PHP_GETTEXT_LENGTH_CHECK(2, ZSTR_LEN(msgid))
@@ -174,19 +179,24 @@ PHP_FUNCTION(dcgettext)
174179
/* {{{ Bind to the text domain domain_name, looking for translations in dir. Returns the current domain */
175180
PHP_FUNCTION(bindtextdomain)
176181
{
177-
char *domain;
178-
size_t domain_len;
179-
zend_string *dir = NULL;
182+
zend_string *domain, *dir = NULL;
180183
char *retval, dir_name[MAXPATHLEN];
181184

182-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sS!", &domain, &domain_len, &dir) == FAILURE) {
185+
ZEND_PARSE_PARAMETERS_START(1, 2)
186+
Z_PARAM_STR(domain)
187+
Z_PARAM_OPTIONAL
188+
Z_PARAM_STR_OR_NULL(dir)
189+
ZEND_PARSE_PARAMETERS_END();
190+
191+
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain))
192+
193+
if (!ZSTR_LEN(domain)) {
194+
zend_argument_value_error(1, "cannot be empty");
183195
RETURN_THROWS();
184196
}
185197

186-
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, domain_len)
187-
188198
if (dir == NULL) {
189-
RETURN_STRING(bindtextdomain(domain, NULL));
199+
RETURN_STRING(bindtextdomain(ZSTR_VAL(domain), NULL));
190200
}
191201

192202
if (ZSTR_LEN(dir) != 0 && !zend_string_equals_literal(dir, "0")) {
@@ -197,7 +207,7 @@ PHP_FUNCTION(bindtextdomain)
197207
RETURN_FALSE;
198208
}
199209

200-
retval = bindtextdomain(domain, dir_name);
210+
retval = bindtextdomain(ZSTR_VAL(domain), dir_name);
201211

202212
RETURN_STRING(retval);
203213
}
@@ -207,18 +217,20 @@ PHP_FUNCTION(bindtextdomain)
207217
/* {{{ Plural version of gettext() */
208218
PHP_FUNCTION(ngettext)
209219
{
210-
char *msgid1, *msgid2, *msgstr;
211-
size_t msgid1_len, msgid2_len;
220+
char *msgstr = NULL;
221+
zend_string *msgid1, *msgid2;
212222
zend_long count;
213223

214-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssl", &msgid1, &msgid1_len, &msgid2, &msgid2_len, &count) == FAILURE) {
215-
RETURN_THROWS();
216-
}
224+
ZEND_PARSE_PARAMETERS_START(3, 3)
225+
Z_PARAM_STR(msgid1)
226+
Z_PARAM_STR(msgid2)
227+
Z_PARAM_LONG(count)
228+
ZEND_PARSE_PARAMETERS_END();
217229

218-
PHP_GETTEXT_LENGTH_CHECK(1, msgid1_len)
219-
PHP_GETTEXT_LENGTH_CHECK(2, msgid2_len)
230+
PHP_GETTEXT_LENGTH_CHECK(1, ZSTR_LEN(msgid1))
231+
PHP_GETTEXT_LENGTH_CHECK(2, ZSTR_LEN(msgid2))
220232

221-
msgstr = ngettext(msgid1, msgid2, count);
233+
msgstr = ngettext(ZSTR_VAL(msgid1), ZSTR_VAL(msgid2), count);
222234

223235
ZEND_ASSERT(msgstr);
224236
RETURN_STRING(msgstr);
@@ -230,20 +242,22 @@ PHP_FUNCTION(ngettext)
230242
/* {{{ Plural version of dgettext() */
231243
PHP_FUNCTION(dngettext)
232244
{
233-
char *domain, *msgid1, *msgid2, *msgstr = NULL;
234-
size_t domain_len, msgid1_len, msgid2_len;
245+
char *msgstr = NULL;
246+
zend_string *domain, *msgid1, *msgid2;
235247
zend_long count;
236248

237-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sssl", &domain, &domain_len,
238-
&msgid1, &msgid1_len, &msgid2, &msgid2_len, &count) == FAILURE) {
239-
RETURN_THROWS();
240-
}
249+
ZEND_PARSE_PARAMETERS_START(4, 4)
250+
Z_PARAM_STR(domain)
251+
Z_PARAM_STR(msgid1)
252+
Z_PARAM_STR(msgid2)
253+
Z_PARAM_LONG(count)
254+
ZEND_PARSE_PARAMETERS_END();
241255

242-
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, domain_len)
243-
PHP_GETTEXT_LENGTH_CHECK(2, msgid1_len)
244-
PHP_GETTEXT_LENGTH_CHECK(3, msgid2_len)
256+
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain))
257+
PHP_GETTEXT_LENGTH_CHECK(2, ZSTR_LEN(msgid1))
258+
PHP_GETTEXT_LENGTH_CHECK(3, ZSTR_LEN(msgid2))
245259

246-
msgstr = dngettext(domain, msgid1, msgid2, count);
260+
msgstr = dngettext(ZSTR_VAL(domain), ZSTR_VAL(msgid1), ZSTR_VAL(msgid2), count);
247261

248262
ZEND_ASSERT(msgstr);
249263
RETURN_STRING(msgstr);
@@ -255,23 +269,26 @@ PHP_FUNCTION(dngettext)
255269
/* {{{ Plural version of dcgettext() */
256270
PHP_FUNCTION(dcngettext)
257271
{
258-
char *domain, *msgid1, *msgid2, *msgstr = NULL;
259-
size_t domain_len, msgid1_len, msgid2_len;
272+
char *msgstr = NULL;
273+
zend_string *domain, *msgid1, *msgid2;
260274
zend_long count, category;
261275

262276
RETVAL_FALSE;
263277

264-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sssll", &domain, &domain_len,
265-
&msgid1, &msgid1_len, &msgid2, &msgid2_len, &count, &category) == FAILURE) {
266-
RETURN_THROWS();
267-
}
278+
ZEND_PARSE_PARAMETERS_START(5, 5)
279+
Z_PARAM_STR(domain)
280+
Z_PARAM_STR(msgid1)
281+
Z_PARAM_STR(msgid2)
282+
Z_PARAM_LONG(count)
283+
Z_PARAM_LONG(category)
284+
ZEND_PARSE_PARAMETERS_END();
268285

269-
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, domain_len)
270-
PHP_GETTEXT_LENGTH_CHECK(2, msgid1_len)
271-
PHP_GETTEXT_LENGTH_CHECK(3, msgid2_len)
286+
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain))
287+
PHP_GETTEXT_LENGTH_CHECK(2, ZSTR_LEN(msgid1))
288+
PHP_GETTEXT_LENGTH_CHECK(3, ZSTR_LEN(msgid2))
272289
PHP_DCGETTEXT_CATEGORY_CHECK(5, category)
273290

274-
msgstr = dcngettext(domain, msgid1, msgid2, count, category);
291+
msgstr = dcngettext(ZSTR_VAL(domain), ZSTR_VAL(msgid1), ZSTR_VAL(msgid2), count, category);
275292

276293
ZEND_ASSERT(msgstr);
277294
RETURN_STRING(msgstr);
@@ -284,16 +301,23 @@ PHP_FUNCTION(dcngettext)
284301
/* {{{ Specify the character encoding in which the messages from the DOMAIN message catalog will be returned. */
285302
PHP_FUNCTION(bind_textdomain_codeset)
286303
{
287-
char *domain, *codeset = NULL, *retval = NULL;
288-
size_t domain_len, codeset_len;
304+
char *retval = NULL;
305+
zend_string *domain, *codeset = NULL;
306+
307+
ZEND_PARSE_PARAMETERS_START(1, 2)
308+
Z_PARAM_STR(domain)
309+
Z_PARAM_OPTIONAL
310+
Z_PARAM_STR_OR_NULL(codeset)
311+
ZEND_PARSE_PARAMETERS_END();
312+
313+
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, ZSTR_LEN(domain))
289314

290-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss!", &domain, &domain_len, &codeset, &codeset_len) == FAILURE) {
315+
if (!ZSTR_LEN(domain)) {
316+
zend_argument_value_error(1, "cannot be empty");
291317
RETURN_THROWS();
292318
}
293319

294-
PHP_GETTEXT_DOMAIN_LENGTH_CHECK(1, domain_len)
295-
296-
retval = bind_textdomain_codeset(domain, codeset);
320+
retval = bind_textdomain_codeset(ZSTR_VAL(domain), codeset ? ZSTR_VAL(codeset) : NULL);
297321

298322
if (!retval) {
299323
RETURN_FALSE;

ext/gettext/gettext.stub.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/** @generate-class-entries */
44

55
/** @refcount 1 */
6-
function textdomain(?string $domain): string {}
6+
function textdomain(?string $domain = null): string {}
77

88
/** @refcount 1 */
99
function gettext(string $message): string {}
@@ -18,7 +18,7 @@ function dgettext(string $domain, string $message): string {}
1818
function dcgettext(string $domain, string $message, int $category): string {}
1919

2020
/** @refcount 1 */
21-
function bindtextdomain(string $domain, ?string $directory): string|false {}
21+
function bindtextdomain(string $domain, ?string $directory = null): string|false {}
2222

2323
#ifdef HAVE_NGETTEXT
2424
/** @refcount 1 */
@@ -37,5 +37,5 @@ function dcngettext(string $domain, string $singular, string $plural, int $count
3737

3838
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
3939
/** @refcount 1 */
40-
function bind_textdomain_codeset(string $domain, ?string $codeset): string|false {}
40+
function bind_textdomain_codeset(string $domain, ?string $codeset = null): string|false {}
4141
#endif

ext/gettext/gettext_arginfo.h

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/gettext/tests/gettext_textdomain-retval.phpt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ echo textdomain('test'), "\n";
1919
echo textdomain(null), "\n";
2020
echo textdomain('foo'), "\n";
2121

22+
try {
23+
textdomain('0');
24+
} catch (\ValueError $e) {
25+
echo $e->getMessage() . PHP_EOL;
26+
}
27+
2228
try {
2329
textdomain('');
2430
} catch (\ValueError $e) {
@@ -29,6 +35,7 @@ try {
2935
test
3036
test
3137
foo
38+
textdomain(): Argument #1 ($domain) cannot be zero
3239
textdomain(): Argument #1 ($domain) cannot be empty
3340
--CREDITS--
3441
Christian Weiske, cweiske@php.net

0 commit comments

Comments
 (0)