-
Notifications
You must be signed in to change notification settings - Fork 7.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mail() function not working correctly in PHP 8.x #8086
Comments
|
The capture from tcpdump is taken on the PHP server, so the trace is captured when going FROM PHP to the MTA(it's the output from sendmail). So the CRCRLF seems to comes from PHP, not the MTA(unless you refer to sendmail as the MTA). When you say MTA, do you mean sendmail? Do you mean that it is sendmail that is converting the input from PHP to CRCRLF? |
You can see the raw PHP output by e.g. writing to a file instead of using sendmail. I.e. set |
Thanks @cmb69 I was able to get the raw output from the mail() function into a file using your advice.
and in PHP 7 it looks like this:
This issue has actually been reported to PHP way back in 2002:
Following this note will cause the output from PHP8 to be a mix of "\r\n" and "\n" for the headers. The build in headers for "To:" and "Subject:" will still use "\r\n" even if you set the additional headers to use only "\n".
The essence of the problem is that a UNIX command/program expects line endings to be "\n" and not "\r\n", and since the mail() function on UNIX systems, forwards/outputs to a UNIX command rather than talking to an SMTP server directly, it causes problems. The solution when using the "php:fpm-alpine" image is to set "sendmail_path" to: |
That is irrelevant. The respective RFCs are Internet standards, and those mandate |
I stumbled upon the same issue recently. The solution with This issue happens both with busybox's and ssmtp's sendmail except with busybox's (unless you add verbosity) you will get this weird error I don't know which SMTP server the OP used but I used OpenSMTPD, so possibly related OpenSMTPD/OpenSMTPD#1135 |
I just faced this issue in the PHP8.1 alpine image. It was fine in PHP7 images. |
Why PHP contributors didn't do this knowing that alpine builds are failing one of the basic functions? |
Because it is not a PHP issue. |
I have just been bitten by this on a site hosted by a commercial ISP, where I don't have root access, don't know precisely what distro is being used, and dos2unix is not installed, so I can't use the workaround. I'm afraid that I don't agree that this isn't a PHP issue. Previous PHP versions implemented mail() by communicating directly with the MTA. In doing so, they presumably correctly followed the RFCs requiring "\r\n" as the end of line characters. For your own reasons (and I suspect that they were quite good ones), you have now decided to use sendmail as an intermediary. sendmail is designed and intended to work at and from the Unix command line. It is therefore entirely reasonable for sendmail to expect header and other 'lines' to be terminated by the standard Unix "\n". If PHP chooses to use sendmail as its intermediary in sending mail, it behoves PHP to comply with its formatting rules. |
PHP uses a configurable MTA (e.g. sendmail) on non Windows platforms for ages; nothing has changed in this regard. What has changed, is that as of PHP 8.0.0, the
You don't even need dos2unix for a workaround; something like |
@pfletch101 Nobody cares. PHP team has implemented a standard breaking the whole functionality and just saying "That's not our business to solve this". The Docker team who build the Docker image says "consider installing an alternative image" and closed the ticket. The sendmail bugtracker is dead and nobody responded at all: mirror/busybox#58. In the end, we have a broken functionality, and everyone just ping-ponging users. |
Well we sometime need to stop supporting of some old versions and clients because it will become very difficult to make sure that the stuff still works there. In general we tend to do that when the support ends on the distributions that are still supported. For example currently the oldest distribution that we still support is RHEL 7 and its variants that are still alive (CentOS 7, Amazon Linux 2). That's how we decide to drop specific versions of the libraries. This particular case is not such a case as it impacts many still supported emulations. However this problem is also causing some issue for other MTA as described in https://bugs.php.net/bug.php?id=47983 and PHP 8.0 was a good time to fix it. It was however omission to not keep the compatibility optionally which we should do if such change is done. However it's difficult to know that when making the change because it is very hard to actively test all MTA's. The only thing we can do is to add that option to the future version and learn from this that doing changes to mail output should require more testing and consider more MTA's. |
When this INI option is enabled, it reverts the line separator for headers and message to LF which was a non conformant behavior in PHP 7. It is done because some non conformant MTAs fail to parse CRLF line separator for headers and body.
I just created a PR #10191 that introduces an option to revert back to the previous behavior. |
BTW why are people pointing to rfc822? The introduction seems very clear to me:
|
I see the point here as technically it is up to MTA to follow the RFC when sending the message. This is really just a program interface. On the other side, the current format had its issue so an attempt to fix them was probably in place. I would personally treat this as an omission but I'm not sure if requiring compliance was in place here. I have to say that after doing some research I haven't found anywhere any spec for sendmail interface that would mandate message format to follow the RFC 822, 2822 or 5322. Honestly I found very little info in sendmail docs but I might have missed something so if anyone else sees it somewhere, please share your findings. |
When this INI option is enabled, it reverts the line separator for headers and message to LF which was a non conformant behavior in PHP 7. It is done because some non conformant MTAs fail to parse CRLF line separator for headers and body. This is used for mail and mb_send_mail functions.
@bukka Thank you a lot for the fix! |
@bukka Thank you for the fix! I was also recently bitten by this issue. Do you know when your |
@ElliotNB The fix is not in 8.1 as it's somewhere between feature and a bug and it adds a new ini which is cleaner to do in the last supported version. Also there's a work around so I would suggest to use that in 8.0 and 8.1:
|
In some PHP 8.0.x, issues with \r\n * php/php-src#8086 * SimpleMachines/SMF#7560 * https://www.drupal.org/project/drupal/issues/3270647
Dears, Is there any final class for sending emails to be used in PHP version greater than 8 without changing the sendmail_path ? Since we are not allowed to change the .ini file configuration in some shared hosting. |
@aly9 no but you should contact the hosting provider to change it globally in their configs. |
I'm experiencing this issue too and it's driving me insane , both on PHP 8,1 and 8,0, and i am not using alpine |
@bukka Thanks for your reply, but I have modify my sending emails script to use PHPMailer Class and it is working fine. |
Sendmail binaries on linux, and pretty much every other OS using LF only are designed to parse normal text for the operating system when piped to directly. They internally convert to match the RFC after, which causes a doubled up CR usually with php 8.x now. Actual Sendmail does have a -ba parameter, which does place it into ARPANET mode, which will do the right thing when presented with a text file containing CRLFs for injection. specifying the -ba option in sendmail path does fix the issue, but naturally, the email tester doesn't do this. So the email test fails. qmail's fake sendmail binary does NOT SUPPORT -ba. not even the alternate usendmail wrapper does. postfix, and most other MTAs that provide a fake sendmail binary do not support ARPANET mode like a real sendmail binary does. The only one that i've seen that does this is actual sendmail itself. The sendmail binary has always accepted email for injection in the OS native text format. All other MTAs that have fake sendmail binaries do the same. They all still send RFC compliant emails, doing the needed conversion. When telnetting or s_clienting to the smtp port, telnet itself usually handles this part, and will convert the line endings properly. I'm sorry, but PHP is wrong here. it's mail() function expects either smtp on windows, or a sendmail binary on linux/bsd/osx/etc. And sendmail has ALWAYS accepted messages in the UNIX (linefeed only) text scheme on unix, and it always will. This isn't a silly RFC issue. Sendmail is NOT breaking the RFC by accepting and interpreting piped data stored in native OS text format. the RFC is for message transmission, and when using sendmail binary, php is not transmitting itself. it's handing off to the sendmail binary. Exim is one that's smart enough to just do the right thing. It actually just strips out the \rs and then puts them back when it send the message :). I'm sure there are some others, but as we can see, it's just not widespread enough. Now this IS something that configure should be able to catch. actual sendmail will respond to in this case, it's real sendmail, and -ba should be added to the options automatically. Any other response mean sit's not actual sendmail, we can't do that. |
I think, PHP is mixing up responsibilities. There are 2 involved parties and both of them have their own tasks. It is PHP's responsibility to assemble all information needed by the mail agent. And it is PHP's responsibility to hand that information over to the mail agent in way that is valid for the OS and the mail agent itself. This is where PHP's responsibilities end. The mail agent is responsible to take the information and create a Mail that complies to the respective RFCs. We now have the situation that the standard way of sending mails is broken due to PHP's interference in something that is not their business. I tried the new config variable
This is unacceptable. The only thing that seemed to work is undoing PHP's magic by setting
With this config setting, mails look good in all clients and there are no bounces. Seems like my mail agent (nullmailer) cares about RFC compliance quite fine on it's own. May I ask you to revert this broken feature? Ensuring mailing RFCs is not PHP's responsibility. |
|
The CORRECT behavior is to produce standard text in the operating system's standard text format when piping to sendmail, and to use CR+LF when using SMTP, which is the circumstance where having it be CRLF matters. Funny enough this setting is used on windows, which already uses CRLF. PHP has a responsibility to pipe stuff to sendmail binaries in the format the sendmail binary expects, which is ALWAYS the native text format used by the operating system, unless it's real sendmail in ARPANET mode. |
If you want any change to happen, you need to create a new issue. Comments in closed issues are pretty much useless because it just get forgotten. |
I also had issues with |
Description
The following code:
Resulted in this output of the DATA part of the communication from tcpdump on the receiving SMTP server when building container "FROM php:8.0.14-fpm-alpine" or "FROM php:fpm-alpine":
And this is the resulting mail headers of the mail on the receiving SMTP server:
This is the output using the exact same environment, just that the container is build using "FROM php:7.4-fpm-alpine":
And this is the resulting mail headers of the mail on the receiving SMTP server:
The result is that when using PHP 8 there are some invalid "\r" which makes the mail format invalid and so the headers are not processed correctly on the receiving SMTP server. The result is that the email does not have a subject. I've also tried setting additional headers, but they are all invalid and not processed due to the invalid "\r".
I've tried using both sendmail and ssmtp in the container. It yields the same result.
My php.ini setting are:
Something has changed in the PHP mail() function between PHP 7 and PHP 8
PHP Version
PHP 8.0.14 and newer
Operating System
Docker php:8.0.14-fpm-alpine and php:fpm-alpine
The text was updated successfully, but these errors were encountered: