Skip to content
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

Body gets truncated at "\n.\n" #2975

Closed
php4fan opened this issue Nov 13, 2023 · 3 comments
Closed

Body gets truncated at "\n.\n" #2975

php4fan opened this issue Nov 13, 2023 · 3 comments

Comments

@php4fan
Copy link

php4fan commented Nov 13, 2023

Problem description

When the ->Body property is set (for a plain-text mail) to a text containing the sequence "\n.\n" somewhere in the middle (i.e. a line made only of a full stop), the body gets truncated there.

I know that the way SMTP encodes a body, that sequence is used to terminate it, but I expect PHPMailer to take care of that and encode the body properly. I am astonished that it doesn't.

Code to reproduce

<?php
$mail = new \PHPMailer\PHPMailer\PHPMailer();
$mail->CharSet = 'UTF-8';
$mail->From = '[email protected]';
$mail->isHTML(false);
$mail->Body = "Lorem ipsum 

.

dolor sit amet";
$mail->Subject = "Whatever";

$mail->AddAddress("[email protected]");
$ok = $mail->send();

# Debug output
@Synchro
Copy link
Member

Synchro commented Nov 14, 2023

You're mixing up two things here. What you're referring to is "dot stuffing", which is from SMTP RFC5321. Significantly, it's not part of RFC5322, which defines the message format, is not concerned with how it is sent, and as such has no bearing on dot stuffing.

PHPMailer has had support for dot stuffing in its SMTP client since at least 2008, right here.

In the code you posted, you're not using SMTP, but the PHP mail() function. This function accepts an RFC2822 (the predecessor of 5322) message as a string, and sends it by calling a command-line binary which typically creates a synchronous SMTP connection to localhost. As such, the binary is the SMTP client, and so PHPMailer is not responsible for dot stuffing when sent via that route.

To use a more modern parallel, if you were submitting an RFC5322 message somewhere like mailgun, over HTTP, you would also not need to perform dot stuffing, since it's an SMTP requirement, not an HTTP one.

I'm somewhat surprised that the PHP mail function doesn't handle this, but I don't have any particular evidence that it doesn't.

@Synchro Synchro closed this as completed Nov 14, 2023
@php4fan
Copy link
Author

php4fan commented Nov 14, 2023

I'm somewhat surprised that the PHP mail function doesn't handle this, but I don't have any particular evidence that it doesn't.

Well, it definitely doesn't (and I have also checked by using it directly). Apparently, mail() doesn't handle a lot of things (e.g. it expects lines no longer than 70 characters and wants them terminated with \r\n and not just \n), and apparently, nor does the binary that it calls.

Which means, unless that is a bug in either of them, PHPMailer should handle it.

The way I see it, I'm passing PHPMailer a text that is to be sent in an email body. PHPMailer is supposed to be an abstraction around whatever transport mechanism it uses underneath. I should be able to switch between SMTP, mail and sendmail (BTW, I can't find an explanation of the difference between the last two in the docs) without having to change how I pass the message to PHPMailer.

@Synchro
Copy link
Member

Synchro commented Nov 14, 2023

There are many problems relating to the mail function, which is why I have been recommending against using it for years; if you want to send to a local mail server, use SMTP to localhost. It's faster, safer, and more controllable. The line break issue is one, but it's not as straightforward as you say as it varies between platforms. It also makes me suspect you're using Windows.

The configuration of your mail function in PHP affects it too. For example postfix's sendmail binary has a -i switch described like this in the docs:

-i When reading a message from standard input, don't treat a line with only a . character as the end of input.

That is a default option in PHP, which PHPMailer inherits. It seems likely your config is missing that.

The difference between mail and sendmail transports is that mail uses the mail() function, which indirectly calls a sendmail binary determined (along with its options) by the sendmail_path php.ini setting, whereas the sendmail approach explicitly calls a sendmail binary directly through shell_exec, and also bypasses the weird things the mail function does with headers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants