php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #43327 wrong return value from mail(), if sendmail_path is wrong
Submitted: 2007-11-19 01:40 UTC Modified: 2018-03-13 15:43 UTC
Votes:8
Avg. Score:4.5 ± 0.9
Reproduced:6 of 7 (85.7%)
Same Version:3 (50.0%)
Same OS:1 (16.7%)
From: carsten_sttgt at gmx dot de Assigned:
Status: Verified Package: Mail related
PHP Version: 7.2 OS: win32 only (?)
Private report: No CVE-ID: None
 [2007-11-19 01:40 UTC] carsten_sttgt at gmx dot de
Description:
------------
Hello,

on Windows, mail() allways returns true, regardless if sendmail_path is wrong, or sendmail returns an error code.

Regards,
Carsten


Reproduce code:
---------------
<?php
error_reporting(E_ALL);

$return = mail('mail@example.com', 'Test', 'Test');
var_dump($return);
?>


Expected result:
----------------
Like on *nix:
| % ./php -d sendmail_path=/foo/bar test.php
| /foo/bar: not found
| bool(false)
| %


Actual result:
--------------
On Windows:
| D:\PHP>php -d sendmail_path=/foo/bar test.php
| bool(true)
|
| D:\PHP>


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-11-19 13:24 UTC] jani@php.net
Are you sure the path is actually set? Try this:

php -d sendmail_path=/foo/bar -r 'var_dump(ini_get("sendmail_path"));'

 [2007-11-19 13:46 UTC] carsten_sttgt at gmx dot de
> Are you sure the path is actually set? Try this:

Yes:
| D:\PHP>php -d sendmail_path=/foo/bar -r \
| "var_dump(ini_get('sendmail_path'));"
| string(8) "/foo/bar"
|
|D:\PHP>

Of course, setting "sendmail_path" from the command line was just for you. The same happens if I set a wrong sendmail_path in "php.ini".

And as I've written above:
mail() returns also TRUE, if "sendmail_path" is correct, but the sendmail binary exit with an error code != 0.
 [2007-11-19 14:40 UTC] jani@php.net
Propably due to wrong usage of popen() and not VCWD_POPEN(). I don't have win32 dev environment setup so someone else should deal with this.
 [2008-01-18 21:52 UTC] aaron at gwmicro dot com
I have confirmed this issue under a Windows Server 2003 environment, and it continues to exist in 5.3 dev. Using the imap_mail.dll and changing all references from mail() to imap_mail() seems to resolve the problem, although changing that reference everywhere is not a reasonable solution for most everyone (including us).
 [2008-08-26 23:28 UTC] jani@php.net
Pierre, this is the real issue, sendmail_path is not checked or something?
 [2009-07-20 10:08 UTC] carsten_sttgt at gmx dot de
After some delay...

If've just test this with PHP 5.3.0 and mail() still returns TRUE, even if PHP can't find the sendmail binary or the sendmail binary returns an errorlevel != 0.

Regards,
Carsten)
 [2009-08-19 16:10 UTC] garretts@php.net
This occurs because popen_ex executes the command using the comspec ('cmd.exe'), which will always create a valid process--but intended actual child process fails.

I'm patching this so that it skips using cmd.exe--there is really no reason this should be here, if this introduces other problems (which I can't see what they could possibly be), then those should be fixed appropriately.

Patched in all branches (5.2.11-dev, 5.3.1-dev and trunk)

 [2009-08-19 16:15 UTC] garretts@php.net
or, it will be once I get some karma in /TSRM ...

 [2009-08-19 18:43 UTC] svn@php.net
Automatic comment from SVN on behalf of pajoye
Revision: http://svn.php.net/viewvc/?view=revision&revision=287480
Log: - fixed #43327, wrong return value from mail(), if sendmail_path is wrong
 [2009-08-19 18:56 UTC] garretts@php.net
Carsten, 

Can you retest with the latest 5.3 snapshot, and post feedback?

Thanks

 [2009-08-20 01:56 UTC] carsten_sttgt at gmx dot de
Hi Garrett,

> Can you retest with the latest 5.3 snapshot, and post feedback?

I can do this. Just some remarks first:


> This occurs because popen_ex executes the command using the comspec
> ('cmd.exe'), which will always create a valid process--but intended
> actual child process fails.

That's correct. No error during creation of the process ("cmd.exe" / "GetLastError == 0"). But in this case, "cmd.exe" returns an exit code != 0, which is available with "GetExitCodeProcess()".  So you know there's a problem.

Regarding mail():
- mail() does not detect that "cmd.exe" can't start "sendmail.exe"

- it also does not detect, if "cmd.exe" can start "sendmail.exe",
  but "sendmail.exe" is returning an exit code != 0
  --> if "cmd.exe" can start a program, it's returning the exit
      code from that program, and so this is available with 
      GetExitCodeProcess().

So there is the question, why does mail() does not test the return value of pclose() in a correct way on windows? At the moment it looks like:
| #ifdef PHP_WIN32
| if (ret == -1)
| {
|     MAIL_RET(0);
| } else {
|    MAIL_RET(1);
| }

But I think it should be also something like?:
| if (ret != 0)


> I'm patching this so that it skips using cmd.exe--there is really
> no reason this should be here,

Some hints:
- If you want start an executable with just the name and without the
  extension (like ".com, *.pl"), you must do this through "cmd.exe"
  (only for "*.exe" files you can use just the name).
- In the MSDN you can read, that you have to use "cmd.exe" to start
  a batchfile with CreateProcess. Ok, for me that's working without
  "cmd.exe". But maybe this depends on the Windows version or
  compiler.

Regards,
Carsten
 [2009-08-20 09:03 UTC] svn@php.net
Automatic comment from SVN on behalf of pajoye
Revision: http://svn.php.net/viewvc/?view=revision&revision=287495
Log: - revert fix for #43327, it breaks system&co functions
 [2009-08-20 10:39 UTC] jani@php.net
Reopened, fix was reverted.
 [2010-06-13 15:20 UTC] felipe@php.net
-Status: Assigned +Status: Open -Assigned To: garretts +Assigned To:
 [2012-12-07 12:54 UTC] pajoye@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: pajoye
 [2017-10-24 07:35 UTC] kalle@php.net
-Status: Assigned +Status: Open -Assigned To: pajoye +Assigned To:
 [2018-03-13 15:43 UTC] cmb@php.net
-Status: Open +Status: Verified -PHP Version: 5.*, 6 (2009-08-07) +PHP Version: 7.2
 [2018-03-13 15:43 UTC] cmb@php.net
Still unresolved.  The culprit indeed appears to be that FALSE
will only be returned, if pclose() returns -1[1], but pclose()
actually returns the exit code[2], where other values may signal
failure as well.

[1] <https://github.com/php/php-src/blob/PHP-7.2.4/ext/standard/mail.c#L618>
[2] <https://github.com/php/php-src/blob/PHP-7.2.4/TSRM/tsrm_win32.c#L633-L637>
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Oct 14 11:01:27 2024 UTC