Skip to content

Commit c5e7490

Browse files
lollipopmanbukka
authored andcommitted
mail: fix exit code handling of sendmail cmd
Prior to this commit the return code of the pclose function was assumed to be the exit code of the process. However, the returned value as specified in wait(2) is a bit packed integer and must be interpreted with the provided macros. This has no effect in success cases as the integer is still zero, but in failure cases the wrong value is used, since the 8 least significant bits contain the status code. After this commit we use the macros to obtain the status code, which fixes the EX_TEMPFAIL conditional. For WIN32 the TSRM popen_ex and pclose function are used. The return value of TSRM's pclose is not bit packed so we only check if the return value is non-zero, which should solve, #43327, https://bugs.php.net/bug.php?id=43327
1 parent d6fc743 commit c5e7490

File tree

4 files changed

+93
-5
lines changed

4 files changed

+93
-5
lines changed

ext/standard/mail.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
#include "ext/date/php_date.h"
2626
#include "zend_smart_str.h"
2727

28+
#ifdef HAVE_SYS_WAIT_H
29+
#include <sys/wait.h>
30+
#endif
31+
2832
#ifdef HAVE_SYSEXITS_H
2933
# include <sysexits.h>
3034
#endif
@@ -562,6 +566,7 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c
562566
}
563567

564568
if (sendmail) {
569+
int ret;
565570
#ifndef PHP_WIN32
566571
if (EACCES == errno) {
567572
php_error_docref(NULL, E_WARNING, "Permission denied: unable to execute shell to run mail delivery binary '%s'", sendmail_path);
@@ -582,24 +587,41 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c
582587
fprintf(sendmail, "%s%s", hdr, line_sep);
583588
}
584589
fprintf(sendmail, "%s%s%s", line_sep, message, line_sep);
585-
int ret = pclose(sendmail);
590+
#ifdef PHP_WIN32
591+
ret = pclose(sendmail);
586592

587593
#if PHP_SIGCHILD
588594
if (sig_handler) {
589595
signal(SIGCHLD, sig_handler);
590596
}
591597
#endif
592-
593-
#ifdef PHP_WIN32
594-
if (ret == -1)
595598
#else
599+
int wstatus = pclose(sendmail);
600+
#if PHP_SIGCHILD
601+
if (sig_handler) {
602+
signal(SIGCHLD, sig_handler);
603+
}
604+
#endif
605+
/* Determine the wait(2) exit status */
606+
if (wstatus == -1) {
607+
MAIL_RET(false);
608+
} else if (WIFSIGNALED(wstatus)) {
609+
MAIL_RET(false);
610+
} else {
611+
if (WIFEXITED(wstatus)) {
612+
ret = WEXITSTATUS(wstatus);
613+
} else {
614+
MAIL_RET(false);
615+
}
616+
}
617+
#endif
618+
596619
#if defined(EX_TEMPFAIL)
597620
if ((ret != EX_OK)&&(ret != EX_TEMPFAIL))
598621
#elif defined(EX_OK)
599622
if (ret != EX_OK)
600623
#else
601624
if (ret != 0)
602-
#endif
603625
#endif
604626
{
605627
MAIL_RET(false);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Test mail() function : variation sendmail temp fail
3+
--INI--
4+
sendmail_path=exit 75
5+
--SKIPIF--
6+
<?php
7+
if (substr(PHP_OS, 0, 3) == "WIN")
8+
die("skip Won't run on Windows");
9+
?>
10+
--FILE--
11+
<?php
12+
echo "*** Testing mail() : variation ***\n";
13+
14+
// Initialise all required variables
15+
16+
$subject = 'Test Subject';
17+
$message = 'A Message';
18+
var_dump(mail($to, $subject, $message));
19+
?>
20+
--EXPECT--
21+
*** Testing mail() : variation ***
22+
bool(true)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Test mail() function : variation sigterm
3+
--INI--
4+
sendmail_path="kill \$\$"
5+
--SKIPIF--
6+
<?php
7+
if (substr(PHP_OS, 0, 3) == "WIN")
8+
die("skip Won't run on Windows");
9+
?>
10+
--FILE--
11+
<?php
12+
echo "*** Testing mail() : variation ***\n";
13+
14+
// Initialise all required variables
15+
16+
$subject = 'Test Subject';
17+
$message = 'A Message';
18+
var_dump(mail($to, $subject, $message));
19+
?>
20+
--EXPECT--
21+
*** Testing mail() : variation ***
22+
bool(false)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Test mail() function : variation non-zero exit
3+
--INI--
4+
sendmail_path="exit 123"
5+
--SKIPIF--
6+
<?php
7+
if (substr(PHP_OS, 0, 3) == "WIN")
8+
die("skip Won't run on Windows");
9+
?>
10+
--FILE--
11+
<?php
12+
echo "*** Testing mail() : variation ***\n";
13+
14+
// Initialise all required variables
15+
16+
$subject = 'Test Subject';
17+
$message = 'A Message';
18+
var_dump(mail($to, $subject, $message));
19+
?>
20+
--EXPECT--
21+
*** Testing mail() : variation ***
22+
bool(false)

0 commit comments

Comments
 (0)