Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions src/wp-includes/pluggable.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,21 @@ function wp_mail( $to, $subject, $message, $headers = '', $attachments = array()
} else {
if ( ! is_array( $headers ) ) {
/*
* Explode the headers out, so this function can take
* both string headers and an array of headers.
* Process headers and handle folding in a single pass.
* Lines starting with whitespace (space or tab) are continuations of the previous line.
*/
$tempheaders = explode( "\n", str_replace( "\r\n", "\n", $headers ) );
$tempheaders = array();
$normalized_headers = str_replace( "\r\n", "\n", $headers );

foreach ( explode( "\n", $normalized_headers ) as $header_line ) {
if ( ! empty( $tempheaders ) && isset( $header_line[0] ) && ( ' ' === $header_line[0] || "\t" === $header_line[0] ) ) {
// Continuation line - append to previous header.
$last_index = count( $tempheaders ) - 1;
$tempheaders[ $last_index ] .= "\n" . $header_line;
} else {
$tempheaders[] = $header_line;
}
}
} else {
$tempheaders = $headers;
}
Expand Down Expand Up @@ -331,6 +342,10 @@ function wp_mail( $to, $subject, $message, $headers = '', $attachments = array()
$from_name = substr( $content, 0, $bracket_pos );
$from_name = str_replace( '"', '', $from_name );
$from_name = trim( $from_name );
// Decode MIME headers if they contain encoded content or newlines
if ( function_exists( 'mb_decode_mimeheader' ) && ( str_contains( $content, "\n" ) || str_contains( $from_name, '=?' ) ) ) {
$from_name = mb_decode_mimeheader( $from_name );
}
}

$from_email = substr( $content, $bracket_pos + 1 );
Expand Down
32 changes: 32 additions & 0 deletions tests/phpunit/tests/pluggable/wpMail.php
Original file line number Diff line number Diff line change
Expand Up @@ -625,4 +625,36 @@ public function test_wp_mail_string_embeds() {
$this->assertStringContainsString( 'cid:' . $key, $mailer->get_sent()->body, 'The cid ' . $key . ' is not referenced in the mail body.' );
}
}

/**
* @ticket 28473
*/
public function test_wp_mail_multiline_header() {
$headers = 'From: =?UTF-8?B?0YLQtdGB0YIg0YLQtdGB0YIg0YLQtdGB0YIg0YLQtdGB0YIg0YLQtdGB0YIg?=';
$headers .= "\n =?UTF-8?B?0YLQtdGB0YIg0YLQtdGB0YI=?= <test@example.com>";
wp_mail( 'test@test.com', 'subject', 'message', $headers );

$mailer = tests_retrieve_phpmailer_instance();
// phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
$this->assertSame( 'test@example.com', $mailer->From );
$this->assertSame(
'тест тест тест тест тест тест тест',
$mailer->FromName
);
// phpcs:enable
}

/**
* @ticket 28473
*/
public function test_wp_mail_single_line_utf8_header() {
$headers = 'From: =?UTF-8?B?VGVzdA==?= <test@example.com>';
wp_mail( 'test@test.com', 'subject', 'message', $headers );

$mailer = tests_retrieve_phpmailer_instance();
// phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
$this->assertSame( 'test@example.com', $mailer->From );
$this->assertSame( 'Test', $mailer->FromName );
// phpcs:enable
}
}
Loading