Problem/Motivation
Using Drupal 7 with php 8.0.24.
When sending a Test E-Mail with the htmlmail modul the received e-mail has not the correct format.
The Test Mail Sending Class is HTMLMailSystem.
If the DefaultMailSystem Class is used, then the content of the receiving email is correct.
With the HTMLMailSystem Class following content is received.
<h1><a href="http://drupal.org/project/htmlmail">HTML Mail</a> test message</h1>
<div class="htmlmail-body">
<p>Test<br />
- asdfsda<br />
- asdfasdf</p>
</div>
Following E-Mail Header:
Arc-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of xx@xx.de designates 91.250.69.35 as permitted sender) smtp.mailfrom=xx@xx.de
Mime-Version: 1.0 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 8Bit X-Mailer: Drupal Return-Path: xx@xx.de Sender: xx@xx.de From: "xxx" <xx@xx.de>
Authentication-Results: mx.google.com; spf=pass (google.com: domain of xx@xx.de designates 91.250.69.35 as permitted sender) smtp.mailfrom=xx@xx.de
X-Bounce-Key: webpack.hosteurope.de;xx@xx.de;1667550549;5c2f9c70;
X-He-Smsgid: 1oqs4a-0002uV-Fu
Return-Path: <xx@xx.de>
Arc-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=date:from:message-id:mime-version:subject:to; bh=h/z7be5KasC87Q2mKTeaa8zkUTRc84oFD+/UT9xIC1s=; b=GAOMjy1BdAzalLc+rg1o5W0NZq3dj0orhXQWygYlXbZC6FXR3EMZCK6EK3Y9DUmfc+ pkzNeJjdDDaUKXZ0WX1mVUgnrgWYBZFnP7Ip1Xo3VhiCqdMMDEUA6F7LnGHhsDy8f7/M x4IyYURxTyLHKfdYpGFdHeJxalwcYMuVaKFSm4Xca94bGvZB0qkoToGnyzrhnQEVamZk 6Pva8iK0hxKymB3s+BTa300DrtMF2qWFJ3b7+P9TNTGHP5CdaFBo+62ECt0tZCJcNI4g Z3awXPn2I9mQHpqR1DC1nvfT9nTg3gw9TsBxiYrG8CG7O1uL7OUBAeApkrwGfDsmBmr+ P1kg==
Arc-Seal: i=1; a=rsa-sha256; t=1667550549; cv=none; d=google.com; s=arc-20160816; b=UCaRZwsqnURzNP7goWqfUzny5k7JZt1x9xSVZ+6oyTwwKKlIygfSgSeEB3AnuitZXN w0e2+gJUQ4xjreyCaTX7Tc/V7WohY/noI7Ixtj5lXZ9/kDVsnNdXBYgAMv92NsLDX7IK G+Kua3MfRrFsPD3Y9ELHvpBj8fDYj+WadttWMHTfdBEvjZboGW2hFCkh9eUR1dd1m2YZ j6jwDW6cT1umrffluxNB0zZKKwzsN4VlvEiiKCc0FZXamdte5lF/q1E7Tv79E0JrjO0f lC4YSTCgR70lAMa14JrEGj1UzygMan3dgiTSVED9cDeUv1vyDaAKhrzD6p+L981tgh7S qEWg==
X-Received: by 2002:a05:600c:a0b:b0:3b4:f9a7:f79b with SMTP id z11-20020a05600c0a0b00b003b4f9a7f79bmr31755843wmp.99.1667550549148; Fri, 04 Nov 2022 01:29:09 -0700 (PDT)
Received: by 2002:a05:7022:219a:b0:46:d7aa:21b9 with SMTP id bh26csp98495dlb; Fri, 4 Nov 2022 01:29:09 -0700 (PDT)
Received: from xxx.webpack.hosteurope.de (xx.webpack.hosteurope.de. [91.250.69.35]) by mx.google.com with ESMTPS id g9-20020adfd1e9000000b0023a43b7cd83si1680925wrd.599.2022.11.04.01.29.08 for <xx.xx@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Nov 2022 01:29:09 -0700 (PDT)
Received: from localhost ([127.0.0.1]) by xxx.webpack.hosteurope.de running ExIM with local id 1oqs4a-0002uV-Fu; Fri, 04 Nov 2022 09:29:08 +0100
Received-Spf: pass (google.com: domain of xx@xx.de designates 91.250.69.35 as permitted sender) client-ip=91.250.69.35;
Delivered-To: xx.xx@gmail.com
<E1oqs4a-0002uV-Fu@xx.webpack.hosteurope.de>
X-He-Php-Submitted: yes
X-Google-Smtp-Source: AMsMyM4vmHbu3b4jDkbFIIgJLCcYx1V6kPaRZmFyNqbMl6hk5CVtq8hP3G6uGQki4kXa0Idq5mrD
Comments
Comment #2
longwaveHTML Mail is not part of Drupal core. Is this a duplicate of #3318128: PHP 8 HTML Test Message fails?
Comment #3
down2under commentedYes, they suggest to post a issue here.
Comment #4
longwaveBut then this is just a duplicate of #3270647: PhpMail : broken mail headers in PHP 8.0+ because of LF characters? You can help by testing the patch over there, posting a duplicate issue won't help get it fixed more quickly.
Comment #5
down2under commentedBut that patch is for version 9. I am using drupal version 7
Comment #6
poker10 commentedYes, it is possible that this is the same problem as in the D9/10 issue. I think we need to be cautious with the D7 fix, because we can easily broke this for some other sites using PHP 7.4 and lower, see:
and also this: https://bugs.php.net/bug.php?id=81158
So I think this fix (line-endings change from LF to CRLF) needs to be done only for PHP 8 (or only as opt-in approach).
Retitled the issue and changed the priority to correspond the D9/10 issue. Correctly this issue should be postponed (as per backport policy), but lets wait a bit for the approach in the D9/10 issue. Because I think that at least for D10 the approach will be a bit different, as the minimum PHP version in D10 is 8.1, so it does not need to care about what was working on lower PHP.
Comment #7
rclemings commentedWhat would the fix look like for Drupal 7?
I tried changing line 68 of /modules/system/system_mail_inc and it had no effect:
from:
$mail_headers = join("\n", $mimeheaders);to
Insofar as PHP7 is now officially EOL it would be nice to get a patch that works for Drupal 7, even if it came with a warning not to use it with PHP<8.
Here's what I see in the emails:
PHP7.4:
PHP8.1:
I inserted "(CRLF)" manually. Among other things, some are missing.
Comment #8
arx-e commentedFor me changing line 68 of /modules/system/system_mail_inc
to
$mail_headers = join("\r\n", $mimeheaders);as described in #7 solved the problem with webform mails.But while trying to solve similar issue in other sites i had some success changing line 13 of includes/mail.inc
I also added the following lines in settings.php (one of them is for use by the mimemail module)
$conf['mail_line_endings'] = "\r\n";
$conf['mimemail_crlf'] = "\r\n";
Comment #9
rclemings commented@arx-e: How did you change line 13 of includes/mail.inc?
I did this (which of course could be abbreviated) and it works, but I'm worried it could have some unpredictable side effects.
This is on a CentOS server v7.9.2009, so not Windows.
I also made the other changes you listed but they didn't work until I changed line 13.
Comment #10
arx-e commented@rclemings I did the same thing as you as a quick solution with minimal editing.
And it worked for some system messages but not for webform messages for example.
I read in an old issue that LF ("\n) is what should be used in Linux systems and CRLF ("\r\n") was reserved only for windows servers.
I am not sure but maybe this has changed?
The old issue is this one drupal_mail(), CRLF, and Windows
Comment #11
arx-e commentedI suppose if it is safe to have it universally as CRLF, this could be shortened to something like this:
define('MAIL_LINE_ENDINGS', "\r\n");Comment #12
rclemings commentedRight above line 13 in includes/mail.inc it says:
So I added this to settings.php:
and it had no effect. I had to change line 13 in includes/mail.inc from:
to:
and then outgoing emails were properly formatted (using CentOS 7.9.2009, PHP 8.1, Drupal 7.94, Commerce Email 7.x-2.x-dev, HTML Mail 7.x-2.71, and Mime Mail 7.x-1.2). I checked the password reset email, a Simplenews newsletter, and order notifications from Commerce 1.x and all looked correct.
I'm not smart enough to troubleshoot this further but it looks as if there's something squirrelly about how $conf['mail_line_endings'] works with this combination.
Comment #13
rclemings commentedHere's a patch with the fix from #12. Works for me (using CentOS 7.9.2009, PHP 8.1, Drupal 7.94, Commerce Email 7.x-2.x-dev, HTML Mail 7.x-2.71, and Mime Mail 7.x-1.2), but not tested otherwise.
Comment #15
aitala commentedHi,
I'm not sure this is working... I'm still getting the leading spaces..
This is with D7.94, PHP 8.1.16, no special Mailers... and with (and without) the patch from https://www.drupal.org/node/111702
Thx,
Eric
Comment #16
arx-e commentedThe modification as in patch #13 had resolved the problem for me but the issue resurfaced the last couple of weeks or so.
I just now discovered another place where the same modification resolves the issue again:
line 67 in modules/system/system.mail.inc is now
$mail_headers = join("\n", $mimeheaders);
and it obviously ruins the messages.
This modification solved the problem again:
$mail_headers = join("\r\n", $mimeheaders);
Comment #17
arx-e commentedAnd here is a patch containing both modifications (#13 + #16).
Comment #18
aitala commentedPatch #17 seems to have worked for me.
Thanks,
Eric
Comment #20
edvanleeuwenManually applied the changes. This works.
Comment #21
jbiechele commentedI also can confirm that the patch in #17 works, on two D7 sites with PHP 8.2. Thanks for the patches.
Comment #22
chase. commentedRunning installations on Debian-based distributions with exim4 or Postfix, the patch from #17 fixes the issue without noticeable side-effects.
Comment #23
poker10 commentedThanks for confimation that the patch is working! However, the patch has a number of failures, so either is it not working correctly in all cases, or the tests needs to be updated. Unfortunatelly it cannot be committed in the current shape until we deal with the failing tests.
Comment #24
arx-e commentedAs far as I managed to understand the tests fail because of the drupal_html_to_text function that is found in the includes\mail.inc file.
But I also found lots of other places where LF line endings are being used.
And from what is stated here https://www.drupal.org/project/drupal/issues/3270647 the line endings should be CRLF for PHP 8+ and LF for prior PHP versions except on Windows servers.
So in this patch I have tried to define line endings according to the php version and server software and I replaced all occurrences of LF with a variable $line_endings
My experience with code is relatively limited so I don't really know whether all those changes are needed and/or correct but I have tested these modifications at one Drupal 7.98 site and it seems to be working without any issues.
Comment #25
arx-e commentedOne more patch keeping the logic that distinguishes between PHP versions and uses CRLF only when PHP is 8 or 8+ or when on a Windows server.
The rest of the changes have been kept to a minimum but the result works for me on a couple PHP8 sites.
Comment #26
arx-e commentedReuploading the patch as the last one had a syntax error.
Comment #27
edvanleeuwenTested and verified patch #26.
Comment #28
poker10 commentedThanks for working on this @arx-e!
Only a quick review / questions:
1. Are we sure we need all these changes to the
$message['body']formatting anddrupal_html_to_text()?The issue summary does not mention any problems with the mail body and the parent D10 issue have not made any changes to the mail body as well. I am curious if it wouldn't be sufficient to make only this change:
Plus the change to the
MAIL_LINE_ENDINGSconstant definition, which looks reasonable. If a change to the mail body is needed, then we should explain the reasons for this change.2. Core is not using
PHP_MAJOR_VERSIONconstant anywhere, let's use the standard comparision used on other places:3. If the updated patch will pass on all PHP versions, we should also backport the new test from D10.
Comment #29
arx-e commented@poker10
No, I was not at all sure about those changes. I was just trying to make the tests work.
So i am uploading a new patch with only:
1. the change in the definition of
MAIL_LINE_ENDINGSin includes/mail.inc2. and the change in modules/system/system.mail.inc
Comment #30
stevewilson commentedI've manually applied the changes at #29 which seem to fix the issue for me.
I'm keen to see the fix for this issue committed, so I'd be really appreciative if somebody could sort out the issues with the failed tests that seem to be the stumbling block. I'd be happy to help, but as I'm not a programmer I'm not sure how I could actually contribute.
Comment #31
danrodI had the exact same issue and the patch #29 worked fine, solved the issues that I had the the outgoing email format.
Thank you !
Comment #32
davidwhthomas commentedThe patch in #29 fixed the issue I was having with line endings being stripped in mail headers, preventing html email being sent, in Drupal 7.102
The email headers would show all on one line and the email body shows the plain text html tags.
After the patch, the headers are formatted correctly and the email comes through HTML formatted, with thanks.
Before:
MIME-Version: 1.0 Content-Type: text/html; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8Bit X-Mailer: Drupal Sender: email@example.com From: Example <email@example.com>After:
Comment #33
mcdruid commented#29 looks reasonable but I'd be happier committing this if we could verify that the comment above the changes to the constant is true:
In other words, I'd like to ensure that sites can override these changes if they need to (e.g. because they use a quirky MTA or similar).
An earlier comment in this issue suggested that the $conf / variable does not in fact override the constant.
It'd also be good to see tests passing in an MR with the new d.o testing pipeline.
Comment #35
poker10 commentedI converted the patch #29 to the MR and it is failing on PHP8+: https://git.drupalcode.org/project/drupal/-/pipelines/358167
I think the reason is in
drupal_html_to_text, which in D7 uses:but in D10:
I compared the tests and they looks the same, so this seems like the only difference. On Linux, PHP 8, in D7, after the patch is applied there will be "\r\n", but on Linux, PHP8, in D10 it is just "\n".
I can update the test with a similar code from D10:
But the question is, if this is a sign of the broken test, or we are unintentionally changing something else.
//edit: if we update it to
Then I think it will still fail, because we are not testing the variable, therefore the outcome will be the same as the current state with only
MAIL_LINE_ENDINGSused.Comment #36
poker10 commentedIt is still failing on PHP8:
I think the patch is not correct.
D10 code:
D7 code:
You can see, that if we change the
MAIL_LINE_ENDINGSin D7, it does change also the body line endings, which I suppose is something we do not want to change. These line endings should be only linux/windows dependent. But after the proposed change, on PHP8, also the body has "\r\n" even on linux. That is a cause of the failure.The correct approach seems to be to only touch headers, as proposed in the issue summary and issue title. So to change this line:
to be "\n" on PHP<8 and "\r\n" on PHP>=8.
Comment #37
poker10 commentedI have updated the MR according to my findings from #36 (the comment I have used in the code is borrowed from Drupal 9.5, see: https://git.drupalcode.org/project/drupal/-/commit/40ad8b5e57e3dc534de77...).
Tests are now green: https://git.drupalcode.org/project/drupal/-/pipelines/358280
Comment #38
poker10 commentedBut now the change cannot be opted-out by using
$conf['mail_line_endings']. Should we introduce another variable? I did not want to use an existing one, because as we found out, mixing line endings and header line endings is not a good option.Comment #39
mcdruid commentedSounds like it might make sense to add another variable; perhaps one we wouldn't add to default.settings.php if it's intended to accommodate sites with edge case mail setups.
Comment #40
poker10 commentedAdded a new variable
mail_headers_line_endings.Tests are green: https://git.drupalcode.org/project/drupal/-/pipelines/358322
I think it is still worth a manual testing - at least to compare the email headers on linux - PHP 7.4 vs 8.0. Plus this will need a change record, in case we will decide to commit it. Thanks!
Comment #41
mcdruid commentedI think the new patch looks good.
Having yet another conf / variable is not ideal but it obviously avoids the situation where a change like this breaks sites with a certain mail setup and they're left with no choice but to hack core.
@poker10 and I looked at this to do some manual testing; it's a little tricky because MTAs / SMTP servers etc.. tend to be so accommodating of all sorts of weird stuff in email. For example mailpit (very useful tool included in ddev) has a relevant option - which defaults to false:
https://mailpit.axllent.org/docs/configuration/runtime-options/#smtp-server
However turning that on didn't seem to help us verify that anything was broken without the patch. Almost every way of actually testing mail that we tried (including with e.g. mimemail enabled or not) did not seem to show any problem without the patch on PHP8 (although I think we did reproduce html mail appearing a bit broken).
We eventually managed to observe the specific difference that the patch makes using strace to observe what PHP emits when Drupal's mail system sends a message. (FWIW we used https://www.drupal.org/project/drush_debug_tools which includes a command to send test email from drush - it's old and dusty but still works).
So we verified that without the patch, on PHP 8.2, just a couple of the mail headers were separated by only
\n. For example:Whereas with the patch applied, this was:
It looks like - at least in the testing we were doing - those were the only headers being inserted by the code in question. All other headers were not influenced by these changes (and always had the correct line endings).
So I believe that verifies that this patch is having the desired effect.
If it has any unintended consequences with a particular mail set up, the new variable should allow for the change to be overridden without
killing kittenshacking core.Comment #43
mcdruid commentedThanks everyone!
Comment #44
poker10 commentedCreated a draft CR: https://www.drupal.org/node/3491626
Comment #45
pentium commentedAfter the Drupal 7.103 core update, i'm still experiencing a problem with outgoing e-mails using drupal_mail() function.
This is how a 3 rows html test mail body is shown in all the e-mail clients that the receiver uses (including gmail webmail).
I'm using PHP 8.3 on Almalinux 8.x.
In my Drupal conf, Mail System is set to use Site-wide default MailSystemInterface class => "MimeMailSystem".
I fixed this problem with the attached patch
Hope it may help others with the same problem
Comment #46
mcdruid commentedSorry, I haven't had time to look at the details properly, but do you need to apply a patch?
Can't you fix your problem with the two variables that control the line-endings?
Comment #47
pentium commentedAs you correctly said, we can also adjust the conf "mail_line_endings", because the $message['body'] uses it, while the patch i'm using changes default value in case that "mail_line_endings" is not set.
So, all linux users, must either:
1- Set the "'mail_line_endings'" variable to "\r\n" manually, adding this row to settings.php:
$conf['mail_line_endings'] = "\r\n");2- Apply the patch, because in the file "/includes/mail.inc" there is this line (line 10):
define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Win32') !== FALSE) ? "\r\n" : "\n");that re-defines the MAIL_LINE_ENDINGS constant, setting it to "\n" (i'm on linux - AlmaLinux 8.x)
Comment #48
poker10 commentedI do not think this is the only one condition which makes this bug present. We have debugged it pretty long and were unable to reproduce the broken emails with the Drupal core itself. So I suppose this is also dependent on mailserver somehow.
The reason why the patch from #45 is not a good idea are explained in #36. This issue was about changing the header line endings. If we have changed also the
MAIL_LINE_ENDINGSconstant, the mail body line endings would have changed as well, which is something very different (and Drupal 10/11 also does not have this). If there is an issue with mail body line endings, that is probably a separate issue and hopefully can be solved by fine-tuning values of both variables without the need of any custom core changes.Re:
I do not think this is correct/needed anymore. The
MAIL_LINE_ENDINGSconstant is defined on the top of themail.incfile. Then, when it is used in themail()function, there is a possibility to override it viamail_line_endingsvariable:DefaultMailSystem::mail():So everything from in the mail body should be changed to specified newlines by this line:
The precedence is by the variable, not by the constant. If this code is not working as expected, that is a separate issue.
Can you please doublecheck again, why do you need to change the constant at all? If you are using another mailer and the seding is not done by core
DefaultMailSystem::mail(), then it is indeed a problem of the contrib module.Thanks!
Comment #49
poker10 commentedDrupal 10/11 is using
PHP_EOLfor the mail body line endings, so it is not using\r\nin linux, see: https://git.drupalcode.org/project/drupal/-/blob/11.x/core/lib/Drupal/Co...That is another reason against using the
\r\nfor the mail body line endings in linux in Drupal 7.