From 9c813c42828dd4a85e9f45658bde26860a405759 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 10 Nov 2020 16:13:54 +0100 Subject: [PATCH] Fix #72964: White space not unfolded for CC/Bcc headers `\r\n` does only terminate a header, if not followed by `\t` or ` `. We have to cater to that when determining the end position of the respective headers. --- ext/standard/tests/mail/bug72964.phpt | 73 +++++++++++++++++++++++++++ win32/sendmail.c | 25 +++++++++ 2 files changed, 98 insertions(+) create mode 100644 ext/standard/tests/mail/bug72964.phpt diff --git a/ext/standard/tests/mail/bug72964.phpt b/ext/standard/tests/mail/bug72964.phpt new file mode 100644 index 0000000000000..44048771d6d2c --- /dev/null +++ b/ext/standard/tests/mail/bug72964.phpt @@ -0,0 +1,73 @@ +--TEST-- +Bug #72964 (White space not unfolded for CC/Bcc headers) +--SKIPIF-- + +--INI-- +SMTP=localhost +smtp_port=25 +--FILE-- + 0) { + // sleep for a while to allow msg to be delivered + sleep(1); + + $num_messages = imap_check($imap_stream)->Nmsgs; + for ($i = $num_messages; $i > 0; $i--) { + $info = imap_headerinfo($imap_stream, $i); + if ($info->subject === $subject) { + imap_delete($imap_stream, $i); + $found = true; + break; + } + } + $repeat_count--; + } + + imap_close($imap_stream, CL_EXPUNGE); + return $found; +} + +$to = "{$users[2]}@$domain"; +$subject = bin2hex(random_bytes(16)); +$message = 'hello'; +$headers = "From: webmaster@example.com\r\n" + . "Cc: {$users[0]}@$domain,\r\n\t{$users[1]}@$domain\r\n" + . "Bcc: {$users[2]}@$domain,\r\n {$users[3]}@$domain\r\n"; + +$res = mail($to, $subject, $message, $headers); +if ($res !== true) { + die("TEST FAILED : Unable to send test email\n"); +} else { + echo "Message sent OK\n"; +} + +foreach ($users as $user) { + if (!find_and_delete_message("$user@$domain", $subject)) { + echo "TEST FAILED: email not delivered\n"; + } else { + echo "TEST PASSED: Message sent and deleted OK\n"; + } +} +?> +--EXPECT-- +Message sent OK +TEST PASSED: Message sent and deleted OK +TEST PASSED: Message sent and deleted OK +TEST PASSED: Message sent and deleted OK +TEST PASSED: Message sent and deleted OK diff --git a/win32/sendmail.c b/win32/sendmail.c index 9e31028d58a24..c82dc7b3c6caf 100644 --- a/win32/sendmail.c +++ b/win32/sendmail.c @@ -458,6 +458,16 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char if (NULL == (pos2 = strstr(pos1, "\r\n"))) { tempMailTo = estrndup(pos1, strlen(pos1)); } else { + char *pos3; + while (pos2[2] == ' ' || pos2[2] == '\t') { + pos3 = strstr(pos2 + 2, "\r\n"); + if (pos3 != NULL) { + pos2 = pos3; + } else { + pos2 += strlen(pos2); + break; + } + } tempMailTo = estrndup(pos1, pos2 - pos1); } @@ -516,7 +526,22 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char header we know it was the last thing. */ pos2 = pos1; } else { + char *pos3 = NULL; + while (pos2[2] == ' ' || pos2[2] == '\t') { + pos3 = strstr(pos2 + 2, "\r\n"); + if (pos3 != NULL) { + pos2 = pos3; + } else { + pos2 += strlen(pos2); + break; + } + } tempMailTo = estrndup(pos1, pos2 - pos1); + if (pos3 == NULL) { + /* Later, when we remove the Bcc: out of the + header we know it was the last thing. */ + pos2 = pos1; + } } token = strtok(tempMailTo, ",");