From 2cca67aec1a10e5b2dd020f71ef7dc4619c648c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=A4tzig?= Date: Tue, 7 May 2019 21:33:15 +0200 Subject: [PATCH 1/2] Issue #310: Fixed issue with unparseable datetimes and updated/added PHPUnit tests --- src/PhpImap/Mailbox.php | 24 +++++++++++++++--------- tests/unit/MailboxTest.php | 35 ++++++++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/PhpImap/Mailbox.php b/src/PhpImap/Mailbox.php index cd9e2151..11853ac5 100644 --- a/src/PhpImap/Mailbox.php +++ b/src/PhpImap/Mailbox.php @@ -3,6 +3,7 @@ use stdClass; use Exception; +use DateTime; use PhpImap\IncomingMail; use PhpImap\IncomingMailHeader; use PhpImap\IncomingMailAttachment; @@ -935,17 +936,22 @@ protected function decodeRFC2231($string, $charset = 'utf-8') { /** * Converts the datetime to a normalized datetime - * @param string header datetime - * @return datetime Normalized datetime + * @param string header datetime + * @return datetime Normalized datetime */ - public function parseDateTime($dateHeader){ - if(!empty($dateHeader)) { - $dateRegex = '/\\s*\\(.*?\\)/'; - $dateFormatted = \DateTime::createFromFormat(\DateTime::RFC2822, preg_replace($dateRegex, '', $dateHeader)); - return $dateFormatted->format('Y-m-d H:i:s'); - } else { - $now = new \DateTime; + public function parseDateTime($dateHeader) { + if(empty($dateHeader)) { + throw new InvalidParameterException('parseDateTime() expects parameter 1 to be a parsable string datetime'); + } + + $dateRegex = '/\\s*\\(.*?\\)/'; + $dateFormatted = DateTime::createFromFormat(DateTime::RFC2822, preg_replace($dateRegex, '', $dateHeader)); + + if(is_bool($dateFormatted)) { + $now = new DateTime; return $now->format('Y-m-d H:i:s'); + } else { + return $dateFormatted->format('Y-m-d H:i:s'); } } diff --git a/tests/unit/MailboxTest.php b/tests/unit/MailboxTest.php index 180ed348..6ddfcb4e 100644 --- a/tests/unit/MailboxTest.php +++ b/tests/unit/MailboxTest.php @@ -6,6 +6,7 @@ * @author Sebastian Kraetzig */ +use DateTime; use PhpImap\Mailbox; use PhpImap\Exceptions\ConnectionException; use PhpImap\Exceptions\InvalidParameterException; @@ -318,9 +319,8 @@ public function testEncodingReturnsCorrectValues() /** * Test, different datetimes conversions using differents timezones - */ - - public function testParsedDateDifferentTimeZones(){ + */ + public function testParsedDateDifferentTimeZones() { $test_datetimes = array ( array('Sun, 14 Aug 2005 16:13:03 +0000 (CEST)' ,'1124035983'), array('Sun, 14 Aug 2005 16:13:03 +0000','1124035983'), @@ -371,7 +371,6 @@ public function testParsedDateDifferentTimeZones(){ array('Sun, 14 Aug 2005 16:13:03 +1200 (CEST)','1124035983'), array('Sun, 14 Aug 2005 16:13:03 +1200','1124035983'), - ); foreach($test_datetimes as $datetime) { @@ -383,19 +382,37 @@ public function testParsedDateDifferentTimeZones(){ $parsedDateTime = new DateTime($parsedDt); $this->assertEquals($parsedDateTime->format('U'), $epochToCompare); - } - } + /** + * Test, different invalid / unparseable datetimes conversions + */ + public function testParsedDateWithUnparseableDateTime() { + $test_unparseable_datetimes = array ( + array('14 Aug 2005 16:13:03 +1200 (CEST)','1124035983'), + array('14 Aug 2005 16:13:03 +1200','1124035983'), + array('14 Aug 2005 16:13:03 -0500','1124035983'), + ); + + foreach($test_unparseable_datetimes as $datetime) { + $dateToParse = $datetime["0"]; + $epochToCompare = $datetime["1"]; + + $parsedDt = $this->mailbox->parseDateTime($dateToParse); + + $parsedDateTime = new DateTime($parsedDt); + + $this->assertNotEquals($parsedDateTime->format('U'), $epochToCompare); + } + } /** * Test, parsed datetime being emtpy the header date */ public function testParsedDateTimeWithEmptyHeaderDate() { - $parsedDt = $this->mailbox->parseDateTime(''); - $now = new DateTime; - $this->assertEquals($parsedDt, $now->format('Y-m-d H:i:s')); + $this->expectException(InvalidParameterException::class); + $this->mailbox->parseDateTime(''); } From 855f122b598cde00655899ab8d1e57e59101b8e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=A4tzig?= Date: Tue, 7 May 2019 22:53:26 +0200 Subject: [PATCH 2/2] Updated formatting --- src/PhpImap/DataPartInfo.php | 82 ++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/src/PhpImap/DataPartInfo.php b/src/PhpImap/DataPartInfo.php index c050359e..c8631c52 100644 --- a/src/PhpImap/DataPartInfo.php +++ b/src/PhpImap/DataPartInfo.php @@ -5,54 +5,56 @@ * @author nickl- http://github.com/nickl- */ class DataPartInfo { - - const TEXT_PLAIN = 0; - const TEXT_HTML = 1; + const TEXT_PLAIN = 0; + const TEXT_HTML = 1; - public $id; - public $encoding; - public $charset; + public $id; + public $encoding; + public $charset; public $part; public $mail; public $options; private $data; - + public function __construct($mail, $id, $part, $encoding, $options) { - $this->mail = $mail; - $this->id = $id; - $this->part = $part; - $this->encoding = $encoding; - $this->options = $options; + $this->mail = $mail; + $this->id = $id; + $this->part = $part; + $this->encoding = $encoding; + $this->options = $options; } function fetch() { - if(isset($this->data)) { - return $this->data; - } - if($this->part == 0) { - $this->data = $this->mail->imap('body', [$this->id, $this->options]); - } - else { - $this->data = $this->mail->imap('fetchbody', [$this->id, $this->part, $this->options]); - } - switch($this->encoding) { - case ENC8BIT: - $this->data = imap_utf8($this->data); - break; - case ENCBINARY: - $this->data = imap_binary($this->data); - break; - case ENCBASE64: - $this->data = preg_replace('~[^a-zA-Z0-9+=/]+~s', '', $this->data); // https://github.com/barbushin/php-imap/issues/88 - $this->data = imap_base64($this->data); - break; - case ENCQUOTEDPRINTABLE: - $this->data = quoted_printable_decode($this->data); - break; - } - if(isset($this->charset)) { - $this->data = $this->mail->convertStringEncoding($this->data, $this->charset, $this->mail->getServerEncoding()); - } - return $this->data; + if(isset($this->data)) { + return $this->data; + } + + if($this->part == 0) { + $this->data = $this->mail->imap('body', [$this->id, $this->options]); + } else { + $this->data = $this->mail->imap('fetchbody', [$this->id, $this->part, $this->options]); + } + + switch($this->encoding) { + case ENC8BIT: + $this->data = imap_utf8($this->data); + break; + case ENCBINARY: + $this->data = imap_binary($this->data); + break; + case ENCBASE64: + $this->data = preg_replace('~[^a-zA-Z0-9+=/]+~s', '', $this->data); // https://github.com/barbushin/php-imap/issues/88 + $this->data = imap_base64($this->data); + break; + case ENCQUOTEDPRINTABLE: + $this->data = quoted_printable_decode($this->data); + break; + } + + if(isset($this->charset)) { + $this->data = $this->mail->convertStringEncoding($this->data, $this->charset, $this->mail->getServerEncoding()); + } + + return $this->data; } }