Make WordPress Core

Opened 6 weeks ago

Last modified 6 weeks ago

#63127 new defect (bug)

wp_mail resets custom headers when headers array is set to empty, causing loss of custom header data (e.g., boundary)

Reported by: regnalf's profile regnalf Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 6.7.2
Component: Mail Keywords:
Focuses: Cc:

Description

In WordPress wp_mail function, when custom headers are passed as an array, the headers array is being reset to an empty array in line 278. This results in the removal of any custom headers, including important headers like boundary for multipart emails, which causes issues when sending emails with custom content types or attachments.

Steps to Reproduce:

  1. Call wp_mail with custom headers that include a boundary in the Content-Type.
  2. WordPress internally resets the headers array to an empty array (line 278).
  3. Custom headers, including the boundary, are lost in the final email sent by wp_mail.

Expected Behavior:
The custom headers passed into the wp_mail function, including boundary in the Content-Type, should not be reset by WordPress and should be preserved in the final email headers.

Possible Fix:
Avoid resetting the headers array to an empty array in wp_mail. Instead, the function should either:

  • Merge the custom headers correctly with the default ones, or
  • Handle custom headers separately to ensure they are retained.

Change History (2)

#1 @joemcgill
6 weeks ago

Thanks @regnalf. It looks like custom data gets processed in the following block after saving the $headers data to a $tempheaders variable.

See: https://github.com/WordPress/wordpress-develop/blob/360732e132c009bedd59cff77511514103077f50/src/wp-includes/pluggable.php#L282-L352

Is there a specific header that you expect to be processed that is not being accounted for in that block?

#2 @regnalf
6 weeks ago

Yes, i wanted to add a boundary to the header. The only way it will be processed is to add it as a third array element.

<?php

$boundary = uniqid ();
$headers = array ('From: WordPress System <wordpress@domain.com>',
                'Content-Type: multipart/related; charset=UTF-8;',
                'boundary="' . $boundary . '"');

In x-debug I could see that the boundary is recognized. However, it is no longer included on the way to the phpmailer. And so it is not included in the final email.

Note: See TracTickets for help on using tickets.