Make WordPress Core

Ticket #62940: 62940.diff

File 62940.diff, 7.4 KB (added by SirLouen, 9 months ago)

First Review + Test

  • src/wp-includes/pluggable.php

    diff --git src/wp-includes/pluggable.php src/wp-includes/pluggable.php
    index 5edd0c760c..0cb207172b 100644
    if ( ! function_exists( 'wp_mail' ) ) : 
    233233                        return $pre_wp_mail;
    234234                }
    235235
    236                 if ( isset( $atts['to'] ) ) {
    237                         $to = $atts['to'];
    238                 }
    239 
    240                 if ( ! is_array( $to ) ) {
    241                         $to = explode( ',', $to );
    242                 }
    243 
    244                 if ( isset( $atts['subject'] ) ) {
    245                         $subject = $atts['subject'];
    246                 }
    247 
    248                 if ( isset( $atts['message'] ) ) {
    249                         $message = $atts['message'];
    250                 }
    251 
    252                 if ( isset( $atts['headers'] ) ) {
    253                         $headers = $atts['headers'];
    254                 }
    255 
    256                 if ( isset( $atts['attachments'] ) ) {
    257                         $attachments = $atts['attachments'];
    258                 }
    259 
    260                 if ( ! is_array( $attachments ) ) {
    261                         $attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) );
    262                 }
    263 
    264                 if ( isset( $atts['embeds'] ) ) {
    265                         $embeds = $atts['embeds'];
    266                 }
    267 
    268                 if ( ! is_array( $embeds ) ) {
    269                         $embeds = explode( "\n", str_replace( "\r\n", "\n", $embeds ) );
    270                 }
    271 
    272236                global $phpmailer;
    273237
    274238                // (Re)create it, if it's gone missing.
    if ( ! function_exists( 'wp_mail' ) ) : 
    284248                        };
    285249                }
    286250
    287                 // Headers.
     251                // Process Headers First.
    288252                $cc       = array();
    289253                $bcc      = array();
    290254                $reply_to = array();
     255                $charset  = get_bloginfo( 'charset' );
     256
     257                if ( isset( $atts['headers'] ) ) {
     258                        $headers = $atts['headers'];
     259                }
    291260
    292261                if ( empty( $headers ) ) {
    293262                        $headers = array();
    if ( ! function_exists( 'wp_mail' ) ) : 
    323292
    324293                                        switch ( strtolower( $name ) ) {
    325294                                                // Mainly for legacy -- process a "From:" header if it's there.
    326                                                 case 'from':
    327                                                         $bracket_pos = strpos( $content, '<' );
    328                                                         if ( false !== $bracket_pos ) {
    329                                                                 // Text before the bracketed email is the "From" name.
    330                                                                 if ( $bracket_pos > 0 ) {
    331                                                                         $from_name = substr( $content, 0, $bracket_pos );
    332                                                                         $from_name = str_replace( '"', '', $from_name );
    333                                                                         $from_name = trim( $from_name );
    334                                                                 }
    335 
    336                                                                 $from_email = substr( $content, $bracket_pos + 1 );
    337                                                                 $from_email = str_replace( '>', '', $from_email );
    338                                                                 $from_email = trim( $from_email );
    339 
    340                                                                 // Avoid setting an empty $from_email.
    341                                                         } elseif ( '' !== trim( $content ) ) {
    342                                                                 $from_email = trim( $content );
    343                                                         }
    344                                                         break;
    345295                                                case 'content-type':
    346296                                                        if ( str_contains( $content, ';' ) ) {
    347297                                                                list( $type, $charset_content ) = explode( ';', $content );
    if ( ! function_exists( 'wp_mail' ) ) : 
    350300                                                                        $charset = trim( str_replace( array( 'charset=', '"' ), '', $charset_content ) );
    351301                                                                } elseif ( false !== stripos( $charset_content, 'boundary=' ) ) {
    352302                                                                        $boundary = trim( str_replace( array( 'BOUNDARY=', 'boundary=', '"' ), '', $charset_content ) );
    353                                                                         $charset  = '';
    354303                                                                }
    355304
    356305                                                                // Avoid setting an empty $content_type.
    if ( ! function_exists( 'wp_mail' ) ) : 
    358307                                                                $content_type = trim( $content );
    359308                                                        }
    360309                                                        break;
     310                                                case 'from':
     311                                                        if ( ! empty( $content ) ) {
     312                                                                $addresses = $phpmailer->parseAddresses( $content, null, $charset );
     313                                                                if ( ! empty( $addresses[0]['name'] ) ) {
     314                                                                        $from_name = $addresses[0]['name'];
     315                                                                }
     316                                                                if ( ! empty( $addresses[0]['address'] ) ) {
     317                                                                        $from_email = $addresses[0]['address'];
     318                                                                }
     319                                                        }
     320                                                        break;
    361321                                                case 'cc':
    362                                                         $cc = array_merge( (array) $cc, explode( ',', $content ) );
     322                                                        $cc = array_merge( (array) $cc, $phpmailer->parseAddresses( $content, null, $charset ) );
    363323                                                        break;
    364324                                                case 'bcc':
    365                                                         $bcc = array_merge( (array) $bcc, explode( ',', $content ) );
     325                                                        $bcc = array_merge( (array) $bcc, $phpmailer->parseAddresses( $content, null, $charset ) );
    366326                                                        break;
    367327                                                case 'reply-to':
    368                                                         $reply_to = array_merge( (array) $reply_to, explode( ',', $content ) );
     328                                                        $reply_to = array_merge( (array) $reply_to, $phpmailer->parseAddresses( $content, null, $charset ) );
    369329                                                        break;
    370330                                                default:
    371331                                                        // Add it to our grand headers array.
    if ( ! function_exists( 'wp_mail' ) ) : 
    376336                        }
    377337                }
    378338
     339                if ( isset( $atts['to'] ) ) {
     340                        $to = $atts['to'];
     341                }
     342
     343                if ( ! is_array( $to ) ) {
     344                        $to = $phpmailer->parseAddresses( $to, null, $charset );
     345                }
     346
     347                if ( isset( $atts['subject'] ) ) {
     348                        $subject = $atts['subject'];
     349                }
     350
     351                if ( isset( $atts['message'] ) ) {
     352                        $message = $atts['message'];
     353                }
     354
     355                if ( isset( $atts['attachments'] ) ) {
     356                        $attachments = $atts['attachments'];
     357                }
     358
     359                if ( ! is_array( $attachments ) ) {
     360                        $attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) );
     361                }
     362
     363                if ( isset( $atts['embeds'] ) ) {
     364                        $embeds = $atts['embeds'];
     365                }
     366
     367                if ( ! is_array( $embeds ) ) {
     368                        $embeds = explode( "\n", str_replace( "\r\n", "\n", $embeds ) );
     369                }
     370
    379371                // Empty out the values that may be set.
    380372                $phpmailer->clearAllRecipients();
    381373                $phpmailer->clearAttachments();
    if ( ! function_exists( 'wp_mail' ) ) : 
    457449                        foreach ( (array) $addresses as $address ) {
    458450                                try {
    459451                                        // Break $recipient into name and address parts if in the format "Foo <bar@baz.com>".
    460                                         $recipient_name = '';
    461 
    462                                         if ( preg_match( '/(.*)<(.+)>/', $address, $matches ) ) {
    463                                                 if ( count( $matches ) === 3 ) {
    464                                                         $recipient_name = $matches[1];
    465                                                         $address        = $matches[2];
    466                                                 }
    467                                         }
     452                                        $recipient_name = $address['name'] ?? '';
     453                                        $address        = $address['address'];
    468454
    469455                                        switch ( $address_header ) {
    470456                                                case 'to':
    if ( ! function_exists( 'wp_mail' ) ) : 
    489475                // Set to use PHP's mail().
    490476                $phpmailer->isMail();
    491477
    492                 // Set Content-Type and charset.
     478                // Set Content-Type and Charset.
    493479
    494480                // If we don't have a Content-Type from the input headers.
    495481                if ( ! isset( $content_type ) ) {
    if ( ! function_exists( 'wp_mail' ) ) : 
    512498                        $phpmailer->isHTML( true );
    513499                }
    514500
    515                 // If we don't have a charset from the input headers.
    516                 if ( ! isset( $charset ) ) {
    517                         $charset = get_bloginfo( 'charset' );
    518                 }
    519 
    520501                /**
    521502                 * Filters the default wp_mail() charset.
    522503                 *
  • tests/phpunit/tests/pluggable/wpMail.php

    diff --git tests/phpunit/tests/pluggable/wpMail.php tests/phpunit/tests/pluggable/wpMail.php
    index 85e3b46f61..dd452400c4 100644
    class Tests_Pluggable_wpMail extends WP_UnitTestCase { 
    441441                $this->assertSame( 1, $ma->get_call_count() );
    442442
    443443                $expected_error_data = array(
    444                         'to'                       => array( 'an_invalid_address' ),
     444                        'to'                       => array(),
    445445                        'subject'                  => 'Testing',
    446446                        'message'                  => 'Test Message',
    447447                        'headers'                  => array(),
    class Tests_Pluggable_wpMail extends WP_UnitTestCase { 
    625625                        $this->assertStringContainsString( 'cid:' . $key, $mailer->get_sent()->body, 'The cid ' . $key . ' is not referenced in the mail body.' );
    626626                }
    627627        }
     628        /**
     629         * @ticket 62940
     630         */
     631        public function test_wp_mail_single_line_utf8_header() {
     632                $headers = 'From: =?UTF-8?B?VGVzdA==?= <test@example.com>';
     633                wp_mail( 'test@test.com', 'subject', 'message', $headers );
     634
     635                $mailer = tests_retrieve_phpmailer_instance();
     636                // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
     637                $this->assertSame( 'test@example.com', $mailer->From );
     638                $this->assertSame( 'Test', $mailer->FromName );
     639                // phpcs:enable
     640        }
    628641}