Skip to content

Commit

Permalink
Also forbid null bytes in mail()
Browse files Browse the repository at this point in the history
I've adjusted mb_send_mail() already, but of course the handling
in mail() should be the same.
  • Loading branch information
nikic committed Sep 11, 2020
1 parent 4d86000 commit a79008b
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 21 deletions.
29 changes: 8 additions & 21 deletions ext/standard/mail.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,6 @@
continue; \
} \

#define MAIL_ASCIIZ_CHECK(str, len) \
p = str; \
e = p + len; \
while ((p = memchr(p, '\0', (e - p)))) { \
*p = ' '; \
} \

extern zend_long php_getuid(void);

static zend_bool php_mail_build_headers_check_field_value(zval *val)
Expand Down Expand Up @@ -260,32 +253,26 @@ PHP_FUNCTION(mail)
size_t subject_len, i;
char *force_extra_parameters = INI_STR("mail.force_extra_parameters");
char *to_r, *subject_r;
char *p, *e;

ZEND_PARSE_PARAMETERS_START(3, 5)
Z_PARAM_STRING(to, to_len)
Z_PARAM_STRING(subject, subject_len)
Z_PARAM_STRING(message, message_len)
Z_PARAM_PATH(to, to_len)
Z_PARAM_PATH(subject, subject_len)
Z_PARAM_PATH(message, message_len)
Z_PARAM_OPTIONAL
Z_PARAM_ARRAY_HT_OR_STR(headers_ht, headers_str)
Z_PARAM_STR(extra_cmd)
Z_PARAM_PATH_STR(extra_cmd)
ZEND_PARSE_PARAMETERS_END();

/* ASCIIZ check */
MAIL_ASCIIZ_CHECK(to, to_len);
MAIL_ASCIIZ_CHECK(subject, subject_len);
MAIL_ASCIIZ_CHECK(message, message_len);
if (headers_str) {
MAIL_ASCIIZ_CHECK(ZSTR_VAL(headers_str), ZSTR_LEN(headers_str));
if (strlen(ZSTR_VAL(headers_str)) != ZSTR_LEN(headers_str)) {
zend_argument_value_error(4, "must not contain any null bytes");
RETURN_THROWS();
}
headers_str = php_trim(headers_str, NULL, 0, 2);
} else if (headers_ht) {
headers_str = php_mail_build_headers(headers_ht);
}

if (extra_cmd) {
MAIL_ASCIIZ_CHECK(ZSTR_VAL(extra_cmd), ZSTR_LEN(extra_cmd));
}

if (to_len > 0) {
to_r = estrndup(to, to_len);
for (; to_len; to_len--) {
Expand Down
38 changes: 38 additions & 0 deletions ext/standard/tests/mail/mail_null_bytes.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
--TEST--
mail() with null bytes in arguments
--FILE--
<?php

try {
mail("foo\0bar", "x", "y");
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
try {
mail("x", "foo\0bar", "y");
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
try {
mail("x", "y", "foo\0bar");
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
try {
mail("x", "y", "z", "foo\0bar");
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
try {
mail("x", "y", "z", "q", "foo\0bar");
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}

?>
--EXPECT--
mail(): Argument #1 ($to) must not contain any null bytes
mail(): Argument #2 ($subject) must not contain any null bytes
mail(): Argument #3 ($message) must not contain any null bytes
mail(): Argument #4 ($additional_headers) must not contain any null bytes
mail(): Argument #5 ($additional_parameters) must not contain any null bytes

0 comments on commit a79008b

Please sign in to comment.