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

Always timeout in class.phpmailer.php on 754 #41

Closed
tempslar opened this issue Apr 9, 2013 · 17 comments
Closed

Always timeout in class.phpmailer.php on 754 #41

tempslar opened this issue Apr 9, 2013 · 17 comments

Comments

@tempslar
Copy link

tempslar commented Apr 9, 2013

When I'm using phpmailer on a Server CentOS 6.4, php 5.4.4( XAMPP ), and PCRE_VERSION 8.12 2011-01-15, I always got Fatal error: Maximum execution time of 30 seconds exceeded in /class.phpmailer.php on line 754. I find that is a method ValidateAddress(), which uses regular expression. After I commented regular expressions , the script can complete.
Besides the same script regular expression version run normally on my windows pc.

@vicary
Copy link

vicary commented Apr 9, 2013

This is strange, I have my fork replaced with the 23K pattern found here and it only takes 0.08 - 0.15 secs more for each address.

@Synchro
Copy link
Member

Synchro commented Apr 9, 2013

I think this has to be something up with your server - it's just a regular expression. If you extract it and run it by itself (outside PHPMailer) do you still have a problem?

@tempslar
Copy link
Author

I extract it and put it in a new file, and run it on the same server. there is no problem. It finished in 0.011907815933228s
Blew is my code:

' . $email . "\n"; var_dump( $result ); } else { die("No input\n"); } $endtime = microtime( true ) - $starttime; exit( $endtime ); /\* The code i extract form PHP Mailer */ function ValidateAddress( $address ) { ``` if (defined('PCRE_VERSION')) { //Check this instead of extension_loaded so it works when that function is disabled if (version_compare(PCRE_VERSION, '8.0') >= 0) { return (boolean)preg_match('/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD', $address);
} else {

//Fall back to an older regex that doesn't need a recent PCRE
return (boolean)preg_match('/^(?!(?>"?(?>\[ -]|[^"])"?){255,})(?!(?>"?(?>\[ -]|[^"])"?){65,}@)(?>[!#-'+/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-[]-\x7F]|\[\x00-\xFF]))")(?>.(?>[!#-'+/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-[]-\x7F]|\[\x00-\xFF]))"))@(?>(?![a-z0-9-]{64,})(?>a-z0-9?)(?>.(?![a-z0-9-]{64,})(?>a-z0-9?)){0,126}|[(?:(?>IPv6:(?>(?>[a-f0-9]{1,4})(?>:[a-f0-9]{1,4}){7}|(?!(?:.[a-f0-9][:]]){8,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?::(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?))|(?>(?>IPv6:(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){5}:|(?!(?:.*[a-f0-9]:){6,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4})?::(?>(?:[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4}):)?))?(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))])$/isD', $address);
}
} else {
//No PCRE! Do something very approximate!
//Check the address is 3 chars or longer and contains an @ that's not the first or last char
return (strlen($address) >= 3 and strpos($address, '@') >= 1 and strpos($address, '@') != strlen($address) - 1);
}


}

@Synchro
Copy link
Member

Synchro commented Apr 12, 2013

If you try using it inside PHPMailer does it make a difference? Like this:

<?php
$starttime = microtime( true );
$email = isset( $argv[ 1 ] ) ? trim( $argv[ 1 ] ) : null;

if ( $email ) {
require 'class.phpmailer.php';
$p = new PHPMailer;
$starttime = microtime( true );
$result = $p->ValidateAddress( $email );
echo 'Email->' . $email . "\n";
var_dump( $result );
}
else {
die("No input\n");
}
$endtime = microtime( true ) - $starttime;
exit( $endtime );

@Synchro
Copy link
Member

Synchro commented Apr 30, 2013

Have you got to the bottom of this?

@Synchro
Copy link
Member

Synchro commented May 6, 2013

No movement, closing.

@Synchro Synchro closed this as completed May 6, 2013
@nagamiki
Copy link

hello all,
I am new to phpmailer and meet the same problem as described above, could anyone please share the solution to this issue? my server is running on ubuntu with xampp 1.8.1. If i comments the statements in function ValidateAddress() the $mail->send() always return false.
It's strange that the same php script is running perfect on my mac mamp server.
thanks for help.

@Synchro
Copy link
Member

Synchro commented Jun 19, 2013

It will always return false because commenting out the validation lines will prevent it adding addresses, so you'll be trying to send without an address. Checking a few return values wouldn't hurt either.

@Muqito
Copy link

Muqito commented Jun 19, 2013

I had the same problem, removed the:

if (version_compare(PCRE_VERSION, '8.0') >= 0) {
    return (boolean)preg_match('/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD', $address);
}

and the else brackets. But I guess this eats too much memory or something, causing it not to finnish properly.

@tempslar
Copy link
Author

tempslar commented Jul 4, 2013

Sorry to Reply so late. I ran your code, and it finished so quickly, well that's very weird.
Result:
$ php test.php 'abc@gmail.com'
Email->abc@gmail.com
bool(true)
0.013795137405396

@ccoltman
Copy link

ccoltman commented Aug 7, 2013

I had the exact same experience as above, with the CPU pinning at 100% and executing until timeout at 30s. PHP version 5.4.7, PCRE version 8.12 (quad core 3.4GHz w/16GB)

The solution was to change the PCRE to something I found on hacksparrow.com for a RFC2822 email regex:

          return (boolean)preg_match("/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/g", $address);

After this it worked for standard email addresses. Strange/rare "valid" emails would not pass, nor would local addresses. I'm sure this could be improved, but at least it got things mailing.

@Synchro
Copy link
Member

Synchro commented Aug 7, 2013

In the smtp-refactor branch, you can choose which validator pattern to use. The older pattern that's in PHPMailer already does not have this problem either.

@jimjag
Copy link
Contributor

jimjag commented Aug 7, 2013

This is exactly why ValidateAddress is public static.

On Wed, Aug 7, 2013 at 3:41 AM, ccoltman notifications@github.com wrote:

I had the exact same experience as above, with the CPU pinning at 100% and
executing until timeout at 30s. PHP version 5.4.7, PCRE version 8.12 (quad
core 3.4GHz w/16GB)

The solution was to change the PCRE to something I found on
hacksparrow.com for a RFC2822 email regex:

      return (boolean)preg_match("/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/g", $address);

After this it worked for standard email addresses. Strange/rare "valid"
emails would not pass, nor would local addresses. I'm sure this could be
improved, but at least it got things mailing.


Reply to this email directly or view it on GitHubhttps://github.com//issues/41#issuecomment-22234815
.

@ccoltman
Copy link

ccoltman commented Aug 7, 2013

Hi jimjag I'm not sure what to do with that information. If I can set or change an option in the validation I haven't figured out how to do that yet.

I'm hard coding the email addresses to my own valid public address, sending the request to my public mail server with my mail account on it, and it hangs on the ValidateAddress function even though it should pass with flying colours.

@Synchro
Copy link
Member

Synchro commented Aug 7, 2013

Jim's saying that if you have trouble, you can simply override the method in your own subclass. In the branch I mentioned, the validate function allows you to select which validator it uses.

@ccoltman
Copy link

ccoltman commented Aug 7, 2013

OK thanks, I'll hit the docs on that branch and see if I can figure out how to select the validator manually. I'm not constructing the call myself (it's built into a CMS), so please excuse my inexperience here.

@RodionGork
Copy link

I do not know whether this could be of any help for developers, but the problem is well reproduced with:

  • Lampp (Xampp) 1.8 (on Ubuntu), PHP 5.4.4, PCRE 8.12;
  • code taken from examples/test_smtp_advanced.php.

(with the line changed to "return true;" library works fine - thanks for it)

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

8 participants