Make WordPress Core

Ticket #28909: 28909.2.diff

File 28909.2.diff, 117.9 KB (added by michalzuber, 10 years ago)

Changed class-pop3.php

  • src/wp-includes/class-phpmailer.php

    diff --git a/src/wp-includes/class-phpmailer.php b/src/wp-includes/class-phpmailer.php
    index c38632a..059ec28 100644
    a b  
    11<?php
    22/**
    33 * PHPMailer - PHP email creation and transport class.
    4  * PHP Version 5.0.0
    5  * Version 5.2.7
     4 * PHP Version 5
    65 * @package PHPMailer
    7  * @link https://github.com/PHPMailer/PHPMailer/
    8  * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
     6 * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
     7 * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
    98 * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
    109 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
    1110 * @author Brent R. Matzelle (original founder)
    12  * @copyright 2013 Marcus Bointon
     11 * @copyright 2012 - 2014 Marcus Bointon
    1312 * @copyright 2010 - 2012 Jim Jagielski
    1413 * @copyright 2004 - 2009 Andy Prevost
    1514 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
     
    1817 * FITNESS FOR A PARTICULAR PURPOSE.
    1918 */
    2019
    21 if (version_compare(PHP_VERSION, '5.0.0', '<')) {
    22     exit("Sorry, PHPMailer will only run on PHP version 5 or greater!\n");
    23 }
    24 
    2520/**
    2621 * PHPMailer - PHP email creation and transport class.
    27  * PHP Version 5.0.0
    2822 * @package PHPMailer
    29  * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
     23 * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
    3024 * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
    3125 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
    3226 * @author Brent R. Matzelle (original founder)
    33  * @copyright 2013 Marcus Bointon
    34  * @copyright 2010 - 2012 Jim Jagielski
    35  * @copyright 2004 - 2009 Andy Prevost
    3627 */
    3728class PHPMailer
    3829{
    class PHPMailer 
    4031     * The PHPMailer Version number.
    4132     * @type string
    4233     */
    43     public $Version = '5.2.7';
     34    public $Version = '5.2.8';
    4435
    4536    /**
    4637     * Email priority.
    class PHPMailer 
    9788     * The Return-Path of the message.
    9889     * If empty, it will be set to either From or Sender.
    9990     * @type string
     91     * @deprecated Email senders should never set a return-path header;
     92     * it's the receiver's job (RFC5321 section 4.4), so this no longer does anything.
     93     * @link https://tools.ietf.org/html/rfc5321#section-4.4 RFC5321 reference
    10094     */
    10195    public $ReturnPath = '';
    10296
    class PHPMailer 
    299293
    300294    /**
    301295     * SMTP class debug output mode.
    302      * Options: 0 = off, 1 = commands, 2 = commands and data
     296     * Options:
     297     *   0: no output
     298     *   1: commands
     299     *   2: data and commands
     300     *   3: as 2 plus connection status
     301     *   4: low level data output
    303302     * @type int
    304303     * @see SMTP::$do_debug
    305304     */
    306305    public $SMTPDebug = 0;
    307306
    308307    /**
    309      * The function/method to use for debugging output.
    310      * Options: "echo" or "error_log"
     308     * How to handle debug output.
     309     * Options:
     310     *   'echo': Output plain-text as-is, appropriate for CLI
     311     *   'html': Output escaped, line breaks converted to <br>, appropriate for browser output
     312     *   'error_log': Output to error log as configured in php.ini
    311313     * @type string
    312314     * @see SMTP::$Debugoutput
    313315     */
    314     public $Debugoutput = "echo";
     316    public $Debugoutput = 'echo';
    315317
    316318    /**
    317319     * Whether to keep SMTP connection open after each message.
    class PHPMailer 
    339341     * Whether to generate VERP addresses on send.
    340342     * Only applicable when sending via SMTP.
    341343     * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path
     344     * @link http://www.postfix.org/VERP_README.html Postfix VERP info
    342345     * @type bool
    343346     */
    344347    public $do_verp = false;
    class PHPMailer 
    396399     * The function that handles the result of the send email action.
    397400     * It is called out by send() for each email sent.
    398401     *
    399      * Value can be:
    400      * - 'function_name' for function names
    401      * - 'Class::Method' for static method calls
    402      * - array($object, 'Method') for calling methods on $object
    403      * See http://php.net/is_callable manual page for more details.
     402     * Value can be any php callable: http://www.php.net/is_callable
    404403     *
    405404     * Parameters:
    406405     *   bool    $result        result of the send action
    class PHPMailer 
    410409     *   string  $subject       the subject
    411410     *   string  $body          the email body
    412411     *   string  $from          email address of sender
    413      *
    414412     * @type string
    415413     */
    416414    public $action_function = '';
    class PHPMailer 
    597595     */
    598596    private function mailPassthru($to, $subject, $body, $header, $params)
    599597    {
     598        //Check overloading of mail function to avoid double-encoding
     599        if (ini_get('mbstring.func_overload') & 1) {
     600            $subject = $this->secureHeader($subject);
     601        } else {
     602            $subject = $this->encodeHeader($this->secureHeader($subject));
     603        }
    600604        if (ini_get('safe_mode') || !($this->UseSendmailOptions)) {
    601             $rt = @mail($to, $this->encodeHeader($this->secureHeader($subject)), $body, $header);
     605            $result = @mail($to, $subject, $body, $header);
    602606        } else {
    603             $rt = @mail($to, $this->encodeHeader($this->secureHeader($subject)), $body, $header, $params);
     607            $result = @mail($to, $subject, $body, $header, $params);
    604608        }
    605         return $rt;
     609        return $result;
    606610    }
    607611
    608612    /**
    class PHPMailer 
    627631                break;
    628632            case 'echo':
    629633            default:
    630                 //Just echoes exactly what was received
    631                 echo $str;
     634                echo $str."\n";
    632635        }
    633636    }
    634637
    class PHPMailer 
    670673     */
    671674    public function isSendmail()
    672675    {
    673         if (!stristr(ini_get('sendmail_path'), 'sendmail')) {
    674             $this->Sendmail = '/var/qmail/bin/sendmail';
     676        $ini_sendmail_path = ini_get('sendmail_path');
     677       
     678        if (!stristr($ini_sendmail_path, 'sendmail')) {
     679            $this->Sendmail = '/usr/sbin/sendmail';
     680        } else {
     681            $this->Sendmail = $ini_sendmail_path;
    675682        }
    676683        $this->Mailer = 'sendmail';
    677684    }
    class PHPMailer 
    682689     */
    683690    public function isQmail()
    684691    {
    685         if (stristr(ini_get('sendmail_path'), 'qmail')) {
    686             $this->Sendmail = '/var/qmail/bin/sendmail';
     692        $ini_sendmail_path = ini_get('sendmail_path');
     693       
     694        if (!stristr($ini_sendmail_path, 'qmail')) {
     695            $this->Sendmail = '/var/qmail/bin/qmail-inject';
     696        } else {
     697            $this->Sendmail = $ini_sendmail_path;
    687698        }
    688         $this->Mailer = 'sendmail';
     699        $this->Mailer = 'qmail';
    689700    }
    690701
    691702    /**
    class PHPMailer 
    748759    {
    749760        if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) {
    750761            $this->setError($this->lang('Invalid recipient array') . ': ' . $kind);
     762            $this->edebug($this->lang('Invalid recipient array') . ': ' . $kind);
    751763            if ($this->exceptions) {
    752764                throw new phpmailerException('Invalid recipient array: ' . $kind);
    753765            }
    754             $this->edebug($this->lang('Invalid recipient array') . ': ' . $kind);
    755766            return false;
    756767        }
    757768        $address = trim($address);
    758769        $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
    759770        if (!$this->validateAddress($address)) {
    760771            $this->setError($this->lang('invalid_address') . ': ' . $address);
     772            $this->edebug($this->lang('invalid_address') . ': ' . $address);
    761773            if ($this->exceptions) {
    762774                throw new phpmailerException($this->lang('invalid_address') . ': ' . $address);
    763775            }
    764             $this->edebug($this->lang('invalid_address') . ': ' . $address);
    765776            return false;
    766777        }
    767778        if ($kind != 'Reply-To') {
    class PHPMailer 
    793804        $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
    794805        if (!$this->validateAddress($address)) {
    795806            $this->setError($this->lang('invalid_address') . ': ' . $address);
     807            $this->edebug($this->lang('invalid_address') . ': ' . $address);
    796808            if ($this->exceptions) {
    797809                throw new phpmailerException($this->lang('invalid_address') . ': ' . $address);
    798810            }
    799             $this->edebug($this->lang('invalid_address') . ': ' . $address);
    800811            return false;
    801812        }
    802813        $this->From = $address;
    class PHPMailer 
    825836     * Check that a string looks like an email address.
    826837     * @param string $address The email address to check
    827838     * @param string $patternselect A selector for the validation pattern to use :
    828      *   'auto' - pick best one automatically;
    829      *   'pcre8' - use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;
    830      *   'pcre' - use old PCRE implementation;
    831      *   'php' - use PHP built-in FILTER_VALIDATE_EMAIL; faster, less thorough;
    832      *   'noregex' - super fast, really dumb.
     839     * * `auto` Pick strictest one automatically;
     840     * * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;
     841     * * `pcre` Use old PCRE implementation;
     842     * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL; same as pcre8 but does not allow 'dotless' domains;
     843     * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements.
     844     * * `noregex` Don't use a regex: super fast, really dumb.
    833845     * @return bool
    834846     * @static
    835847     * @access public
    836848     */
    837849    public static function validateAddress($address, $patternselect = 'auto')
    838850    {
    839         if ($patternselect == 'auto') {
    840             if (defined(
    841                 'PCRE_VERSION'
    842             )
    843             ) { //Check this instead of extension_loaded so it works when that function is disabled
     851        if (!$patternselect or $patternselect == 'auto') {
     852            if (defined('PCRE_VERSION')) { //Check this constant so it works when extension_loaded() is disabled
    844853                if (version_compare(PCRE_VERSION, '8.0') >= 0) {
    845854                    $patternselect = 'pcre8';
    846855                } else {
    class PHPMailer 
    858867        switch ($patternselect) {
    859868            case 'pcre8':
    860869                /**
    861                  * Conforms to RFC5322: Uses *correct* regex on which FILTER_VALIDATE_EMAIL is
    862                  * based; So why not use FILTER_VALIDATE_EMAIL? Because it was broken to
    863                  * not allow a@b type valid addresses :(
     870                 * Uses the same RFC5322 regex on which FILTER_VALIDATE_EMAIL is based, but allows dotless domains.
    864871                 * @link http://squiloople.com/2009/12/20/email-address-validation/
    865872                 * @copyright 2009-2010 Michael Rushton
    866873                 * Feel free to use and redistribute this code. But please keep this copyright notice.
    class PHPMailer 
    894901                    $address
    895902                );
    896903                break;
     904            case 'html5':
     905                /**
     906                 * This is the pattern used in the HTML5 spec for validation of 'email' type form input elements.
     907                 * @link http://www.whatwg.org/specs/web-apps/current-work/#e-mail-state-(type=email)
     908                 */
     909                return (bool)preg_match('/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' .
     910                    '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD', $address);
     911                break;
    897912            case 'php':
    898913            default:
    899914                return (bool)filter_var($address, FILTER_VALIDATE_EMAIL);
    class PHPMailer 
    911926    /**
    912927     * Create a message and send it.
    913928     * Uses the sending method specified by $Mailer.
    914      * Returns false on error - Use the ErrorInfo variable to view description of the error.
    915929     * @throws phpmailerException
    916      * @return bool
     930     * @return bool false on error - See the ErrorInfo property for details of the error.
    917931     */
    918932    public function send()
    919933    {
    class PHPMailer 
    922936                return false;
    923937            }
    924938            return $this->postSend();
    925         } catch (phpmailerException $e) {
     939        } catch (phpmailerException $exc) {
    926940            $this->mailHeader = '';
    927             $this->setError($e->getMessage());
     941            $this->setError($exc->getMessage());
    928942            if ($this->exceptions) {
    929                 throw $e;
     943                throw $exc;
    930944            }
    931945            return false;
    932946        }
    class PHPMailer 
    940954    public function preSend()
    941955    {
    942956        try {
    943             $this->mailHeader = "";
     957            $this->mailHeader = '';
    944958            if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
    945959                throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL);
    946960            }
    class PHPMailer 
    964978            // an extra header list which createHeader() doesn't fold in
    965979            if ($this->Mailer == 'mail') {
    966980                if (count($this->to) > 0) {
    967                     $this->mailHeader .= $this->addrAppend("To", $this->to);
     981                    $this->mailHeader .= $this->addrAppend('To', $this->to);
    968982                } else {
    969                     $this->mailHeader .= $this->headerLine("To", "undisclosed-recipients:;");
     983                    $this->mailHeader .= $this->headerLine('To', 'undisclosed-recipients:;');
    970984                }
    971985                $this->mailHeader .= $this->headerLine(
    972986                    'Subject',
    class PHPMailer 
    9901004            }
    9911005            return true;
    9921006
    993         } catch (phpmailerException $e) {
    994             $this->setError($e->getMessage());
     1007        } catch (phpmailerException $exc) {
     1008            $this->setError($exc->getMessage());
    9951009            if ($this->exceptions) {
    996                 throw $e;
     1010                throw $exc;
    9971011            }
    9981012            return false;
    9991013        }
    class PHPMailer 
    10111025            // Choose the mailer and send through it
    10121026            switch ($this->Mailer) {
    10131027                case 'sendmail':
     1028                case 'qmail':
    10141029                    return $this->sendmailSend($this->MIMEHeader, $this->MIMEBody);
    10151030                case 'smtp':
    10161031                    return $this->smtpSend($this->MIMEHeader, $this->MIMEBody);
    10171032                case 'mail':
    10181033                    return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
    10191034                default:
     1035                    $sendMethod = $this->Mailer.'Send';
     1036                    if (method_exists($this, $sendMethod)) {
     1037                        return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);
     1038                    }
     1039                   
    10201040                    return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
    10211041            }
    1022         } catch (phpmailerException $e) {
    1023             $this->setError($e->getMessage());
     1042        } catch (phpmailerException $exc) {
     1043            $this->setError($exc->getMessage());
     1044            $this->edebug($exc->getMessage());
    10241045            if ($this->exceptions) {
    1025                 throw $e;
     1046                throw $exc;
    10261047            }
    1027             $this->edebug($e->getMessage() . "\n");
    10281048        }
    10291049        return false;
    10301050    }
    class PHPMailer 
    10411061    protected function sendmailSend($header, $body)
    10421062    {
    10431063        if ($this->Sender != '') {
    1044             $sendmail = sprintf("%s -oi -f%s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
     1064            if ($this->Mailer == 'qmail') {
     1065                $sendmail = sprintf('%s -f%s', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
     1066            } else {
     1067                $sendmail = sprintf('%s -oi -f%s -t', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
     1068            }
    10451069        } else {
    1046             $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
     1070            if ($this->Mailer == 'qmail') {
     1071                $sendmail = sprintf('%s', escapeshellcmd($this->Sendmail));
     1072            } else {
     1073                $sendmail = sprintf('%s -oi -t', escapeshellcmd($this->Sendmail));
     1074            }
    10471075        }
    10481076        if ($this->SingleTo === true) {
    10491077            foreach ($this->SingleToArray as $val) {
    10501078                if (!@$mail = popen($sendmail, 'w')) {
    10511079                    throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
    10521080                }
    1053                 fputs($mail, "To: " . $val . "\n");
     1081                fputs($mail, 'To: ' . $val . "\n");
    10541082                fputs($mail, $header);
    10551083                fputs($mail, $body);
    10561084                $result = pclose($mail);
    class PHPMailer 
    10901118    protected function mailSend($header, $body)
    10911119    {
    10921120        $toArr = array();
    1093         foreach ($this->to as $t) {
    1094             $toArr[] = $this->addrFormat($t);
     1121        foreach ($this->to as $toaddr) {
     1122            $toArr[] = $this->addrFormat($toaddr);
    10951123        }
    10961124        $to = implode(', ', $toArr);
    10971125
    10981126        if (empty($this->Sender)) {
    1099             $params = " ";
     1127            $params = ' ';
    11001128        } else {
    1101             $params = sprintf("-f%s", $this->Sender);
     1129            $params = sprintf('-f%s', $this->Sender);
    11021130        }
    11031131        if ($this->Sender != '' and !ini_get('safe_mode')) {
    11041132            $old_from = ini_get('sendmail_from');
    11051133            ini_set('sendmail_from', $this->Sender);
    11061134        }
    1107         $rt = false;
     1135        $result = false;
    11081136        if ($this->SingleTo === true && count($toArr) > 1) {
    11091137            foreach ($toArr as $val) {
    1110                 $rt = $this->mailPassthru($val, $this->Subject, $body, $header, $params);
     1138                $result = $this->mailPassthru($val, $this->Subject, $body, $header, $params);
    11111139                // implement call back function if it exists
    1112                 $isSent = ($rt == 1) ? 1 : 0;
     1140                $isSent = ($result == 1) ? 1 : 0;
    11131141                $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
    11141142            }
    11151143        } else {
    1116             $rt = $this->mailPassthru($to, $this->Subject, $body, $header, $params);
     1144            $result = $this->mailPassthru($to, $this->Subject, $body, $header, $params);
    11171145            // implement call back function if it exists
    1118             $isSent = ($rt == 1) ? 1 : 0;
     1146            $isSent = ($result == 1) ? 1 : 0;
    11191147            $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
    11201148        }
    11211149        if (isset($old_from)) {
    11221150            ini_set('sendmail_from', $old_from);
    11231151        }
    1124         if (!$rt) {
     1152        if (!$result) {
    11251153            throw new phpmailerException($this->lang('instantiate'), self::STOP_CRITICAL);
    11261154        }
    11271155        return true;
    class PHPMailer 
    11351163    public function getSMTPInstance()
    11361164    {
    11371165        if (!is_object($this->smtp)) {
    1138             require_once 'class-smtp.php';
     1166                        require_once 'class-smtp.php';
    11391167            $this->smtp = new SMTP;
    11401168        }
    11411169        return $this->smtp;
    class PHPMailer 
    11661194            throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL);
    11671195        }
    11681196
    1169         // Attempt to send attach all recipients
     1197        // Attempt to send to all recipients
    11701198        foreach ($this->to as $to) {
    11711199            if (!$this->smtp->recipient($to[0])) {
    11721200                $bad_rcpt[] = $to[0];
    class PHPMailer 
    11951223            $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body, $this->From);
    11961224        }
    11971225
    1198         if (count($bad_rcpt) > 0) { //Create error message for any bad addresses
    1199             throw new phpmailerException($this->lang('recipients_failed') . implode(', ', $bad_rcpt));
    1200         }
    1201         if (!$this->smtp->data($header . $body)) {
     1226        //Only send the DATA command if we have viable recipients
     1227        if ((count($this->all_recipients) > count($bad_rcpt)) and !$this->smtp->data($header . $body)) {
    12021228            throw new phpmailerException($this->lang('data_not_accepted'), self::STOP_CRITICAL);
    12031229        }
    12041230        if ($this->SMTPKeepAlive == true) {
    class PHPMailer 
    12071233            $this->smtp->quit();
    12081234            $this->smtp->close();
    12091235        }
     1236        if (count($bad_rcpt) > 0) { //Create error message for any bad addresses
     1237            throw new phpmailerException(
     1238                $this->lang('recipients_failed') . implode(', ', $bad_rcpt),
     1239                self::STOP_CONTINUE
     1240            );
     1241        }
    12101242        return true;
    12111243    }
    12121244
    class PHPMailer 
    12341266        $this->smtp->setDebugLevel($this->SMTPDebug);
    12351267        $this->smtp->setDebugOutput($this->Debugoutput);
    12361268        $this->smtp->setVerp($this->do_verp);
    1237         $tls = ($this->SMTPSecure == 'tls');
    1238         $ssl = ($this->SMTPSecure == 'ssl');
    12391269        $hosts = explode(';', $this->Host);
    12401270        $lastexception = null;
    12411271
    12421272        foreach ($hosts as $hostentry) {
    12431273            $hostinfo = array();
    1244             $host = $hostentry;
     1274            if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
     1275                //Not a valid host entry
     1276                continue;
     1277            }
     1278            //$hostinfo[2]: optional ssl or tls prefix
     1279            //$hostinfo[3]: the hostname
     1280            //$hostinfo[4]: optional port number
     1281            //The host string prefix can temporarily override the current setting for SMTPSecure
     1282            //If it's not specified, the default value is used
     1283            $prefix = '';
     1284            $tls = ($this->SMTPSecure == 'tls');
     1285            if ($hostinfo[2] == 'ssl' or ($hostinfo[2] == '' and $this->SMTPSecure == 'ssl')) {
     1286                $prefix = 'ssl://';
     1287                $tls = false; //Can't have SSL and TLS at once
     1288            } elseif ($hostinfo[2] == 'tls') {
     1289                $tls = true;
     1290                //tls doesn't use a prefix
     1291            }
     1292            $host = $hostinfo[3];
    12451293            $port = $this->Port;
    1246             if (preg_match(
    1247                 '/^(.+):([0-9]+)$/',
    1248                 $hostentry,
    1249                 $hostinfo
    1250             )
    1251             ) { //If $hostentry contains 'address:port', override default
    1252                 $host = $hostinfo[1];
    1253                 $port = $hostinfo[2];
     1294            $tport = (integer)$hostinfo[4];
     1295            if ($tport > 0 and $tport < 65536) {
     1296                $port = $tport;
    12541297            }
    1255             if ($this->smtp->connect(($ssl ? 'ssl://' : '') . $host, $port, $this->Timeout, $options)) {
     1298            if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
    12561299                try {
    12571300                    if ($this->Helo) {
    12581301                        $hello = $this->Helo;
    class PHPMailer 
    12811324                        }
    12821325                    }
    12831326                    return true;
    1284                 } catch (phpmailerException $e) {
    1285                     $lastexception = $e;
     1327                } catch (phpmailerException $exc) {
     1328                    $lastexception = $exc;
    12861329                    //We must have connected, but then failed TLS or Auth, so close connection nicely
    12871330                    $this->smtp->quit();
    12881331                }
    class PHPMailer 
    13201363     * @return bool
    13211364     * @access public
    13221365     */
    1323     public function setLanguage($langcode = 'en', $lang_path = 'language/')
     1366    public function setLanguage($langcode = 'en', $lang_path = '')
    13241367    {
    1325         //Define full set of translatable strings
     1368        //Define full set of translatable strings in English
    13261369        $PHPMAILER_LANG = array(
    13271370            'authenticate' => 'SMTP Error: Could not authenticate.',
    13281371            'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
    class PHPMailer 
    13431386            'smtp_error' => 'SMTP server error: ',
    13441387            'variable_set' => 'Cannot set or reset variable: '
    13451388        );
    1346         //Overwrite language-specific strings.
    1347         //This way we'll never have missing translations - no more "language string failed to load"!
    1348         $l = true;
     1389        if (empty($lang_path)) {
     1390            //Calculate an absolute path so it can work if CWD is not here
     1391            $lang_path = dirname(__FILE__). DIRECTORY_SEPARATOR . 'language'. DIRECTORY_SEPARATOR;
     1392        }
     1393        $foundlang = true;
     1394        $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php';
    13491395        if ($langcode != 'en') { //There is no English translation file
    1350             $l = @include $lang_path . 'phpmailer.lang-' . $langcode . '.php';
     1396            //Make sure language file path is readable
     1397            if (!is_readable($lang_file)) {
     1398                $foundlang = false;
     1399            } else {
     1400                //Overwrite language-specific strings.
     1401                //This way we'll never have missing translations.
     1402                $foundlang = include $lang_file;
     1403            }
    13511404        }
    13521405        $this->language = $PHPMAILER_LANG;
    1353         return ($l == true); //Returns false if language not found
     1406        return ($foundlang == true); //Returns false if language not found
    13541407    }
    13551408
    13561409    /**
    class PHPMailer 
    13751428    public function addrAppend($type, $addr)
    13761429    {
    13771430        $addresses = array();
    1378         foreach ($addr as $a) {
    1379             $addresses[] = $this->addrFormat($a);
     1431        foreach ($addr as $address) {
     1432            $addresses[] = $this->addrFormat($address);
    13801433        }
    13811434        return $type . ': ' . implode(', ', $addresses) . $this->LE;
    13821435    }
    class PHPMailer 
    13931446        if (empty($addr[1])) { // No name provided
    13941447            return $this->secureHeader($addr[0]);
    13951448        } else {
    1396             return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . " <" . $this->secureHeader(
     1449            return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . ' <' . $this->secureHeader(
    13971450                $addr[0]
    1398             ) . ">";
     1451            ) . '>';
    13991452        }
    14001453    }
    14011454
    class PHPMailer 
    14121465     */
    14131466    public function wrapText($message, $length, $qp_mode = false)
    14141467    {
    1415         $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
     1468        $soft_break = ($qp_mode) ? sprintf(' =%s', $this->LE) : $this->LE;
    14161469        // If utf-8 encoding is used, we will need to make sure we don't
    14171470        // split multibyte characters when we wrap
    1418         $is_utf8 = (strtolower($this->CharSet) == "utf-8");
     1471        $is_utf8 = (strtolower($this->CharSet) == 'utf-8');
    14191472        $lelen = strlen($this->LE);
    14201473        $crlflen = strlen(self::CRLF);
    14211474
    class PHPMailer 
    14381491                            $len = $space_left;
    14391492                            if ($is_utf8) {
    14401493                                $len = $this->utf8CharBoundary($word, $len);
    1441                             } elseif (substr($word, $len - 1, 1) == "=") {
     1494                            } elseif (substr($word, $len - 1, 1) == '=') {
    14421495                                $len--;
    1443                             } elseif (substr($word, $len - 2, 1) == "=") {
     1496                            } elseif (substr($word, $len - 2, 1) == '=') {
    14441497                                $len -= 2;
    14451498                            }
    14461499                            $part = substr($word, 0, $len);
    14471500                            $word = substr($word, $len);
    14481501                            $buf .= ' ' . $part;
    1449                             $message .= $buf . sprintf("=%s", self::CRLF);
     1502                            $message .= $buf . sprintf('=%s', self::CRLF);
    14501503                        } else {
    14511504                            $message .= $buf . $soft_break;
    14521505                        }
    class PHPMailer 
    14591512                        $len = $length;
    14601513                        if ($is_utf8) {
    14611514                            $len = $this->utf8CharBoundary($word, $len);
    1462                         } elseif (substr($word, $len - 1, 1) == "=") {
     1515                        } elseif (substr($word, $len - 1, 1) == '=') {
    14631516                            $len--;
    1464                         } elseif (substr($word, $len - 2, 1) == "=") {
     1517                        } elseif (substr($word, $len - 2, 1) == '=') {
    14651518                            $len -= 2;
    14661519                        }
    14671520                        $part = substr($word, 0, $len);
    14681521                        $word = substr($word, $len);
    14691522
    14701523                        if (strlen($word) > 0) {
    1471                             $message .= $part . sprintf("=%s", self::CRLF);
     1524                            $message .= $part . sprintf('=%s', self::CRLF);
    14721525                        } else {
    14731526                            $buf = $part;
    14741527                        }
    class PHPMailer 
    15041557        $lookBack = 3;
    15051558        while (!$foundSplitPos) {
    15061559            $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
    1507             $encodedCharPos = strpos($lastChunk, "=");
     1560            $encodedCharPos = strpos($lastChunk, '=');
    15081561            if ($encodedCharPos !== false) {
    15091562                // Found start of encoded character byte within $lookBack block.
    15101563                // Check the encoded byte value (the 2 chars after the '=')
    class PHPMailer 
    15311584        return $maxLength;
    15321585    }
    15331586
    1534 
    15351587    /**
    15361588     * Set the body wrapping.
    15371589     * @access public
    class PHPMailer 
    15721624        $this->boundary[3] = 'b3_' . $uniq_id;
    15731625
    15741626        if ($this->MessageDate == '') {
    1575             $result .= $this->headerLine('Date', self::rfcDate());
    1576         } else {
    1577             $result .= $this->headerLine('Date', $this->MessageDate);
     1627            $this->MessageDate = self::rfcDate();
    15781628        }
     1629        $result .= $this->headerLine('Date', $this->MessageDate);
    15791630
    1580         if ($this->ReturnPath) {
    1581             $result .= $this->headerLine('Return-Path', '<' . trim($this->ReturnPath) . '>');
    1582         } elseif ($this->Sender == '') {
    1583             $result .= $this->headerLine('Return-Path', '<' . trim($this->From) . '>');
    1584         } else {
    1585             $result .= $this->headerLine('Return-Path', '<' . trim($this->Sender) . '>');
    1586         }
    15871631
    15881632        // To be created automatically by mail()
    1589         if ($this->Mailer != 'mail') {
    1590             if ($this->SingleTo === true) {
    1591                 foreach ($this->to as $t) {
    1592                     $this->SingleToArray[] = $this->addrFormat($t);
     1633        if ($this->SingleTo === true) {
     1634            if ($this->Mailer != 'mail') {
     1635                foreach ($this->to as $toaddr) {
     1636                    $this->SingleToArray[] = $this->addrFormat($toaddr);
    15931637                }
    1594             } else {
    1595                 if (count($this->to) > 0) {
     1638            }
     1639        } else {
     1640            if (count($this->to) > 0) {
     1641                if ($this->Mailer != 'mail') {
    15961642                    $result .= $this->addrAppend('To', $this->to);
    1597                 } elseif (count($this->cc) == 0) {
    1598                     $result .= $this->headerLine('To', 'undisclosed-recipients:;');
    15991643                }
     1644            } elseif (count($this->cc) == 0) {
     1645                $result .= $this->headerLine('To', 'undisclosed-recipients:;');
    16001646            }
    16011647        }
    16021648
    class PHPMailer 
    16081654        }
    16091655
    16101656        // sendmail and mail() extract Bcc from the header before sending
    1611         if ((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) {
     1657        if ((
     1658                $this->Mailer == 'sendmail' or $this->Mailer == 'qmail' or $this->Mailer == 'mail'
     1659            )
     1660            and count($this->bcc) > 0
     1661        ) {
    16121662            $result .= $this->addrAppend('Bcc', $this->bcc);
    16131663        }
    16141664
    class PHPMailer 
    16241674        if ($this->MessageID != '') {
    16251675            $this->lastMessageID = $this->MessageID;
    16261676        } else {
    1627             $this->lastMessageID = sprintf("<%s@%s>", $uniq_id, $this->ServerHostname());
     1677            $this->lastMessageID = sprintf('<%s@%s>', $uniq_id, $this->ServerHostname());
    16281678        }
    16291679        $result .= $this->HeaderLine('Message-ID', $this->lastMessageID);
    16301680        $result .= $this->headerLine('X-Priority', $this->Priority);
    class PHPMailer 
    16671717    public function getMailMIME()
    16681718    {
    16691719        $result = '';
     1720        $ismultipart = true;
    16701721        switch ($this->message_type) {
    16711722            case 'inline':
    16721723                $result .= $this->headerLine('Content-Type', 'multipart/related;');
    class PHPMailer 
    16871738            default:
    16881739                // Catches case 'plain': and case '':
    16891740                $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet);
     1741                $ismultipart = false;
    16901742                break;
    16911743        }
    16921744        //RFC1341 part 5 says 7bit is assumed if not specified
    16931745        if ($this->Encoding != '7bit') {
    1694             $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);
     1746            //RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE
     1747            if ($ismultipart) {
     1748                if ($this->Encoding == '8bit') {
     1749                    $result .= $this->headerLine('Content-Transfer-Encoding', '8bit');
     1750                }
     1751                //The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible
     1752            } else {
     1753                $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);
     1754            }
    16951755        }
    16961756
    16971757        if ($this->Mailer != 'mail') {
    class PHPMailer 
    17041764    /**
    17051765     * Returns the whole MIME message.
    17061766     * Includes complete headers and body.
    1707      * Only valid post PreSend().
    1708      * @see PHPMailer::PreSend()
     1767     * Only valid post preSend().
     1768     * @see PHPMailer::preSend()
    17091769     * @access public
    17101770     * @return string
    17111771     */
    class PHPMailer 
    17321792
    17331793        $this->setWordWrap();
    17341794
     1795        $bodyEncoding = $this->Encoding;
     1796        $bodyCharSet = $this->CharSet;
     1797        if ($bodyEncoding == '8bit' and !$this->has8bitChars($this->Body)) {
     1798            $bodyEncoding = '7bit';
     1799            $bodyCharSet = 'us-ascii';
     1800        }
     1801        $altBodyEncoding = $this->Encoding;
     1802        $altBodyCharSet = $this->CharSet;
     1803        if ($altBodyEncoding == '8bit' and !$this->has8bitChars($this->AltBody)) {
     1804            $altBodyEncoding = '7bit';
     1805            $altBodyCharSet = 'us-ascii';
     1806        }
    17351807        switch ($this->message_type) {
    17361808            case 'inline':
    1737                 $body .= $this->getBoundary($this->boundary[1], '', '', '');
    1738                 $body .= $this->encodeString($this->Body, $this->Encoding);
     1809                $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
     1810                $body .= $this->encodeString($this->Body, $bodyEncoding);
    17391811                $body .= $this->LE . $this->LE;
    17401812                $body .= $this->attachAll('inline', $this->boundary[1]);
    17411813                break;
    17421814            case 'attach':
    1743                 $body .= $this->getBoundary($this->boundary[1], '', '', '');
    1744                 $body .= $this->encodeString($this->Body, $this->Encoding);
     1815                $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
     1816                $body .= $this->encodeString($this->Body, $bodyEncoding);
    17451817                $body .= $this->LE . $this->LE;
    17461818                $body .= $this->attachAll('attachment', $this->boundary[1]);
    17471819                break;
    class PHPMailer 
    17501822                $body .= $this->headerLine('Content-Type', 'multipart/related;');
    17511823                $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
    17521824                $body .= $this->LE;
    1753                 $body .= $this->getBoundary($this->boundary[2], '', '', '');
    1754                 $body .= $this->encodeString($this->Body, $this->Encoding);
     1825                $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, '', $bodyEncoding);
     1826                $body .= $this->encodeString($this->Body, $bodyEncoding);
    17551827                $body .= $this->LE . $this->LE;
    17561828                $body .= $this->attachAll('inline', $this->boundary[2]);
    17571829                $body .= $this->LE;
    17581830                $body .= $this->attachAll('attachment', $this->boundary[1]);
    17591831                break;
    17601832            case 'alt':
    1761                 $body .= $this->getBoundary($this->boundary[1], '', 'text/plain', '');
    1762                 $body .= $this->encodeString($this->AltBody, $this->Encoding);
     1833                $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);
     1834                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
    17631835                $body .= $this->LE . $this->LE;
    1764                 $body .= $this->getBoundary($this->boundary[1], '', 'text/html', '');
    1765                 $body .= $this->encodeString($this->Body, $this->Encoding);
     1836                $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, 'text/html', $bodyEncoding);
     1837                $body .= $this->encodeString($this->Body, $bodyEncoding);
    17661838                $body .= $this->LE . $this->LE;
    17671839                if (!empty($this->Ical)) {
    17681840                    $body .= $this->getBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', '');
    class PHPMailer 
    17721844                $body .= $this->endBoundary($this->boundary[1]);
    17731845                break;
    17741846            case 'alt_inline':
    1775                 $body .= $this->getBoundary($this->boundary[1], '', 'text/plain', '');
    1776                 $body .= $this->encodeString($this->AltBody, $this->Encoding);
     1847                $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);
     1848                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
    17771849                $body .= $this->LE . $this->LE;
    17781850                $body .= $this->textLine('--' . $this->boundary[1]);
    17791851                $body .= $this->headerLine('Content-Type', 'multipart/related;');
    17801852                $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
    17811853                $body .= $this->LE;
    1782                 $body .= $this->getBoundary($this->boundary[2], '', 'text/html', '');
    1783                 $body .= $this->encodeString($this->Body, $this->Encoding);
     1854                $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);
     1855                $body .= $this->encodeString($this->Body, $bodyEncoding);
    17841856                $body .= $this->LE . $this->LE;
    17851857                $body .= $this->attachAll('inline', $this->boundary[2]);
    17861858                $body .= $this->LE;
    class PHPMailer 
    17911863                $body .= $this->headerLine('Content-Type', 'multipart/alternative;');
    17921864                $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
    17931865                $body .= $this->LE;
    1794                 $body .= $this->getBoundary($this->boundary[2], '', 'text/plain', '');
    1795                 $body .= $this->encodeString($this->AltBody, $this->Encoding);
     1866                $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);
     1867                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
    17961868                $body .= $this->LE . $this->LE;
    1797                 $body .= $this->getBoundary($this->boundary[2], '', 'text/html', '');
    1798                 $body .= $this->encodeString($this->Body, $this->Encoding);
     1869                $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);
     1870                $body .= $this->encodeString($this->Body, $bodyEncoding);
    17991871                $body .= $this->LE . $this->LE;
    18001872                $body .= $this->endBoundary($this->boundary[2]);
    18011873                $body .= $this->LE;
    class PHPMailer 
    18061878                $body .= $this->headerLine('Content-Type', 'multipart/alternative;');
    18071879                $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
    18081880                $body .= $this->LE;
    1809                 $body .= $this->getBoundary($this->boundary[2], '', 'text/plain', '');
    1810                 $body .= $this->encodeString($this->AltBody, $this->Encoding);
     1881                $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);
     1882                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
    18111883                $body .= $this->LE . $this->LE;
    18121884                $body .= $this->textLine('--' . $this->boundary[2]);
    18131885                $body .= $this->headerLine('Content-Type', 'multipart/related;');
    18141886                $body .= $this->textLine("\tboundary=\"" . $this->boundary[3] . '"');
    18151887                $body .= $this->LE;
    1816                 $body .= $this->getBoundary($this->boundary[3], '', 'text/html', '');
    1817                 $body .= $this->encodeString($this->Body, $this->Encoding);
     1888                $body .= $this->getBoundary($this->boundary[3], $bodyCharSet, 'text/html', $bodyEncoding);
     1889                $body .= $this->encodeString($this->Body, $bodyEncoding);
    18181890                $body .= $this->LE . $this->LE;
    18191891                $body .= $this->attachAll('inline', $this->boundary[3]);
    18201892                $body .= $this->LE;
    class PHPMailer 
    18241896                break;
    18251897            default:
    18261898                // catch case 'plain' and case ''
    1827                 $body .= $this->encodeString($this->Body, $this->Encoding);
     1899                $body .= $this->encodeString($this->Body, $bodyEncoding);
    18281900                break;
    18291901        }
    18301902
    class PHPMailer 
    18351907                if (!defined('PKCS7_TEXT')) {
    18361908                    throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.');
    18371909                }
     1910                //TODO would be nice to use php://temp streams here, but need to wrap for PHP < 5.1
    18381911                $file = tempnam(sys_get_temp_dir(), 'mail');
    18391912                file_put_contents($file, $body); //TODO check this worked
    18401913                $signed = tempnam(sys_get_temp_dir(), 'signed');
    class PHPMailer 
    18541927                    @unlink($signed);
    18551928                    throw new phpmailerException($this->lang('signing') . openssl_error_string());
    18561929                }
    1857             } catch (phpmailerException $e) {
     1930            } catch (phpmailerException $exc) {
    18581931                $body = '';
    18591932                if ($this->exceptions) {
    1860                     throw $e;
     1933                    throw $exc;
    18611934                }
    18621935            }
    18631936        }
    class PHPMailer 
    18861959            $encoding = $this->Encoding;
    18871960        }
    18881961        $result .= $this->textLine('--' . $boundary);
    1889         $result .= sprintf("Content-Type: %s; charset=%s", $contentType, $charSet);
     1962        $result .= sprintf('Content-Type: %s; charset=%s', $contentType, $charSet);
    18901963        $result .= $this->LE;
    1891         $result .= $this->headerLine('Content-Transfer-Encoding', $encoding);
     1964        //RFC1341 part 5 says 7bit is assumed if not specified
     1965        if ($encoding != '7bit') {
     1966            $result .= $this->headerLine('Content-Transfer-Encoding', $encoding);
     1967        }
    18921968        $result .= $this->LE;
    18931969
    18941970        return $result;
    class PHPMailer 
    19161992    {
    19171993        $this->message_type = array();
    19181994        if ($this->alternativeExists()) {
    1919             $this->message_type[] = "alt";
     1995            $this->message_type[] = 'alt';
    19201996        }
    19211997        if ($this->inlineImageExists()) {
    1922             $this->message_type[] = "inline";
     1998            $this->message_type[] = 'inline';
    19231999        }
    19242000        if ($this->attachmentExists()) {
    1925             $this->message_type[] = "attach";
     2001            $this->message_type[] = 'attach';
    19262002        }
    1927         $this->message_type = implode("_", $this->message_type);
    1928         if ($this->message_type == "") {
    1929             $this->message_type = "plain";
     2003        $this->message_type = implode('_', $this->message_type);
     2004        if ($this->message_type == '') {
     2005            $this->message_type = 'plain';
    19302006        }
    19312007    }
    19322008
    class PHPMailer 
    19922068                7 => 0
    19932069            );
    19942070
    1995         } catch (phpmailerException $e) {
    1996             $this->setError($e->getMessage());
     2071        } catch (phpmailerException $exc) {
     2072            $this->setError($exc->getMessage());
     2073            $this->edebug($exc->getMessage());
    19972074            if ($this->exceptions) {
    1998                 throw $e;
     2075                throw $exc;
    19992076            }
    2000             $this->edebug($e->getMessage() . "\n");
    20012077            return false;
    20022078        }
    20032079        return true;
    class PHPMailer 
    20562132                }
    20572133                $cidUniq[$cid] = true;
    20582134
    2059                 $mime[] = sprintf("--%s%s", $boundary, $this->LE);
     2135                $mime[] = sprintf('--%s%s', $boundary, $this->LE);
    20602136                $mime[] = sprintf(
    2061                     "Content-Type: %s; name=\"%s\"%s",
     2137                    'Content-Type: %s; name="%s"%s',
    20622138                    $type,
    20632139                    $this->encodeHeader($this->secureHeader($name)),
    20642140                    $this->LE
    20652141                );
    2066                 $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
     2142                //RFC1341 part 5 says 7bit is assumed if not specified
     2143                if ($encoding != '7bit') {
     2144                    $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, $this->LE);
     2145                }
    20672146
    20682147                if ($disposition == 'inline') {
    2069                     $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
     2148                    $mime[] = sprintf('Content-ID: <%s>%s', $cid, $this->LE);
    20702149                }
    20712150
    20722151                // If a filename contains any of these chars, it should be quoted,
    class PHPMailer 
    20762155                if (!(empty($disposition))) {
    20772156                    if (preg_match('/[ \(\)<>@,;:\\"\/\[\]\?=]/', $name)) {
    20782157                        $mime[] = sprintf(
    2079                             "Content-Disposition: %s; filename=\"%s\"%s",
     2158                            'Content-Disposition: %s; filename="%s"%s',
    20802159                            $disposition,
    20812160                            $this->encodeHeader($this->secureHeader($name)),
    20822161                            $this->LE . $this->LE
    20832162                        );
    20842163                    } else {
    20852164                        $mime[] = sprintf(
    2086                             "Content-Disposition: %s; filename=%s%s",
     2165                            'Content-Disposition: %s; filename=%s%s',
    20872166                            $disposition,
    20882167                            $this->encodeHeader($this->secureHeader($name)),
    20892168                            $this->LE . $this->LE
    class PHPMailer 
    21102189            }
    21112190        }
    21122191
    2113         $mime[] = sprintf("--%s--%s", $boundary, $this->LE);
     2192        $mime[] = sprintf('--%s--%s', $boundary, $this->LE);
    21142193
    2115         return implode("", $mime);
     2194        return implode('', $mime);
    21162195    }
    21172196
    21182197    /**
    class PHPMailer 
    21492228                }
    21502229            }
    21512230            return $file_buffer;
    2152         } catch (Exception $e) {
    2153             $this->setError($e->getMessage());
     2231        } catch (Exception $exc) {
     2232            $this->setError($exc->getMessage());
    21542233            return '';
    21552234        }
    21562235    }
    class PHPMailer 
    22012280     */
    22022281    public function encodeHeader($str, $position = 'text')
    22032282    {
    2204         $x = 0;
     2283        $matchcount = 0;
    22052284        switch (strtolower($position)) {
    22062285            case 'phrase':
    22072286                if (!preg_match('/[\200-\377]/', $str)) {
    2208                     // Can't use addslashes as we don't know what value has magic_quotes_sybase
     2287                    // Can't use addslashes as we don't know the value of magic_quotes_sybase
    22092288                    $encoded = addcslashes($str, "\0..\37\177\\\"");
    22102289                    if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
    22112290                        return ($encoded);
    class PHPMailer 
    22132292                        return ("\"$encoded\"");
    22142293                    }
    22152294                }
    2216                 $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
     2295                $matchcount = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
    22172296                break;
    22182297            /** @noinspection PhpMissingBreakStatementInspection */
    22192298            case 'comment':
    2220                 $x = preg_match_all('/[()"]/', $str, $matches);
     2299                $matchcount = preg_match_all('/[()"]/', $str, $matches);
    22212300                // Intentional fall-through
    22222301            case 'text':
    22232302            default:
    2224                 $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
     2303                $matchcount += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
    22252304                break;
    22262305        }
    22272306
    2228         if ($x == 0) { //There are no chars that need encoding
     2307        if ($matchcount == 0) { //There are no chars that need encoding
    22292308            return ($str);
    22302309        }
    22312310
    22322311        $maxlen = 75 - 7 - strlen($this->CharSet);
    22332312        // Try to select the encoding which should produce the shortest output
    2234         if ($x > strlen($str) / 3) {
     2313        if ($matchcount > strlen($str) / 3) {
    22352314            //More than a third of the content will need encoding, so B encoding will be most efficient
    22362315            $encoding = 'B';
    22372316            if (function_exists('mb_strlen') && $this->hasMultiBytes($str)) {
    class PHPMailer 
    22502329            $encoded = str_replace('=' . self::CRLF, "\n", trim($encoded));
    22512330        }
    22522331
    2253         $encoded = preg_replace('/^(.*)$/m', " =?" . $this->CharSet . "?$encoding?\\1?=", $encoded);
     2332        $encoded = preg_replace('/^(.*)$/m', ' =?' . $this->CharSet . "?$encoding?\\1?=", $encoded);
    22542333        $encoded = trim(str_replace("\n", $this->LE, $encoded));
    22552334
    22562335        return $encoded;
    class PHPMailer 
    22722351    }
    22732352
    22742353    /**
     2354     * Does a string contain any 8-bit chars (in any charset)?
     2355     * @param string $text
     2356     * @return bool
     2357     */
     2358    public function has8bitChars($text)
     2359    {
     2360        return (bool)preg_match('/[\x80-\xFF]/', $text);
     2361    }
     2362
     2363    /**
    22752364     * Encode and wrap long multibyte strings for mail headers
    22762365     * without breaking lines within a character.
    2277      * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php
     2366     * Adapted from a function by paravoid
     2367     * @link http://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283
    22782368     * @access public
    22792369     * @param string $str multi-byte text to wrap encode
    2280      * @param string $lf string to use as linefeed/end-of-line
     2370     * @param string $linebreak string to use as linefeed/end-of-line
    22812371     * @return string
    22822372     */
    2283     public function base64EncodeWrapMB($str, $lf = null)
     2373    public function base64EncodeWrapMB($str, $linebreak = null)
    22842374    {
    2285         $start = "=?" . $this->CharSet . "?B?";
    2286         $end = "?=";
    2287         $encoded = "";
    2288         if ($lf === null) {
    2289             $lf = $this->LE;
     2375        $start = '=?' . $this->CharSet . '?B?';
     2376        $end = '?=';
     2377        $encoded = '';
     2378        if ($linebreak === null) {
     2379            $linebreak = $this->LE;
    22902380        }
    22912381
    22922382        $mb_length = mb_strlen($str, $this->CharSet);
    class PHPMailer 
    23052395                $chunk = base64_encode($chunk);
    23062396                $lookBack++;
    23072397            } while (strlen($chunk) > $length);
    2308             $encoded .= $chunk . $lf;
     2398            $encoded .= $chunk . $linebreak;
    23092399        }
    23102400
    23112401        // Chomp the last linefeed
    2312         $encoded = substr($encoded, 0, -strlen($lf));
     2402        $encoded = substr($encoded, 0, -strlen($linebreak));
    23132403        return $encoded;
    23142404    }
    23152405
    class PHPMailer 
    23202410     * @param string $string The text to encode
    23212411     * @param integer $line_max Number of chars allowed on a line before wrapping
    23222412     * @return string
    2323      * @link PHP version adapted from http://www.php.net/manual/en/function.quoted-printable-decode.php#89417
     2413     * @link http://www.php.net/manual/en/function.quoted-printable-decode.php#89417 Adapted from this comment
    23242414     */
    23252415    public function encodeQP($string, $line_max = 76)
    23262416    {
    23272417        if (function_exists('quoted_printable_encode')) { //Use native function if it's available (>= PHP5.3)
    2328             return quoted_printable_encode($string);
     2418            return $this->fixEOL(quoted_printable_encode($string));
    23292419        }
    23302420        //Fall back to a pure PHP implementation
    23312421        $string = str_replace(
    class PHPMailer 
    23342424            rawurlencode($string)
    23352425        );
    23362426        $string = preg_replace('/[^\r\n]{' . ($line_max - 3) . '}[^=\r\n]{2}/', "$0=\r\n", $string);
    2337         return $string;
     2427        return $this->fixEOL($string);
    23382428    }
    23392429
    23402430    /**
    class PHPMailer 
    23902480        if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) {
    23912481            //If the string contains an '=', make sure it's the first thing we replace
    23922482            //so as to avoid double-encoding
    2393             $s = array_search('=', $matches[0]);
    2394             if ($s !== false) {
    2395                 unset($matches[0][$s]);
     2483            $eqkey = array_search('=', $matches[0]);
     2484            if ($eqkey !== false) {
     2485                unset($matches[0][$eqkey]);
    23962486                array_unshift($matches[0], '=');
    23972487            }
    23982488            foreach (array_unique($matches[0]) as $char) {
    class PHPMailer 
    26802770     */
    26812771    protected function serverHostname()
    26822772    {
     2773        $result = 'localhost.localdomain';
    26832774        if (!empty($this->Hostname)) {
    26842775            $result = $this->Hostname;
    2685         } elseif (isset($_SERVER['SERVER_NAME'])) {
     2776        } elseif (isset($_SERVER) and array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) {
    26862777            $result = $_SERVER['SERVER_NAME'];
    2687         } else {
    2688             $result = 'localhost.localdomain';
     2778        } elseif (function_exists('gethostname') && gethostname() !== false) {
     2779            $result = gethostname();
     2780        } elseif (php_uname('n') !== false) {
     2781            $result = php_uname('n');
    26892782        }
    2690 
    26912783        return $result;
    26922784    }
    26932785
    class PHPMailer 
    27702862     */
    27712863    public function msgHTML($message, $basedir = '', $advanced = false)
    27722864    {
    2773         preg_match_all("/(src|background)=[\"'](.*)[\"']/Ui", $message, $images);
     2865        preg_match_all('/(src|background)=["\'](.*)["\']/Ui', $message, $images);
    27742866        if (isset($images[2])) {
    2775             foreach ($images[2] as $i => $url) {
     2867            foreach ($images[2] as $imgindex => $url) {
    27762868                // do not change urls for absolute images (thanks to corvuscorax)
    27772869                if (!preg_match('#^[A-z]+://#', $url)) {
    27782870                    $filename = basename($url);
    class PHPMailer 
    27962888                    )
    27972889                    ) {
    27982890                        $message = preg_replace(
    2799                             "/" . $images[1][$i] . "=[\"']" . preg_quote($url, '/') . "[\"']/Ui",
    2800                             $images[1][$i] . "=\"cid:" . $cid . "\"",
     2891                            '/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui',
     2892                            $images[1][$imgindex] . '="cid:' . $cid . '"',
    28012893                            $message
    28022894                        );
    28032895                    }
    class PHPMailer 
    28052897            }
    28062898        }
    28072899        $this->isHTML(true);
    2808         if (empty($this->AltBody)) {
    2809             $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n";
    2810         }
    28112900        //Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better
    28122901        $this->Body = $this->normalizeBreaks($message);
    28132902        $this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced));
     2903        if (empty($this->AltBody)) {
     2904            $this->AltBody = 'To view this email message, open it in a program that understands HTML!' .
     2905                self::CRLF . self::CRLF;
     2906        }
    28142907        return $this->Body;
    28152908    }
    28162909
    class PHPMailer 
    28242917    {
    28252918        if ($advanced) {
    28262919            require_once 'extras/class.html2text.php';
    2827             $h = new html2text($html);
    2828             return $h->get_text();
     2920            $htmlconverter = new html2text($html);
     2921            return $htmlconverter->get_text();
    28292922        }
    28302923        return html_entity_decode(
    28312924            trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))),
    class PHPMailer 
    29203013            'txt' => 'text/plain',
    29213014            'rtx' => 'text/richtext',
    29223015            'rtf' => 'text/rtf',
     3016            'vcf' => 'text/vcard',
     3017            'vcard' => 'text/vcard',
    29233018            'xml' => 'text/xml',
    29243019            'xsl' => 'text/xml',
    29253020            'mpeg' => 'video/mpeg',
    class PHPMailer 
    29663061    public static function mb_pathinfo($path, $options = null)
    29673062    {
    29683063        $ret = array('dirname' => '', 'basename' => '', 'extension' => '', 'filename' => '');
    2969         $m = array();
    2970         preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $m);
    2971         if (array_key_exists(1, $m)) {
    2972             $ret['dirname'] = $m[1];
     3064        $pathinfo = array();
     3065        preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $pathinfo);
     3066        if (array_key_exists(1, $pathinfo)) {
     3067            $ret['dirname'] = $pathinfo[1];
    29733068        }
    2974         if (array_key_exists(2, $m)) {
    2975             $ret['basename'] = $m[2];
     3069        if (array_key_exists(2, $pathinfo)) {
     3070            $ret['basename'] = $pathinfo[2];
    29763071        }
    2977         if (array_key_exists(5, $m)) {
    2978             $ret['extension'] = $m[5];
     3072        if (array_key_exists(5, $pathinfo)) {
     3073            $ret['extension'] = $pathinfo[5];
    29793074        }
    2980         if (array_key_exists(3, $m)) {
    2981             $ret['filename'] = $m[3];
     3075        if (array_key_exists(3, $pathinfo)) {
     3076            $ret['filename'] = $pathinfo[3];
    29823077        }
    29833078        switch ($options) {
    29843079            case PATHINFO_DIRNAME:
    class PHPMailer 
    30243119            } else {
    30253120                throw new phpmailerException($this->lang('variable_set') . $name, self::STOP_CRITICAL);
    30263121            }
    3027         } catch (Exception $e) {
    3028             $this->setError($e->getMessage());
    3029             if ($e->getCode() == self::STOP_CRITICAL) {
     3122        } catch (Exception $exc) {
     3123            $this->setError($exc->getMessage());
     3124            if ($exc->getCode() == self::STOP_CRITICAL) {
    30303125                return false;
    30313126            }
    30323127        }
    class PHPMailer 
    30613156
    30623157
    30633158    /**
    3064      * Set the private key file and password for S/MIME signing.
     3159     * Set the public and private key files and password for S/MIME signing.
    30653160     * @access public
    30663161     * @param string $cert_filename
    30673162     * @param string $key_filename
    class PHPMailer 
    30883183            if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) {
    30893184                $line .= $txt[$i];
    30903185            } else {
    3091                 $line .= "=" . sprintf("%02X", $ord);
     3186                $line .= '=' . sprintf('%02X', $ord);
    30923187            }
    30933188        }
    30943189        return $line;
    class PHPMailer 
    30973192    /**
    30983193     * Generate a DKIM signature.
    30993194     * @access public
    3100      * @param string $s Header
     3195     * @param string $signheader Header
    31013196     * @throws phpmailerException
    31023197     * @return string
    31033198     */
    3104     public function DKIM_Sign($s)
     3199    public function DKIM_Sign($signheader)
    31053200    {
    31063201        if (!defined('PKCS7_TEXT')) {
    31073202            if ($this->exceptions) {
    3108                 throw new phpmailerException($this->lang("signing") . ' OpenSSL extension missing.');
     3203                throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.');
    31093204            }
    31103205            return '';
    31113206        }
    class PHPMailer 
    31153210        } else {
    31163211            $privKey = $privKeyStr;
    31173212        }
    3118         if (openssl_sign($s, $signature, $privKey)) {
     3213        if (openssl_sign($signheader, $signature, $privKey)) {
    31193214            return base64_encode($signature);
    31203215        }
    31213216        return '';
    class PHPMailer 
    31243219    /**
    31253220     * Generate a DKIM canonicalization header.
    31263221     * @access public
    3127      * @param string $s Header
     3222     * @param string $signheader Header
    31283223     * @return string
    31293224     */
    3130     public function DKIM_HeaderC($s)
     3225    public function DKIM_HeaderC($signheader)
    31313226    {
    3132         $s = preg_replace("/\r\n\s+/", " ", $s);
    3133         $lines = explode("\r\n", $s);
     3227        $signheader = preg_replace('/\r\n\s+/', ' ', $signheader);
     3228        $lines = explode("\r\n", $signheader);
    31343229        foreach ($lines as $key => $line) {
    3135             list($heading, $value) = explode(":", $line, 2);
     3230            list($heading, $value) = explode(':', $line, 2);
    31363231            $heading = strtolower($heading);
    3137             $value = preg_replace("/\s+/", " ", $value); // Compress useless spaces
    3138             $lines[$key] = $heading . ":" . trim($value); // Don't forget to remove WSP around the value
     3232            $value = preg_replace('/\s+/', ' ', $value); // Compress useless spaces
     3233            $lines[$key] = $heading . ':' . trim($value); // Don't forget to remove WSP around the value
    31393234        }
    3140         $s = implode("\r\n", $lines);
    3141         return $s;
     3235        $signheader = implode("\r\n", $lines);
     3236        return $signheader;
    31423237    }
    31433238
    31443239    /**
    class PHPMailer 
    32053300        ); // Copied header fields (dkim-quoted-printable)
    32063301        $body = $this->DKIM_BodyC($body);
    32073302        $DKIMlen = strlen($body); // Length of body
    3208         $DKIMb64 = base64_encode(pack("H*", sha1($body))); // Base64 of packed binary SHA-1 hash of body
    3209         $ident = ($this->DKIM_identity == '') ? '' : " i=" . $this->DKIM_identity . ";";
    3210         $dkimhdrs = "DKIM-Signature: v=1; a=" .
    3211             $DKIMsignatureType . "; q=" .
    3212             $DKIMquery . "; l=" .
    3213             $DKIMlen . "; s=" .
     3303        $DKIMb64 = base64_encode(pack('H*', sha1($body))); // Base64 of packed binary SHA-1 hash of body
     3304        $ident = ($this->DKIM_identity == '') ? '' : ' i=' . $this->DKIM_identity . ';';
     3305        $dkimhdrs = 'DKIM-Signature: v=1; a=' .
     3306            $DKIMsignatureType . '; q=' .
     3307            $DKIMquery . '; l=' .
     3308            $DKIMlen . '; s=' .
    32143309            $this->DKIM_selector .
    32153310            ";\r\n" .
    3216             "\tt=" . $DKIMtime . "; c=" . $DKIMcanonicalization . ";\r\n" .
     3311            "\tt=" . $DKIMtime . '; c=' . $DKIMcanonicalization . ";\r\n" .
    32173312            "\th=From:To:Subject;\r\n" .
    3218             "\td=" . $this->DKIM_domain . ";" . $ident . "\r\n" .
     3313            "\td=" . $this->DKIM_domain . ';' . $ident . "\r\n" .
    32193314            "\tz=$from\r\n" .
    32203315            "\t|$to\r\n" .
    32213316            "\t|$subject;\r\n" .
    class PHPMailer 
    32293324    }
    32303325
    32313326    /**
     3327     * Allows for public read access to 'to' property.
     3328     * @access public
     3329     * @return array
     3330     */
     3331    public function getToAddresses()
     3332    {
     3333        return $this->to;
     3334    }
     3335
     3336    /**
     3337     * Allows for public read access to 'cc' property.
     3338     * @access public
     3339     * @return array
     3340     */
     3341    public function getCcAddresses()
     3342    {
     3343        return $this->cc;
     3344    }
     3345
     3346    /**
     3347     * Allows for public read access to 'bcc' property.
     3348     * @access public
     3349     * @return array
     3350     */
     3351    public function getBccAddresses()
     3352    {
     3353        return $this->bcc;
     3354    }
     3355
     3356    /**
     3357     * Allows for public read access to 'ReplyTo' property.
     3358     * @access public
     3359     * @return array
     3360     */
     3361    public function getReplyToAddresses()
     3362    {
     3363        return $this->ReplyTo;
     3364    }
     3365
     3366    /**
     3367     * Allows for public read access to 'all_recipients' property.
     3368     * @access public
     3369     * @return array
     3370     */
     3371    public function getAllRecipientAddresses()
     3372    {
     3373        return $this->all_recipients;
     3374    }
     3375
     3376    /**
    32323377     * Perform a callback.
    32333378     * @param bool $isSent
    32343379     * @param string $to
  • src/wp-includes/class-pop3.php

    diff --git a/src/wp-includes/class-pop3.php b/src/wp-includes/class-pop3.php
    index d0455d7..71dffac 100644
    a b  
    11<?php
    22/**
    3  * mail_fetch/setup.php
    4  *
    5  * Copyright (c) 1999-2011 CDI (cdi@thewebmasters.net) All Rights Reserved
    6  * Modified by Philippe Mingo 2001-2009 mingo@rotedic.com
    7  * An RFC 1939 compliant wrapper class for the POP3 protocol.
    8  *
    9  * Licensed under the GNU GPL. For full terms see the file COPYING.
    10  *
    11  * POP3 class
    12  *
    13  * @copyright 1999-2011 The SquirrelMail Project Team
    14  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
    15  * @package plugins
    16  * @subpackage mail_fetch
     3 * PHPMailer POP-Before-SMTP Authentication Class.
     4 * PHP Version 5
     5 * @package PHPMailer
     6 * @link https://github.com/PHPMailer/PHPMailer/
     7 * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
     8 * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
     9 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
     10 * @author Brent R. Matzelle (original founder)
     11 * @copyright 2012 - 2014 Marcus Bointon
     12 * @copyright 2010 - 2012 Jim Jagielski
     13 * @copyright 2004 - 2009 Andy Prevost
     14 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
     15 * @note This program is distributed in the hope that it will be useful - WITHOUT
     16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     17 * FITNESS FOR A PARTICULAR PURPOSE.
    1718 */
    1819
    19 class POP3 {
    20     var $ERROR      = '';       //  Error string.
    21 
    22     var $TIMEOUT    = 60;       //  Default timeout before giving up on a
    23                                 //  network operation.
    24 
    25     var $COUNT      = -1;       //  Mailbox msg count
    26 
    27     var $BUFFER     = 512;      //  Socket buffer for socket fgets() calls.
    28                                 //  Per RFC 1939 the returned line a POP3
    29                                 //  server can send is 512 bytes.
    30 
    31     var $FP         = '';       //  The connection to the server's
    32                                 //  file descriptor
    33 
    34     var $MAILSERVER = '';       // Set this to hard code the server name
    35 
    36     var $DEBUG      = FALSE;    // set to true to echo pop3
    37                                 // commands and responses to error_log
    38                                 // this WILL log passwords!
    39 
    40     var $BANNER     = '';       //  Holds the banner returned by the
    41                                 //  pop server - used for apop()
    42 
    43     var $ALLOWAPOP  = FALSE;    //  Allow or disallow apop()
    44                                 //  This must be set to true
    45                                 //  manually
    46 
    47     function POP3 ( $server = '', $timeout = '' ) {
    48         settype($this->BUFFER,"integer");
    49         if( !empty($server) ) {
    50             // Do not allow programs to alter MAILSERVER
    51             // if it is already specified. They can get around
    52             // this if they -really- want to, so don't count on it.
    53             if(empty($this->MAILSERVER))
    54                 $this->MAILSERVER = $server;
    55         }
    56         if(!empty($timeout)) {
    57             settype($timeout,"integer");
    58             $this->TIMEOUT = $timeout;
    59             if (!ini_get('safe_mode'))
    60                 set_time_limit($timeout);
    61         }
    62         return true;
     20/**
     21 * PHPMailer POP-Before-SMTP Authentication Class.
     22 * Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication.
     23 * Does not support APOP.
     24 * @package PHPMailer
     25 * @author Richard Davey (original author) <rich@corephp.co.uk>
     26 * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
     27 * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
     28 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
     29 */
     30class POP3
     31{
     32    /**
     33     * The POP3 PHPMailer Version number.
     34     * @type string
     35     * @access public
     36     */
     37    public $Version = '5.2.8';
     38
     39    /**
     40     * Default POP3 port number.
     41     * @type int
     42     * @access public
     43     */
     44    public $POP3_PORT = 110;
     45
     46    /**
     47     * Default timeout in seconds.
     48     * @type int
     49     * @access public
     50     */
     51    public $POP3_TIMEOUT = 30;
     52
     53    /**
     54     * POP3 Carriage Return + Line Feed.
     55     * @type string
     56     * @access public
     57     * @deprecated Use the constant instead
     58     */
     59    public $CRLF = "\r\n";
     60
     61    /**
     62     * Debug display level.
     63     * Options: 0 = no, 1+ = yes
     64     * @type int
     65     * @access public
     66     */
     67    public $do_debug = 0;
     68
     69    /**
     70     * POP3 mail server hostname.
     71     * @type string
     72     * @access public
     73     */
     74    public $host;
     75
     76    /**
     77     * POP3 port number.
     78     * @type int
     79     * @access public
     80     */
     81    public $port;
     82
     83    /**
     84     * POP3 Timeout Value in seconds.
     85     * @type int
     86     * @access public
     87     */
     88    public $tval;
     89
     90    /**
     91     * POP3 username
     92     * @type string
     93     * @access public
     94     */
     95    public $username;
     96
     97    /**
     98     * POP3 password.
     99     * @type string
     100     * @access public
     101     */
     102    public $password;
     103
     104    /**
     105     * Resource handle for the POP3 connection socket.
     106     * @type resource
     107     * @access private
     108     */
     109    private $pop_conn;
     110
     111    /**
     112     * Are we connected?
     113     * @type bool
     114     * @access private
     115     */
     116    private $connected;
     117
     118    /**
     119     * Error container.
     120     * @type array
     121     * @access private
     122     */
     123    private $error;
     124
     125    /**
     126     * Line break constant
     127     */
     128    const CRLF = "\r\n";
     129
     130    /**
     131     * Constructor.
     132     * @access public
     133     */
     134    public function __construct()
     135    {
     136        $this->pop_conn = 0;
     137        $this->connected = false;
     138        $this->error = null;
    63139    }
    64140
    65     function update_timer () {
    66         if (!ini_get('safe_mode'))
    67             set_time_limit($this->TIMEOUT);
    68         return true;
     141    /**
     142     * Simple static wrapper for all-in-one POP before SMTP
     143     * @param $host
     144     * @param bool $port
     145     * @param bool $tval
     146     * @param string $username
     147     * @param string $password
     148     * @param int $debug_level
     149     * @return bool
     150     */
     151    public static function popBeforeSmtp(
     152        $host,
     153        $port = false,
     154        $tval = false,
     155        $username = '',
     156        $password = '',
     157        $debug_level = 0
     158    ) {
     159        $pop = new POP3;
     160        return $pop->authorise($host, $port, $tval, $username, $password, $debug_level);
    69161    }
    70162
    71     function connect ($server, $port = 110)  {
    72         //  Opens a socket to the specified server. Unless overridden,
    73         //  port defaults to 110. Returns true on success, false on fail
    74 
    75         // If MAILSERVER is set, override $server with it's value
    76 
    77     if (!isset($port) || !$port) {$port = 110;}
    78         if(!empty($this->MAILSERVER))
    79             $server = $this->MAILSERVER;
    80 
    81         if(empty($server)){
    82             $this->ERROR = "POP3 connect: " . _("No server specified");
    83             unset($this->FP);
    84             return false;
    85         }
    86 
    87         $fp = @fsockopen("$server", $port, $errno, $errstr);
    88 
    89         if(!$fp) {
    90             $this->ERROR = "POP3 connect: " . _("Error ") . "[$errno] [$errstr]";
    91             unset($this->FP);
    92             return false;
    93         }
    94 
    95         socket_set_blocking($fp,-1);
    96         $this->update_timer();
    97         $reply = fgets($fp,$this->BUFFER);
    98         $reply = $this->strip_clf($reply);
    99         if($this->DEBUG)
    100             error_log("POP3 SEND [connect: $server] GOT [$reply]",0);
    101         if(!$this->is_ok($reply)) {
    102             $this->ERROR = "POP3 connect: " . _("Error ") . "[$reply]";
    103             unset($this->FP);
    104             return false;
    105         }
    106         $this->FP = $fp;
    107         $this->BANNER = $this->parse_banner($reply);
    108         return true;
    109     }
    110 
    111     function user ($user = "") {
    112         // Sends the USER command, returns true or false
    113 
    114         if( empty($user) ) {
    115             $this->ERROR = "POP3 user: " . _("no login ID submitted");
    116             return false;
    117         } elseif(!isset($this->FP)) {
    118             $this->ERROR = "POP3 user: " . _("connection not established");
    119             return false;
     163    /**
     164     * Authenticate with a POP3 server.
     165     * A connect, login, disconnect sequence
     166     * appropriate for POP-before SMTP authorisation.
     167     * @access public
     168     * @param string $host
     169     * @param bool|int $port
     170     * @param bool|int $tval
     171     * @param string $username
     172     * @param string $password
     173     * @param int $debug_level
     174     * @return bool
     175     */
     176    public function authorise($host, $port = false, $tval = false, $username = '', $password = '', $debug_level = 0)
     177    {
     178        $this->host = $host;
     179        // If no port value provided, use default
     180        if ($port === false) {
     181            $this->port = $this->POP3_PORT;
    120182        } else {
    121             $reply = $this->send_cmd("USER $user");
    122             if(!$this->is_ok($reply)) {
    123                 $this->ERROR = "POP3 user: " . _("Error ") . "[$reply]";
    124                 return false;
    125             } else
    126                 return true;
     183            $this->port = $port;
    127184        }
    128     }
    129 
    130     function pass ($pass = "")     {
    131         // Sends the PASS command, returns # of msgs in mailbox,
    132         // returns false (undef) on Auth failure
    133 
    134         if(empty($pass)) {
    135             $this->ERROR = "POP3 pass: " . _("No password submitted");
    136             return false;
    137         } elseif(!isset($this->FP)) {
    138             $this->ERROR = "POP3 pass: " . _("connection not established");
    139             return false;
     185        // If no timeout value provided, use default
     186        if ($tval === false) {
     187            $this->tval = $this->POP3_TIMEOUT;
    140188        } else {
    141             $reply = $this->send_cmd("PASS $pass");
    142             if(!$this->is_ok($reply)) {
    143                 $this->ERROR = "POP3 pass: " . _("Authentication failed") . " [$reply]";
    144                 $this->quit();
    145                 return false;
    146             } else {
    147                 //  Auth successful.
    148                 $count = $this->last("count");
    149                 $this->COUNT = $count;
    150                 return $count;
     189            $this->tval = $tval;
     190        }
     191        $this->do_debug = $debug_level;
     192        $this->username = $username;
     193        $this->password = $password;
     194        //  Refresh the error log
     195        $this->error = null;
     196        //  connect
     197        $result = $this->connect($this->host, $this->port, $this->tval);
     198        if ($result) {
     199            $login_result = $this->login($this->username, $this->password);
     200            if ($login_result) {
     201                $this->disconnect();
     202                return true;
    151203            }
    152204        }
     205        // We need to disconnect regardless of whether the login succeeded
     206        $this->disconnect();
     207        return false;
    153208    }
    154209
    155     function apop ($login,$pass) {
    156         //  Attempts an APOP login. If this fails, it'll
    157         //  try a standard login. YOUR SERVER MUST SUPPORT
    158         //  THE USE OF THE APOP COMMAND!
    159         //  (apop is optional per rfc1939)
    160 
    161         if(!isset($this->FP)) {
    162             $this->ERROR = "POP3 apop: " . _("No connection to server");
    163             return false;
    164         } elseif(!$this->ALLOWAPOP) {
    165             $retVal = $this->login($login,$pass);
    166             return $retVal;
    167         } elseif(empty($login)) {
    168             $this->ERROR = "POP3 apop: " . _("No login ID submitted");
    169             return false;
    170         } elseif(empty($pass)) {
    171             $this->ERROR = "POP3 apop: " . _("No password submitted");
    172             return false;
    173         } else {
    174             $banner = $this->BANNER;
    175             if( (!$banner) or (empty($banner)) ) {
    176                 $this->ERROR = "POP3 apop: " . _("No server banner") . ' - ' . _("abort");
    177                 $retVal = $this->login($login,$pass);
    178                 return $retVal;
    179             } else {
    180                 $AuthString = $banner;
    181                 $AuthString .= $pass;
    182                 $APOPString = md5($AuthString);
    183                 $cmd = "APOP $login $APOPString";
    184                 $reply = $this->send_cmd($cmd);
    185                 if(!$this->is_ok($reply)) {
    186                     $this->ERROR = "POP3 apop: " . _("apop authentication failed") . ' - ' . _("abort");
    187                     $retVal = $this->login($login,$pass);
    188                     return $retVal;
    189                 } else {
    190                     //  Auth successful.
    191                     $count = $this->last("count");
    192                     $this->COUNT = $count;
    193                     return $count;
    194                 }
     210    /**
     211     * Connect to a POP3 server.
     212     * @access public
     213     * @param string $host
     214     * @param bool|int $port
     215     * @param integer $tval
     216     * @return boolean
     217     */
     218    public function connect($host, $port = false, $tval = 30)
     219    {
     220        //  Are we already connected?
     221        if ($this->connected) {
     222            return true;
     223        }
     224
     225        //On Windows this will raise a PHP Warning error if the hostname doesn't exist.
     226        //Rather than suppress it with @fsockopen, capture it cleanly instead
     227        set_error_handler(array($this, 'catchWarning'));
     228
     229        //  connect to the POP3 server
     230        $this->pop_conn = fsockopen(
     231            $host, //  POP3 Host
     232            $port, //  Port #
     233            $errno, //  Error Number
     234            $errstr, //  Error Message
     235            $tval
     236        ); //  Timeout (seconds)
     237        //  Restore the error handler
     238        restore_error_handler();
     239        //  Does the Error Log now contain anything?
     240        if ($this->error && $this->do_debug >= 1) {
     241            $this->displayErrors();
     242        }
     243        //  Did we connect?
     244        if ($this->pop_conn == false) {
     245            //  It would appear not...
     246            $this->error = array(
     247                'error' => "Failed to connect to server $host on port $port",
     248                'errno' => $errno,
     249                'errstr' => $errstr
     250            );
     251            if ($this->do_debug >= 1) {
     252                $this->displayErrors();
    195253            }
     254            return false;
    196255        }
    197     }
    198256
    199     function login ($login = "", $pass = "") {
    200         // Sends both user and pass. Returns # of msgs in mailbox or
    201         // false on failure (or -1, if the error occurs while getting
    202         // the number of messages.)
    203 
    204         if( !isset($this->FP) ) {
    205             $this->ERROR = "POP3 login: " . _("No connection to server");
    206             return false;
     257        //  Increase the stream time-out
     258        //  Check for PHP 4.3.0 or later
     259        if (version_compare(phpversion(), '5.0.0', 'ge')) {
     260            stream_set_timeout($this->pop_conn, $tval, 0);
    207261        } else {
    208             $fp = $this->FP;
    209             if( !$this->user( $login ) ) {
    210                 //  Preserve the error generated by user()
    211                 return false;
    212             } else {
    213                 $count = $this->pass($pass);
    214                 if( (!$count) || ($count == -1) ) {
    215                     //  Preserve the error generated by last() and pass()
    216                     return false;
    217                 } else
    218                     return $count;
     262            //  Does not work on Windows
     263            if (substr(PHP_OS, 0, 3) !== 'WIN') {
     264                socket_set_timeout($this->pop_conn, $tval, 0);
    219265            }
    220266        }
    221     }
    222 
    223     function top ($msgNum, $numLines = "0") {
    224         //  Gets the header and first $numLines of the msg body
    225         //  returns data in an array with each returned line being
    226         //  an array element. If $numLines is empty, returns
    227         //  only the header information, and none of the body.
    228 
    229         if(!isset($this->FP)) {
    230             $this->ERROR = "POP3 top: " . _("No connection to server");
    231             return false;
    232         }
    233         $this->update_timer();
    234 
    235         $fp = $this->FP;
    236         $buffer = $this->BUFFER;
    237         $cmd = "TOP $msgNum $numLines";
    238         fwrite($fp, "TOP $msgNum $numLines\r\n");
    239         $reply = fgets($fp, $buffer);
    240         $reply = $this->strip_clf($reply);
    241         if($this->DEBUG) {
    242             @error_log("POP3 SEND [$cmd] GOT [$reply]",0);
    243         }
    244         if(!$this->is_ok($reply))
    245         {
    246             $this->ERROR = "POP3 top: " . _("Error ") . "[$reply]";
    247             return false;
    248         }
    249267
    250         $count = 0;
    251         $MsgArray = array();
    252 
    253         $line = fgets($fp,$buffer);
    254         while ( !preg_match('/^\.\r\n/',$line))
    255         {
    256             $MsgArray[$count] = $line;
    257             $count++;
    258             $line = fgets($fp,$buffer);
    259             if(empty($line))    { break; }
     268        //  Get the POP3 server response
     269        $pop3_response = $this->getResponse();
     270        //  Check for the +OK
     271        if ($this->checkResponse($pop3_response)) {
     272            //  The connection is established and the POP3 server is talking
     273            $this->connected = true;
     274            return true;
    260275        }
    261 
    262         return $MsgArray;
     276        return false;
    263277    }
    264278
    265     function pop_list ($msgNum = "") {
    266         //  If called with an argument, returns that msgs' size in octets
    267         //  No argument returns an associative array of undeleted
    268         //  msg numbers and their sizes in octets
    269 
    270         if(!isset($this->FP))
    271         {
    272             $this->ERROR = "POP3 pop_list: " . _("No connection to server");
    273             return false;
    274         }
    275         $fp = $this->FP;
    276         $Total = $this->COUNT;
    277         if( (!$Total) or ($Total == -1) )
    278         {
    279             return false;
    280         }
    281         if($Total == 0)
    282         {
    283             return array("0","0");
    284             // return -1;   // mailbox empty
    285         }
    286 
    287         $this->update_timer();
     279    /**
     280     * Log in to the POP3 server.
     281     * Does not support APOP (RFC 2828, 4949).
     282     * @access public
     283     * @param string $username
     284     * @param string $password
     285     * @return boolean
     286     */
     287    public function login($username = '', $password = '')
     288    {
     289        if ($this->connected == false) {
     290            $this->error = 'Not connected to POP3 server';
    288291
    289         if(!empty($msgNum))
    290         {
    291             $cmd = "LIST $msgNum";
    292             fwrite($fp,"$cmd\r\n");
    293             $reply = fgets($fp,$this->BUFFER);
    294             $reply = $this->strip_clf($reply);
    295             if($this->DEBUG) {
    296                 @error_log("POP3 SEND [$cmd] GOT [$reply]",0);
     292            if ($this->do_debug >= 1) {
     293                $this->displayErrors();
    297294            }
    298             if(!$this->is_ok($reply))
    299             {
    300                 $this->ERROR = "POP3 pop_list: " . _("Error ") . "[$reply]";
    301                 return false;
    302             }
    303             list($junk,$num,$size) = preg_split('/\s+/',$reply);
    304             return $size;
    305295        }
    306         $cmd = "LIST";
    307         $reply = $this->send_cmd($cmd);
    308         if(!$this->is_ok($reply))
    309         {
    310             $reply = $this->strip_clf($reply);
    311             $this->ERROR = "POP3 pop_list: " . _("Error ") .  "[$reply]";
    312             return false;
     296        if (empty($username)) {
     297            $username = $this->username;
    313298        }
    314         $MsgArray = array();
    315         $MsgArray[0] = $Total;
    316         for($msgC=1;$msgC <= $Total; $msgC++)
    317         {
    318             if($msgC > $Total) { break; }
    319             $line = fgets($fp,$this->BUFFER);
    320             $line = $this->strip_clf($line);
    321             if(strpos($line, '.') === 0)
    322             {
    323                 $this->ERROR = "POP3 pop_list: " . _("Premature end of list");
    324                 return false;
    325             }
    326             list($thisMsg,$msgSize) = preg_split('/\s+/',$line);
    327             settype($thisMsg,"integer");
    328             if($thisMsg != $msgC)
    329             {
    330                 $MsgArray[$msgC] = "deleted";
    331             }
    332             else
    333             {
    334                 $MsgArray[$msgC] = $msgSize;
    335             }
     299        if (empty($password)) {
     300            $password = $this->password;
    336301        }
    337         return $MsgArray;
    338     }
    339 
    340     function get ($msgNum) {
    341         //  Retrieve the specified msg number. Returns an array
    342         //  where each line of the msg is an array element.
    343302
    344         if(!isset($this->FP))
    345         {
    346             $this->ERROR = "POP3 get: " . _("No connection to server");
    347             return false;
    348         }
    349 
    350         $this->update_timer();
    351 
    352         $fp = $this->FP;
    353         $buffer = $this->BUFFER;
    354         $cmd = "RETR $msgNum";
    355         $reply = $this->send_cmd($cmd);
    356 
    357         if(!$this->is_ok($reply))
    358         {
    359             $this->ERROR = "POP3 get: " . _("Error ") . "[$reply]";
    360             return false;
    361         }
    362 
    363         $count = 0;
    364         $MsgArray = array();
    365 
    366         $line = fgets($fp,$buffer);
    367         while ( !preg_match('/^\.\r\n/',$line))
    368         {
    369             if ( $line{0} == '.' ) { $line = substr($line,1); }
    370             $MsgArray[$count] = $line;
    371             $count++;
    372             $line = fgets($fp,$buffer);
    373             if(empty($line))    { break; }
    374         }
    375         return $MsgArray;
    376     }
    377 
    378     function last ( $type = "count" ) {
    379         //  Returns the highest msg number in the mailbox.
    380         //  returns -1 on error, 0+ on success, if type != count
    381         //  results in a popstat() call (2 element array returned)
    382 
    383         $last = -1;
    384         if(!isset($this->FP))
    385         {
    386             $this->ERROR = "POP3 last: " . _("No connection to server");
    387             return $last;
    388         }
    389 
    390         $reply = $this->send_cmd("STAT");
    391         if(!$this->is_ok($reply))
    392         {
    393             $this->ERROR = "POP3 last: " . _("Error ") . "[$reply]";
    394             return $last;
    395         }
    396 
    397         $Vars = preg_split('/\s+/',$reply);
    398         $count = $Vars[1];
    399         $size = $Vars[2];
    400         settype($count,"integer");
    401         settype($size,"integer");
    402         if($type != "count")
    403         {
    404             return array($count,$size);
    405         }
    406         return $count;
    407     }
    408 
    409     function reset () {
    410         //  Resets the status of the remote server. This includes
    411         //  resetting the status of ALL msgs to not be deleted.
    412         //  This method automatically closes the connection to the server.
    413 
    414         if(!isset($this->FP))
    415         {
    416             $this->ERROR = "POP3 reset: " . _("No connection to server");
    417             return false;
    418         }
    419         $reply = $this->send_cmd("RSET");
    420         if(!$this->is_ok($reply))
    421         {
    422             //  The POP3 RSET command -never- gives a -ERR
    423             //  response - if it ever does, something truely
    424             //  wild is going on.
    425 
    426             $this->ERROR = "POP3 reset: " . _("Error ") . "[$reply]";
    427             @error_log("POP3 reset: ERROR [$reply]",0);
     303        // Send the Username
     304        $this->sendString("USER $username" . self::CRLF);
     305        $pop3_response = $this->getResponse();
     306        if ($this->checkResponse($pop3_response)) {
     307            // Send the Password
     308            $this->sendString("PASS $password" . self::CRLF);
     309            $pop3_response = $this->getResponse();
     310            if ($this->checkResponse($pop3_response)) {
     311                return true;
     312            }
    428313        }
    429         $this->quit();
    430         return true;
     314        return false;
    431315    }
    432316
    433     function send_cmd ( $cmd = "" )
     317    /**
     318     * Disconnect from the POP3 server.
     319     * @access public
     320     */
     321    public function disconnect()
    434322    {
    435         //  Sends a user defined command string to the
    436         //  POP server and returns the results. Useful for
    437         //  non-compliant or custom POP servers.
    438         //  Do NOT includ the \r\n as part of your command
    439         //  string - it will be appended automatically.
    440 
    441         //  The return value is a standard fgets() call, which
    442         //  will read up to $this->BUFFER bytes of data, until it
    443         //  encounters a new line, or EOF, whichever happens first.
    444 
    445         //  This method works best if $cmd responds with only
    446         //  one line of data.
    447 
    448         if(!isset($this->FP))
    449         {
    450             $this->ERROR = "POP3 send_cmd: " . _("No connection to server");
    451             return false;
    452         }
    453 
    454         if(empty($cmd))
    455         {
    456             $this->ERROR = "POP3 send_cmd: " . _("Empty command string");
    457             return "";
    458         }
    459 
    460         $fp = $this->FP;
    461         $buffer = $this->BUFFER;
    462         $this->update_timer();
    463         fwrite($fp,"$cmd\r\n");
    464         $reply = fgets($fp,$buffer);
    465         $reply = $this->strip_clf($reply);
    466         if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
    467         return $reply;
     323        $this->sendString('QUIT');
     324        //The QUIT command may cause the daemon to exit, which will kill our connection
     325        //So ignore errors here
     326        @fclose($this->pop_conn);
    468327    }
    469328
    470     function quit() {
    471         //  Closes the connection to the POP3 server, deleting
    472         //  any msgs marked as deleted.
    473 
    474         if(!isset($this->FP))
    475         {
    476             $this->ERROR = "POP3 quit: " . _("connection does not exist");
    477             return false;
    478         }
    479         $fp = $this->FP;
    480         $cmd = "QUIT";
    481         fwrite($fp,"$cmd\r\n");
    482         $reply = fgets($fp,$this->BUFFER);
    483         $reply = $this->strip_clf($reply);
    484         if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
    485         fclose($fp);
    486         unset($this->FP);
    487         return true;
    488     }
    489 
    490     function popstat () {
    491         //  Returns an array of 2 elements. The number of undeleted
    492         //  msgs in the mailbox, and the size of the mbox in octets.
    493 
    494         $PopArray = $this->last("array");
    495 
    496         if($PopArray == -1) { return false; }
    497 
    498         if( (!$PopArray) or (empty($PopArray)) )
    499         {
    500             return false;
     329    /**
     330     * Get a response from the POP3 server.
     331     * $size is the maximum number of bytes to retrieve
     332     * @param integer $size
     333     * @return string
     334     * @access private
     335     */
     336    private function getResponse($size = 128)
     337    {
     338        $response = fgets($this->pop_conn, $size);
     339        if ($this->do_debug >= 1) {
     340            echo "Server -> Client: $response";
    501341        }
    502         return $PopArray;
     342        return $response;
    503343    }
    504344
    505     function uidl ($msgNum = "")
     345    /**
     346     * Send raw data to the POP3 server.
     347     * @param string $string
     348     * @return integer
     349     * @access private
     350     */
     351    private function sendString($string)
    506352    {
    507         //  Returns the UIDL of the msg specified. If called with
    508         //  no arguments, returns an associative array where each
    509         //  undeleted msg num is a key, and the msg's uidl is the element
    510         //  Array element 0 will contain the total number of msgs
    511 
    512         if(!isset($this->FP)) {
    513             $this->ERROR = "POP3 uidl: " . _("No connection to server");
    514             return false;
    515         }
    516 
    517         $fp = $this->FP;
    518         $buffer = $this->BUFFER;
    519 
    520         if(!empty($msgNum)) {
    521             $cmd = "UIDL $msgNum";
    522             $reply = $this->send_cmd($cmd);
    523             if(!$this->is_ok($reply))
    524             {
    525                 $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]";
    526                 return false;
     353        if ($this->pop_conn) {
     354            if ($this->do_debug >= 2) { //Show client messages when debug >= 2
     355                echo "Client -> Server: $string";
    527356            }
    528             list ($ok,$num,$myUidl) = preg_split('/\s+/',$reply);
    529             return $myUidl;
    530         } else {
    531             $this->update_timer();
    532 
    533             $UIDLArray = array();
    534             $Total = $this->COUNT;
    535             $UIDLArray[0] = $Total;
    536 
    537             if ($Total < 1)
    538             {
    539                 return $UIDLArray;
    540             }
    541             $cmd = "UIDL";
    542             fwrite($fp, "UIDL\r\n");
    543             $reply = fgets($fp, $buffer);
    544             $reply = $this->strip_clf($reply);
    545             if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
    546             if(!$this->is_ok($reply))
    547             {
    548                 $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]";
    549                 return false;
    550             }
    551 
    552             $line = "";
    553             $count = 1;
    554             $line = fgets($fp,$buffer);
    555             while ( !preg_match('/^\.\r\n/',$line)) {
    556                 list ($msg,$msgUidl) = preg_split('/\s+/',$line);
    557                 $msgUidl = $this->strip_clf($msgUidl);
    558                 if($count == $msg) {
    559                     $UIDLArray[$msg] = $msgUidl;
    560                 }
    561                 else
    562                 {
    563                     $UIDLArray[$count] = 'deleted';
    564                 }
    565                 $count++;
    566                 $line = fgets($fp,$buffer);
    567             }
    568         }
    569         return $UIDLArray;
    570     }
    571 
    572     function delete ($msgNum = "") {
    573         //  Flags a specified msg as deleted. The msg will not
    574         //  be deleted until a quit() method is called.
    575 
    576         if(!isset($this->FP))
    577         {
    578             $this->ERROR = "POP3 delete: " . _("No connection to server");
    579             return false;
    580         }
    581         if(empty($msgNum))
    582         {
    583             $this->ERROR = "POP3 delete: " . _("No msg number submitted");
    584             return false;
    585         }
    586         $reply = $this->send_cmd("DELE $msgNum");
    587         if(!$this->is_ok($reply))
    588         {
    589             $this->ERROR = "POP3 delete: " . _("Command failed ") . "[$reply]";
    590             return false;
     357            return fwrite($this->pop_conn, $string, strlen($string));
    591358        }
    592         return true;
     359        return 0;
    593360    }
    594361
    595     //  *********************************************************
    596 
    597     //  The following methods are internal to the class.
    598 
    599     function is_ok ($cmd = "") {
    600         //  Return true or false on +OK or -ERR
    601 
    602         if( empty($cmd) )
     362    /**
     363     * Checks the POP3 server response.
     364     * Looks for for +OK or -ERR.
     365     * @param string $string
     366     * @return boolean
     367     * @access private
     368     */
     369    private function checkResponse($string)
     370    {
     371        if (substr($string, 0, 3) !== '+OK') {
     372            $this->error = array(
     373                'error' => "Server reported an error: $string",
     374                'errno' => 0,
     375                'errstr' => ''
     376            );
     377            if ($this->do_debug >= 1) {
     378                $this->displayErrors();
     379            }
    603380            return false;
    604         else
    605             return( stripos($cmd, '+OK') !== false );
    606     }
    607 
    608     function strip_clf ($text = "") {
    609         // Strips \r\n from server responses
    610 
    611         if(empty($text))
    612             return $text;
    613         else {
    614             $stripped = str_replace(array("\r","\n"),'',$text);
    615             return $stripped;
     381        } else {
     382            return true;
    616383        }
    617384    }
    618385
    619     function parse_banner ( $server_text ) {
    620         $outside = true;
    621         $banner = "";
    622         $length = strlen($server_text);
    623         for($count =0; $count < $length; $count++)
    624         {
    625             $digit = substr($server_text,$count,1);
    626             if(!empty($digit))             {
    627                 if( (!$outside) && ($digit != '<') && ($digit != '>') )
    628                 {
    629                     $banner .= $digit;
    630                 }
    631                 if ($digit == '<')
    632                 {
    633                     $outside = false;
    634                 }
    635                 if($digit == '>')
    636                 {
    637                     $outside = true;
    638                 }
    639             }
     386    /**
     387     * Display errors if debug is enabled.
     388     * @access private
     389     */
     390    private function displayErrors()
     391    {
     392        echo '<pre>';
     393        foreach ($this->error as $single_error) {
     394            print_r($single_error);
    640395        }
    641         $banner = $this->strip_clf($banner);    // Just in case
    642         return "<$banner>";
     396        echo '</pre>';
    643397    }
    644398
    645 }   // End class
    646 
    647 // For php4 compatibility
    648 if (!function_exists("stripos")) {
    649     function stripos($haystack, $needle){
    650         return strpos($haystack, stristr( $haystack, $needle ));
     399    /**
     400     * POP3 connection error handler.
     401     * @param integer $errno
     402     * @param string $errstr
     403     * @param string $errfile
     404     * @param integer $errline
     405     * @access private
     406     */
     407    private function catchWarning($errno, $errstr, $errfile, $errline)
     408    {
     409        $this->error[] = array(
     410            'error' => "Connecting to the POP3 server raised a PHP warning: ",
     411            'errno' => $errno,
     412            'errstr' => $errstr,
     413            'errfile' => $errfile,
     414            'errline' => $errline
     415        );
    651416    }
    652417}
  • src/wp-includes/class-smtp.php

    diff --git a/src/wp-includes/class-smtp.php b/src/wp-includes/class-smtp.php
    index e6b4522..ec75ca5 100644
    a b  
    11<?php
    22/**
    33 * PHPMailer RFC821 SMTP email transport class.
    4  * Version 5.2.7
    5  * PHP version 5.0.0
    6  * @category  PHP
    7  * @package   PHPMailer
    8  * @link      https://github.com/PHPMailer/PHPMailer/
    9  * @author Marcus Bointon (coolbru) <phpmailer@synchromedia.co.uk>
     4 * PHP Version 5
     5 * @package PHPMailer
     6 * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
     7 * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
    108 * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
    119 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
    12  * @copyright 2013 Marcus Bointon
    13  * @copyright 2004 - 2008 Andy Prevost
     10 * @author Brent R. Matzelle (original founder)
     11 * @copyright 2014 Marcus Bointon
    1412 * @copyright 2010 - 2012 Jim Jagielski
    15  * @license   http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
     13 * @copyright 2004 - 2009 Andy Prevost
     14 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
     15 * @note This program is distributed in the hope that it will be useful - WITHOUT
     16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     17 * FITNESS FOR A PARTICULAR PURPOSE.
    1618 */
    1719
    1820/**
    1921 * PHPMailer RFC821 SMTP email transport class.
    20  *
    21  * Implements RFC 821 SMTP commands
    22  * and provides some utility methods for sending mail to an SMTP server.
    23  *
    24  * PHP Version 5.0.0
    25  *
    26  * @category PHP
    27  * @package  PHPMailer
    28  * @link     https://github.com/PHPMailer/PHPMailer/blob/master/class.smtp.php
    29  * @author   Chris Ryan <unknown@example.com>
    30  * @author   Marcus Bointon <phpmailer@synchromedia.co.uk>
    31  * @license  http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
     22 * Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server.
     23 * @package PHPMailer
     24 * @author Chris Ryan <unknown@example.com>
     25 * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
    3226 */
    33 
    3427class SMTP
    3528{
    3629    /**
    37      * The PHPMailer SMTP Version number.
     30     * The PHPMailer SMTP version number.
     31     * @type string
    3832     */
    39     const VERSION = '5.2.7';
     33    const VERSION = '5.2.8';
    4034
    4135    /**
    4236     * SMTP line break constant.
     37     * @type string
    4338     */
    4439    const CRLF = "\r\n";
    4540
    4641    /**
    4742     * The SMTP port to use if one is not specified.
     43     * @type int
    4844     */
    4945    const DEFAULT_SMTP_PORT = 25;
    5046
    5147    /**
     48     * The maximum line length allowed by RFC 2822 section 2.1.1
     49     * @type int
     50     */
     51    const MAX_LINE_LENGTH = 998;
     52
     53    /**
    5254     * The PHPMailer SMTP Version number.
    5355     * @type string
    54      * @deprecated This should be a constant
     56     * @deprecated Use the constant instead
    5557     * @see SMTP::VERSION
    5658     */
    57     public $Version = '5.2.7';
     59    public $Version = '5.2.8';
    5860
    5961    /**
    6062     * SMTP server port number.
    6163     * @type int
    62      * @deprecated This is only ever ued as default value, so should be a constant
     64     * @deprecated This is only ever used as a default value, so use the constant instead
    6365     * @see SMTP::DEFAULT_SMTP_PORT
    6466     */
    6567    public $SMTP_PORT = 25;
    6668
    6769    /**
    68      * SMTP reply line ending
     70     * SMTP reply line ending.
    6971     * @type string
    70      * @deprecated Use the class constant instead
     72     * @deprecated Use the constant instead
    7173     * @see SMTP::CRLF
    7274     */
    7375    public $CRLF = "\r\n";
    7476
    7577    /**
    7678     * Debug output level.
    77      * Options: 0 for no output, 1 for commands, 2 for data and commands
     79     * Options:
     80     * * `0` No output
     81     * * `1` Commands
     82     * * `2` Data and commands
     83     * * `3` As 2 plus connection status
     84     * * `4` Low-level data output
    7885     * @type int
    7986     */
    8087    public $do_debug = 0;
    8188
    8289    /**
    83      * The function/method to use for debugging output.
    84      * Options: 'echo', 'html' or 'error_log'
     90     * How to handle debug output.
     91     * Options:
     92     * * `echo` Output plain-text as-is, appropriate for CLI
     93     * * `html` Output escaped, line breaks converted to <br>, appropriate for browser output
     94     * * `error_log` Output to error log as configured in php.ini
    8595     * @type string
    8696     */
    8797    public $Debugoutput = 'echo';
    8898
    8999    /**
    90100     * Whether to use VERP.
     101     * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path
     102     * @link http://www.postfix.org/VERP_README.html Info on VERP
    91103     * @type bool
    92104     */
    93105    public $do_verp = false;
    94106
    95107    /**
    96      * The SMTP timeout value for reads, in seconds.
     108     * The timeout value for connection, in seconds.
     109     * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
     110     * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.
     111     * @link http://tools.ietf.org/html/rfc2821#section-4.5.3.2
    97112     * @type int
    98113     */
    99     public $Timeout = 15;
     114    public $Timeout = 300;
    100115
    101116    /**
    102117     * The SMTP timelimit value for reads, in seconds.
    class SMTP 
    137152        $this->smtp_conn = 0;
    138153        $this->error = null;
    139154        $this->helo_rply = null;
    140 
    141155        $this->do_debug = 0;
    142156    }
    143157
    class SMTP 
    164178                break;
    165179            case 'echo':
    166180            default:
    167                 //Just echoes whatever was received
    168                 echo $str;
     181                echo gmdate('Y-m-d H:i:s')."\t".trim($str)."\n";
    169182        }
    170183    }
    171184
    172185    /**
    173186     * Connect to an SMTP server.
    174      * @param string $host    SMTP server IP or host name
    175      * @param int $port    The port number to connect to
     187     * @param string $host SMTP server IP or host name
     188     * @param int $port The port number to connect to
    176189     * @param int $timeout How long to wait for the connection to open
    177190     * @param array $options An array of options for stream_context_create()
    178191     * @access public
    class SMTP 
    182195    {
    183196        // Clear errors to avoid confusion
    184197        $this->error = null;
    185 
    186198        // Make sure we are __not__ connected
    187199        if ($this->connected()) {
    188200            // Already connected, generate error
    189201            $this->error = array('error' => 'Already connected to a server');
    190202            return false;
    191203        }
    192 
    193204        if (empty($port)) {
    194205            $port = self::DEFAULT_SMTP_PORT;
    195206        }
    196 
    197207        // Connect to the SMTP server
     208        if ($this->do_debug >= 3) {
     209            $this->edebug('Connection: opening');
     210        }
    198211        $errno = 0;
    199212        $errstr = '';
    200213        $socket_context = stream_context_create($options);
    class SMTP 
    207220            STREAM_CLIENT_CONNECT,
    208221            $socket_context
    209222        );
    210 
    211223        // Verify we connected properly
    212224        if (empty($this->smtp_conn)) {
    213225            $this->error = array(
    class SMTP 
    217229            );
    218230            if ($this->do_debug >= 1) {
    219231                $this->edebug(
    220                     'SMTP -> ERROR: ' . $this->error['error']
     232                    'SMTP ERROR: ' . $this->error['error']
    221233                    . ": $errstr ($errno)"
    222234                );
    223235            }
    224236            return false;
    225237        }
    226 
     238        if ($this->do_debug >= 3) {
     239            $this->edebug('Connection: opened');
     240        }
    227241        // SMTP server can take longer to respond, give longer timeout for first read
    228242        // Windows does not have support for this timeout function
    229243        if (substr(PHP_OS, 0, 3) != 'WIN') {
    class SMTP 
    233247            }
    234248            stream_set_timeout($this->smtp_conn, $timeout, 0);
    235249        }
    236 
    237250        // Get any announcement
    238251        $announce = $this->get_lines();
    239 
    240252        if ($this->do_debug >= 2) {
    241             $this->edebug('SMTP -> FROM SERVER:' . $announce);
     253            $this->edebug('SERVER -> CLIENT: ' . $announce);
    242254        }
    243 
    244255        return true;
    245256    }
    246257
    class SMTP 
    251262     */
    252263    public function startTLS()
    253264    {
    254         if (!$this->sendCommand("STARTTLS", "STARTTLS", 220)) {
     265        if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) {
    255266            return false;
    256267        }
    257268        // Begin encrypted connection
    class SMTP 
    259270            $this->smtp_conn,
    260271            true,
    261272            STREAM_CRYPTO_METHOD_TLS_CLIENT
    262         )
    263         ) {
     273        )) {
    264274            return false;
    265275        }
    266276        return true;
    class SMTP 
    288298        if (empty($authtype)) {
    289299            $authtype = 'LOGIN';
    290300        }
    291 
    292301        switch ($authtype) {
    293302            case 'PLAIN':
    294303                // Start authentication
    class SMTP 
    351360                ) {
    352361                    return false;
    353362                }
    354 
    355363                //Though 0 based, there is a white space after the 3 digit number
    356364                //msg2
    357365                $challenge = substr($this->last_reply, 3);
    class SMTP 
    411419        // Eliminates the need to install mhash to compute a HMAC
    412420        // Hacked by Lance Rushing
    413421
    414         $b = 64; // byte length for md5
    415         if (strlen($key) > $b) {
     422        $bytelen = 64; // byte length for md5
     423        if (strlen($key) > $bytelen) {
    416424            $key = pack('H*', md5($key));
    417425        }
    418         $key = str_pad($key, $b, chr(0x00));
    419         $ipad = str_pad('', $b, chr(0x36));
    420         $opad = str_pad('', $b, chr(0x5c));
     426        $key = str_pad($key, $bytelen, chr(0x00));
     427        $ipad = str_pad('', $bytelen, chr(0x36));
     428        $opad = str_pad('', $bytelen, chr(0x5c));
    421429        $k_ipad = $key ^ $ipad;
    422430        $k_opad = $key ^ $opad;
    423431
    class SMTP 
    437445                // the socket is valid but we are not connected
    438446                if ($this->do_debug >= 1) {
    439447                    $this->edebug(
    440                         'SMTP -> NOTICE: EOF caught while checking if connected'
     448                        'SMTP NOTICE: EOF caught while checking if connected'
    441449                    );
    442450                }
    443451                $this->close();
    class SMTP 
    462470        if (!empty($this->smtp_conn)) {
    463471            // close the connection and cleanup
    464472            fclose($this->smtp_conn);
     473            if ($this->do_debug >= 3) {
     474                $this->edebug('Connection: closed');
     475            }
    465476            $this->smtp_conn = 0;
    466477        }
    467478    }
    class SMTP 
    483494        if (!$this->sendCommand('DATA', 'DATA', 354)) {
    484495            return false;
    485496        }
    486 
    487497        /* The server is ready to accept data!
    488          * according to rfc821 we should not send more than 1000
    489          * including the CRLF
    490          * characters on a single line so we will break the data up
    491          * into lines by \r and/or \n then if needed we will break
    492          * each of those into smaller lines to fit within the limit.
    493          * in addition we will be looking for lines that start with
    494          * a period '.' and append and additional period '.' to that
    495          * line. NOTE: this does not count towards limit.
     498         * According to rfc821 we should not send more than 1000 characters on a single line (including the CRLF)
     499         * so we will break the data up into lines by \r and/or \n then if needed we will break each of those into
     500         * smaller lines to fit within the limit.
     501         * We will also look for lines that start with a '.' and prepend an additional '.'.
     502         * NOTE: this does not count towards line-length limit.
    496503         */
    497504
    498         // Normalize the line breaks before exploding
    499         $msg_data = str_replace("\r\n", "\n", $msg_data);
    500         $msg_data = str_replace("\r", "\n", $msg_data);
    501         $lines = explode("\n", $msg_data);
    502 
    503         /* We need to find a good way to determine if headers are
    504          * in the msg_data or if it is a straight msg body
    505          * currently I am assuming rfc822 definitions of msg headers
    506          * and if the first field of the first line (':' separated)
    507          * does not contain a space then it _should_ be a header
    508          * and we can process all lines before a blank "" line as
    509          * headers.
     505        // Normalize line breaks before exploding
     506        $lines = explode("\n", str_replace(array("\r\n", "\r"), "\n", $msg_data));
     507
     508        /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field
     509         * of the first line (':' separated) does not contain a space then it _should_ be a header and we will
     510         * process all lines before a blank line as headers.
    510511         */
    511512
    512513        $field = substr($lines[0], 0, strpos($lines[0], ':'));
    513514        $in_headers = false;
    514         if (!empty($field) && !strstr($field, ' ')) {
     515        if (!empty($field) && strpos($field, ' ') === false) {
    515516            $in_headers = true;
    516517        }
    517518
    518         //RFC 2822 section 2.1.1 limit
    519         $max_line_length = 998;
    520 
    521519        foreach ($lines as $line) {
    522             $lines_out = null;
    523             if ($line == '' && $in_headers) {
     520            $lines_out = array();
     521            if ($in_headers and $line == '') {
    524522                $in_headers = false;
    525523            }
    526524            // ok we need to break this line up into several smaller lines
    527             while (strlen($line) > $max_line_length) {
    528                 $pos = strrpos(substr($line, 0, $max_line_length), ' ');
    529 
    530                 // Patch to fix DOS attack
    531                 if (!$pos) {
    532                     $pos = $max_line_length - 1;
     525            //This is a small micro-optimisation: isset($str[$len]) is equivalent to (strlen($str) > $len)
     526            while (isset($line[self::MAX_LINE_LENGTH])) {
     527                //Working backwards, try to find a space within the last MAX_LINE_LENGTH chars of the line to break on
     528                //so as to avoid breaking in the middle of a word
     529                $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' ');
     530                if (!$pos) { //Deliberately matches both false and 0
     531                    //No nice break found, add a hard break
     532                    $pos = self::MAX_LINE_LENGTH - 1;
    533533                    $lines_out[] = substr($line, 0, $pos);
    534534                    $line = substr($line, $pos);
    535535                } else {
     536                    //Break at the found point
    536537                    $lines_out[] = substr($line, 0, $pos);
     538                    //Move along by the amount we dealt with
    537539                    $line = substr($line, $pos + 1);
    538540                }
    539 
    540541                /* If processing headers add a LWSP-char to the front of new line
    541                  * rfc822 on long msg headers
     542                 * RFC822 section 3.1.1
    542543                 */
    543544                if ($in_headers) {
    544545                    $line = "\t" . $line;
    class SMTP 
    546547            }
    547548            $lines_out[] = $line;
    548549
    549             // send the lines to the server
    550             while (list(, $line_out) = @each($lines_out)) {
    551                 if (strlen($line_out) > 0) {
    552                     if (substr($line_out, 0, 1) == '.') {
    553                         $line_out = '.' . $line_out;
    554                     }
     550            // Send the lines to the server
     551            foreach ($lines_out as $line_out) {
     552                //RFC2821 section 4.5.2
     553                if (!empty($line_out) and $line_out[0] == '.') {
     554                    $line_out = '.' . $line_out;
    555555                }
    556556                $this->client_send($line_out . self::CRLF);
    557557            }
    class SMTP 
    565565     * Send an SMTP HELO or EHLO command.
    566566     * Used to identify the sending server to the receiving server.
    567567     * This makes sure that client and server are in a known state.
    568      * Implements from RFC 821: HELO <SP> <domain> <CRLF>
     568     * Implements RFC 821: HELO <SP> <domain> <CRLF>
    569569     * and RFC 2821 EHLO.
    570570     * @param string $host The host name or IP to connect to
    571571     * @access public
    class SMTP 
    574574    public function hello($host = '')
    575575    {
    576576        // Try extended hello first (RFC 2821)
    577         if (!$this->sendHello('EHLO', $host)) {
    578             if (!$this->sendHello('HELO', $host)) {
    579                 return false;
    580             }
    581         }
    582 
    583         return true;
     577        return (bool)($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host));
    584578    }
    585579
    586580    /**
    class SMTP 
    588582     * Low-level implementation used by hello()
    589583     * @see hello()
    590584     * @param string $hello The HELO string
    591      * @param string $host  The hostname to say we are
     585     * @param string $host The hostname to say we are
    592586     * @access protected
    593587     * @return bool
    594588     */
    class SMTP 
    631625    public function quit($close_on_error = true)
    632626    {
    633627        $noerror = $this->sendCommand('QUIT', 'QUIT', 221);
    634         $e = $this->error; //Save any error
     628        $err = $this->error; //Save any error
    635629        if ($noerror or $close_on_error) {
    636630            $this->close();
    637             $this->error = $e; //Restore any error from the quit command
     631            $this->error = $err; //Restore any error from the quit command
    638632        }
    639633        return $noerror;
    640634    }
    641635
    642636    /**
    643637     * Send an SMTP RCPT command.
    644      * Sets the TO argument to $to.
     638     * Sets the TO argument to $toaddr.
    645639     * Returns true if the recipient was accepted false if it was rejected.
    646640     * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
    647      * @param string $to The address the message is being sent to
     641     * @param string $toaddr The address the message is being sent to
    648642     * @access public
    649643     * @return bool
    650644     */
    651     public function recipient($to)
     645    public function recipient($toaddr)
    652646    {
    653647        return $this->sendCommand(
    654             'RCPT TO ',
    655             'RCPT TO:<' . $to . '>',
     648            'RCPT TO',
     649            'RCPT TO:<' . $toaddr . '>',
    656650            array(250, 251)
    657651        );
    658652    }
    class SMTP 
    681675    {
    682676        if (!$this->connected()) {
    683677            $this->error = array(
    684                 "error" => "Called $command without being connected"
     678                'error' => "Called $command without being connected"
    685679            );
    686680            return false;
    687681        }
    class SMTP 
    691685        $code = substr($reply, 0, 3);
    692686
    693687        if ($this->do_debug >= 2) {
    694             $this->edebug('SMTP -> FROM SERVER:' . $reply);
     688            $this->edebug('SERVER -> CLIENT: ' . $reply);
    695689        }
    696690
    697691        if (!in_array($code, (array)$expect)) {
    698692            $this->last_reply = null;
    699693            $this->error = array(
    700                 "error" => "$command command failed",
    701                 "smtp_code" => $code,
    702                 "detail" => substr($reply, 4)
     694                'error' => "$command command failed",
     695                'smtp_code' => $code,
     696                'detail' => substr($reply, 4)
    703697            );
    704698            if ($this->do_debug >= 1) {
    705699                $this->edebug(
    706                     'SMTP -> ERROR: ' . $this->error['error'] . ': ' . $reply
     700                    'SMTP ERROR: ' . $this->error['error'] . ': ' . $reply
    707701                );
    708702            }
    709703            return false;
    class SMTP 
    729723     */
    730724    public function sendAndMail($from)
    731725    {
    732         return $this->sendCommand("SAML", "SAML FROM:$from", 250);
     726        return $this->sendCommand('SAML', "SAML FROM:$from", 250);
    733727    }
    734728
    735729    /**
    class SMTP 
    740734     */
    741735    public function verify($name)
    742736    {
    743         return $this->sendCommand("VRFY", "VRFY $name", array(250, 251));
     737        return $this->sendCommand('VRFY', "VRFY $name", array(250, 251));
    744738    }
    745739
    746740    /**
    class SMTP 
    751745     */
    752746    public function noop()
    753747    {
    754         return $this->sendCommand("NOOP", "NOOP", 250);
     748        return $this->sendCommand('NOOP', 'NOOP', 250);
    755749    }
    756750
    757751    /**
    758752     * Send an SMTP TURN command.
    759753     * This is an optional command for SMTP that this class does not support.
    760      * This method is here to make the RFC821 Definition
    761      * complete for this class and __may__ be implemented in future
     754     * This method is here to make the RFC821 Definition complete for this class
     755     * and _may_ be implemented in future
    762756     * Implements from rfc 821: TURN <CRLF>
    763757     * @access public
    764758     * @return bool
    class SMTP 
    769763            'error' => 'The SMTP TURN command is not implemented'
    770764        );
    771765        if ($this->do_debug >= 1) {
    772             $this->edebug('SMTP -> NOTICE: ' . $this->error['error']);
     766            $this->edebug('SMTP NOTICE: ' . $this->error['error']);
    773767        }
    774768        return false;
    775769    }
    class SMTP 
    778772     * Send raw data to the server.
    779773     * @param string $data The data to send
    780774     * @access public
    781      * @return int|bool The number of bytes sent to the server or FALSE on error
     775     * @return int|bool The number of bytes sent to the server or false on error
    782776     */
    783777    public function client_send($data)
    784778    {
    785779        if ($this->do_debug >= 1) {
    786             $this->edebug("CLIENT -> SMTP: $data");
     780            $this->edebug("CLIENT -> SERVER: $data");
    787781        }
    788782        return fwrite($this->smtp_conn, $data);
    789783    }
    class SMTP 
    819813     */
    820814    protected function get_lines()
    821815    {
    822         $data = '';
    823         $endtime = 0;
    824         // If the connection is bad, give up now
     816        // If the connection is bad, give up straight away
    825817        if (!is_resource($this->smtp_conn)) {
    826             return $data;
     818            return '';
    827819        }
     820        $data = '';
     821        $endtime = 0;
    828822        stream_set_timeout($this->smtp_conn, $this->Timeout);
    829823        if ($this->Timelimit > 0) {
    830824            $endtime = time() + $this->Timelimit;
    class SMTP 
    839833            if ($this->do_debug >= 4) {
    840834                $this->edebug("SMTP -> get_lines(): \$data is \"$data\"");
    841835            }
    842             // if 4th character is a space, we are done reading, break the loop
    843             if (substr($str, 3, 1) == ' ') {
     836            // If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen
     837            if ((isset($str[3]) and $str[3] == ' ')) {
    844838                break;
    845839            }
    846840            // Timed-out? Log and break
    class SMTP 
    854848                break;
    855849            }
    856850            // Now check if reads took too long
    857             if ($endtime) {
    858                 if (time() > $endtime) {
    859                     if ($this->do_debug >= 4) {
    860                         $this->edebug(
    861                             'SMTP -> get_lines(): timelimit reached ('
    862                             . $this->Timelimit . ' sec)'
    863                         );
    864                     }
    865                     break;
     851            if ($endtime and time() > $endtime) {
     852                if ($this->do_debug >= 4) {
     853                    $this->edebug(
     854                        'SMTP -> get_lines(): timelimit reached ('.
     855                        $this->Timelimit . ' sec)'
     856                    );
    866857                }
     858                break;
    867859            }
    868860        }
    869861        return $data;