Skip to content

Commit a79008b

Browse files
committed
Also forbid null bytes in mail()
I've adjusted mb_send_mail() already, but of course the handling in mail() should be the same.
1 parent 4d86000 commit a79008b

File tree

2 files changed

+46
-21
lines changed

2 files changed

+46
-21
lines changed

ext/standard/mail.c

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,6 @@
5555
continue; \
5656
} \
5757

58-
#define MAIL_ASCIIZ_CHECK(str, len) \
59-
p = str; \
60-
e = p + len; \
61-
while ((p = memchr(p, '\0', (e - p)))) { \
62-
*p = ' '; \
63-
} \
64-
6558
extern zend_long php_getuid(void);
6659

6760
static zend_bool php_mail_build_headers_check_field_value(zval *val)
@@ -260,32 +253,26 @@ PHP_FUNCTION(mail)
260253
size_t subject_len, i;
261254
char *force_extra_parameters = INI_STR("mail.force_extra_parameters");
262255
char *to_r, *subject_r;
263-
char *p, *e;
264256

265257
ZEND_PARSE_PARAMETERS_START(3, 5)
266-
Z_PARAM_STRING(to, to_len)
267-
Z_PARAM_STRING(subject, subject_len)
268-
Z_PARAM_STRING(message, message_len)
258+
Z_PARAM_PATH(to, to_len)
259+
Z_PARAM_PATH(subject, subject_len)
260+
Z_PARAM_PATH(message, message_len)
269261
Z_PARAM_OPTIONAL
270262
Z_PARAM_ARRAY_HT_OR_STR(headers_ht, headers_str)
271-
Z_PARAM_STR(extra_cmd)
263+
Z_PARAM_PATH_STR(extra_cmd)
272264
ZEND_PARSE_PARAMETERS_END();
273265

274-
/* ASCIIZ check */
275-
MAIL_ASCIIZ_CHECK(to, to_len);
276-
MAIL_ASCIIZ_CHECK(subject, subject_len);
277-
MAIL_ASCIIZ_CHECK(message, message_len);
278266
if (headers_str) {
279-
MAIL_ASCIIZ_CHECK(ZSTR_VAL(headers_str), ZSTR_LEN(headers_str));
267+
if (strlen(ZSTR_VAL(headers_str)) != ZSTR_LEN(headers_str)) {
268+
zend_argument_value_error(4, "must not contain any null bytes");
269+
RETURN_THROWS();
270+
}
280271
headers_str = php_trim(headers_str, NULL, 0, 2);
281272
} else if (headers_ht) {
282273
headers_str = php_mail_build_headers(headers_ht);
283274
}
284275

285-
if (extra_cmd) {
286-
MAIL_ASCIIZ_CHECK(ZSTR_VAL(extra_cmd), ZSTR_LEN(extra_cmd));
287-
}
288-
289276
if (to_len > 0) {
290277
to_r = estrndup(to, to_len);
291278
for (; to_len; to_len--) {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
mail() with null bytes in arguments
3+
--FILE--
4+
<?php
5+
6+
try {
7+
mail("foo\0bar", "x", "y");
8+
} catch (ValueError $e) {
9+
echo $e->getMessage(), "\n";
10+
}
11+
try {
12+
mail("x", "foo\0bar", "y");
13+
} catch (ValueError $e) {
14+
echo $e->getMessage(), "\n";
15+
}
16+
try {
17+
mail("x", "y", "foo\0bar");
18+
} catch (ValueError $e) {
19+
echo $e->getMessage(), "\n";
20+
}
21+
try {
22+
mail("x", "y", "z", "foo\0bar");
23+
} catch (ValueError $e) {
24+
echo $e->getMessage(), "\n";
25+
}
26+
try {
27+
mail("x", "y", "z", "q", "foo\0bar");
28+
} catch (ValueError $e) {
29+
echo $e->getMessage(), "\n";
30+
}
31+
32+
?>
33+
--EXPECT--
34+
mail(): Argument #1 ($to) must not contain any null bytes
35+
mail(): Argument #2 ($subject) must not contain any null bytes
36+
mail(): Argument #3 ($message) must not contain any null bytes
37+
mail(): Argument #4 ($additional_headers) must not contain any null bytes
38+
mail(): Argument #5 ($additional_parameters) must not contain any null bytes

0 commit comments

Comments
 (0)