mirror of
https://github.com/php/php-src.git
synced 2024-11-27 03:44:07 +08:00
Fix GH-8086: Introduce mail.mixed_lf_and_crlf INI
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.
This commit is contained in:
parent
4d8f981818
commit
cc931af35d
3
NEWS
3
NEWS
@ -8,6 +8,9 @@ PHP NEWS
|
||||
- GMP:
|
||||
. Properly implement GMP::__construct(). (nielsdos)
|
||||
|
||||
- Standard:
|
||||
- Fixed bug GH-8086 (Introduce mail.mixed_lf_and_crlf INI). (Jakub Zelenka)
|
||||
|
||||
02 Feb 2023, PHP 8.2.2
|
||||
|
||||
- Core:
|
||||
|
@ -230,6 +230,8 @@ PHP 8.2 UPGRADE NOTES
|
||||
- Standard
|
||||
. unserialize() now performs a stricter validation of the structure of serialized
|
||||
objects.
|
||||
. mail() function reverts back to the mixed LF and CRLF new lines (behavior
|
||||
before PHP 8.0) if mail.mixed_lf_and_crlf INI is on.
|
||||
|
||||
- XML
|
||||
. xml_parser_set_option() now actually returns false when attempting to set a
|
||||
|
@ -4128,7 +4128,9 @@ PHP_FUNCTION(mb_send_mail)
|
||||
|| orig_str.encoding->no_encoding == mbfl_no_encoding_pass) {
|
||||
orig_str.encoding = mbfl_identify_encoding(&orig_str, MBSTRG(current_detect_order_list), MBSTRG(current_detect_order_list_size), MBSTRG(strict_detection));
|
||||
}
|
||||
pstr = mbfl_mime_header_encode(&orig_str, &conv_str, tran_cs, head_enc, CRLF, sizeof("Subject: [PHP-jp nnnnnnnn]" CRLF) - 1);
|
||||
const char *line_sep = PG(mail_mixed_lf_and_crlf) ? "\n" : CRLF;
|
||||
size_t line_sep_len = strlen(line_sep);
|
||||
pstr = mbfl_mime_header_encode(&orig_str, &conv_str, tran_cs, head_enc, line_sep, strlen("Subject: [PHP-jp nnnnnnnn]") + line_sep_len);
|
||||
if (pstr != NULL) {
|
||||
subject_buf = subject = (char *)pstr->val;
|
||||
}
|
||||
@ -4167,14 +4169,14 @@ PHP_FUNCTION(mb_send_mail)
|
||||
n = ZSTR_LEN(str_headers);
|
||||
mbfl_memory_device_strncat(&device, p, n);
|
||||
if (n > 0 && p[n - 1] != '\n') {
|
||||
mbfl_memory_device_strncat(&device, CRLF, sizeof(CRLF)-1);
|
||||
mbfl_memory_device_strncat(&device, line_sep, line_sep_len);
|
||||
}
|
||||
zend_string_release_ex(str_headers, 0);
|
||||
}
|
||||
|
||||
if (!zend_hash_str_exists(&ht_headers, "mime-version", sizeof("mime-version") - 1)) {
|
||||
mbfl_memory_device_strncat(&device, PHP_MBSTR_MAIL_MIME_HEADER1, sizeof(PHP_MBSTR_MAIL_MIME_HEADER1) - 1);
|
||||
mbfl_memory_device_strncat(&device, CRLF, sizeof(CRLF)-1);
|
||||
mbfl_memory_device_strncat(&device, line_sep, line_sep_len);
|
||||
}
|
||||
|
||||
if (!suppressed_hdrs.cnt_type) {
|
||||
@ -4185,7 +4187,7 @@ PHP_FUNCTION(mb_send_mail)
|
||||
mbfl_memory_device_strncat(&device, PHP_MBSTR_MAIL_MIME_HEADER3, sizeof(PHP_MBSTR_MAIL_MIME_HEADER3) - 1);
|
||||
mbfl_memory_device_strcat(&device, p);
|
||||
}
|
||||
mbfl_memory_device_strncat(&device, CRLF, sizeof(CRLF)-1);
|
||||
mbfl_memory_device_strncat(&device, line_sep, line_sep_len);
|
||||
}
|
||||
if (!suppressed_hdrs.cnt_trans_enc) {
|
||||
mbfl_memory_device_strncat(&device, PHP_MBSTR_MAIL_MIME_HEADER4, sizeof(PHP_MBSTR_MAIL_MIME_HEADER4) - 1);
|
||||
@ -4194,10 +4196,12 @@ PHP_FUNCTION(mb_send_mail)
|
||||
p = "7bit";
|
||||
}
|
||||
mbfl_memory_device_strcat(&device, p);
|
||||
mbfl_memory_device_strncat(&device, CRLF, sizeof(CRLF)-1);
|
||||
mbfl_memory_device_strncat(&device, line_sep, line_sep_len);
|
||||
}
|
||||
|
||||
mbfl_memory_device_unput(&device);
|
||||
if (!PG(mail_mixed_lf_and_crlf)) {
|
||||
mbfl_memory_device_unput(&device);
|
||||
}
|
||||
mbfl_memory_device_unput(&device);
|
||||
mbfl_memory_device_output('\0', &device);
|
||||
str_headers = zend_string_init((char *)device.buffer, strlen((char *)device.buffer), 0);
|
||||
|
33
ext/mbstring/tests/gh8086.phpt
Normal file
33
ext/mbstring/tests/gh8086.phpt
Normal file
@ -0,0 +1,33 @@
|
||||
--TEST--
|
||||
GH-8086 (mb_send_mail() function not working correctly in PHP 8.x)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("mbstring")) die("skip mbstring extension not available");
|
||||
?>
|
||||
--INI--
|
||||
sendmail_path={MAIL:{PWD}/gh8086.eml}
|
||||
mail.mixed_lf_and_crlf=on
|
||||
--FILE--
|
||||
<?php
|
||||
mb_internal_encoding("UTF-8");
|
||||
mb_language("uni");
|
||||
$to = "omittedvalidaddress@example.com";
|
||||
$subject = "test mail";
|
||||
$message = "body of testing php mail";
|
||||
$header["Mime-Version"] = "1.0";
|
||||
$header["Content-Type"] = "text/html; charset=UTF-8";
|
||||
$header["From"] = "omittedvalidaddress2@example.com";
|
||||
$header["X-Mailer"] = "PHP/" . phpversion();
|
||||
mb_send_mail($to, $subject, $message, $header);
|
||||
|
||||
$stream = fopen(__DIR__ . "/gh8086.eml", "rb");
|
||||
$eml = stream_get_contents($stream);
|
||||
fclose($stream);
|
||||
var_dump(preg_match_all('/(?<!\r)\n/', $eml));
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
@unlink(__DIR__ . "/gh8086.eml");
|
||||
?>
|
||||
--EXPECT--
|
||||
int(6)
|
@ -429,6 +429,8 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co
|
||||
MAIL_RET(0);
|
||||
}
|
||||
|
||||
char *line_sep = PG(mail_mixed_lf_and_crlf) ? "\n" : "\r\n";
|
||||
|
||||
if (PG(mail_x_header)) {
|
||||
const char *tmp = zend_get_executed_filename();
|
||||
zend_string *f;
|
||||
@ -436,7 +438,7 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co
|
||||
f = php_basename(tmp, strlen(tmp), NULL, 0);
|
||||
|
||||
if (headers != NULL && *headers) {
|
||||
spprintf(&ahdr, 0, "X-PHP-Originating-Script: " ZEND_LONG_FMT ":%s\r\n%s", php_getuid(), ZSTR_VAL(f), headers);
|
||||
spprintf(&ahdr, 0, "X-PHP-Originating-Script: " ZEND_LONG_FMT ":%s%s%s", php_getuid(), ZSTR_VAL(f), line_sep, headers);
|
||||
} else {
|
||||
spprintf(&ahdr, 0, "X-PHP-Originating-Script: " ZEND_LONG_FMT ":%s", php_getuid(), ZSTR_VAL(f));
|
||||
}
|
||||
@ -510,12 +512,12 @@ PHPAPI int php_mail(const char *to, const char *subject, const char *message, co
|
||||
MAIL_RET(0);
|
||||
}
|
||||
#endif
|
||||
fprintf(sendmail, "To: %s\r\n", to);
|
||||
fprintf(sendmail, "Subject: %s\r\n", subject);
|
||||
fprintf(sendmail, "To: %s%s", to, line_sep);
|
||||
fprintf(sendmail, "Subject: %s%s", subject, line_sep);
|
||||
if (hdr != NULL) {
|
||||
fprintf(sendmail, "%s\r\n", hdr);
|
||||
fprintf(sendmail, "%s%s", hdr, line_sep);
|
||||
}
|
||||
fprintf(sendmail, "\r\n%s\r\n", message);
|
||||
fprintf(sendmail, "%s%s%s", line_sep, message, line_sep);
|
||||
ret = pclose(sendmail);
|
||||
|
||||
#if PHP_SIGCHILD
|
||||
|
18
ext/standard/tests/mail/gh8086.phpt
Normal file
18
ext/standard/tests/mail/gh8086.phpt
Normal file
@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
GH-8086 (Mail() function not working correctly in PHP 8.x)
|
||||
--INI--
|
||||
sendmail_path={MAIL:gh8086.out}
|
||||
mail.mixed_lf_and_crlf=on
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(mail('user@example.com', 'Test Subject', 'A Message', 'KHeaders'));
|
||||
$mail = file_get_contents('gh8086.out');
|
||||
var_dump(preg_match_all('/(?<!\r)\n/', $mail));
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
unlink('gh8086.out');
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
int(5)
|
@ -737,6 +737,7 @@ PHP_INI_BEGIN()
|
||||
PHP_INI_ENTRY("SMTP", "localhost",PHP_INI_ALL, NULL)
|
||||
PHP_INI_ENTRY("smtp_port", "25", PHP_INI_ALL, NULL)
|
||||
STD_PHP_INI_BOOLEAN("mail.add_x_header", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, mail_x_header, php_core_globals, core_globals)
|
||||
STD_PHP_INI_BOOLEAN("mail.mixed_lf_and_crlf", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, mail_mixed_lf_and_crlf, php_core_globals, core_globals)
|
||||
STD_PHP_INI_ENTRY("mail.log", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMailLog, mail_log, php_core_globals, core_globals)
|
||||
PHP_INI_ENTRY("browscap", NULL, PHP_INI_SYSTEM, OnChangeBrowscap)
|
||||
PHP_INI_ENTRY("memory_limit", "128M", PHP_INI_ALL, OnChangeMemoryLimit)
|
||||
|
@ -153,6 +153,7 @@ struct _php_core_globals {
|
||||
char *request_order;
|
||||
|
||||
bool mail_x_header;
|
||||
bool mail_mixed_lf_and_crlf;
|
||||
char *mail_log;
|
||||
|
||||
bool in_error_log;
|
||||
|
@ -1095,6 +1095,10 @@ smtp_port = 25
|
||||
; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename
|
||||
mail.add_x_header = Off
|
||||
|
||||
; Use mixed LF and CRLF line separators to keep compatibility with some
|
||||
; RFC 2822 non conformant MTA.
|
||||
mail.mixed_lf_and_crlf = Off
|
||||
|
||||
; The path to a log file that will log all mail() calls. Log entries include
|
||||
; the full path of the script, line number, To address and headers.
|
||||
;mail.log =
|
||||
|
@ -1097,6 +1097,10 @@ smtp_port = 25
|
||||
; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename
|
||||
mail.add_x_header = Off
|
||||
|
||||
; Use mixed LF and CRLF line separators to keep compatibility with some
|
||||
; RFC 2822 non conformant MTA.
|
||||
mail.mixed_lf_and_crlf = Off
|
||||
|
||||
; The path to a log file that will log all mail() calls. Log entries include
|
||||
; the full path of the script, line number, To address and headers.
|
||||
;mail.log =
|
||||
|
Loading…
Reference in New Issue
Block a user