laminas / laminas-mail

Provides generalized functionality to compose and send both text and MIME-compliant multipart e-mail messages
https://docs.laminas.dev/laminas-mail/
BSD 3-Clause "New" or "Revised" License
93 stars 63 forks source link

POP3 getMessage fails with 'Line "<==UUID==>" does not match header format' #6

Open weierophinney opened 4 years ago

weierophinney commented 4 years ago

We are using zend-mail to fetch emails via POP3 and IMAP. For integration tests, we run an instance of Flying Rat (https://pypi.org/project/flyingrat/) to mock a mail server with POP3. We build multipart emails in Python using MIMEMultipart and send them to the server via smtplib (all standard code used there, nothing fancy).

Now when I try to fetch the emails in zend-mail via getMessage(), it fails with the following exception::

Line "--===============0544532757501787723==" does not match header format!
vendor/zendframework/zend-mail/src/Storage/Part.php(112):   Zend\Mail\Headers::fromString('MIME-Version: 1...')
vendor/zendframework/zend-mail/src/Storage/Message.php(56): Zend\Mail\Storage\Part->__construct(Array)
vendor/zendframework/zend-mail/src/Storage/Pop3.php(63): Zend\Mail\Storage\Message->__construct(Array)
ourclass.php(298): Zend\Mail\Storage\Pop3->getMessage(1)

I have tried to debug this and printed out the $params in Message.php _construct. It looks to me like zend-mail is not able to parse the headers correctly because Flying Rat does not support the TOP command and so the whole message is downloaded. Could this be a bug?

Here is the full debug output of the $params::

 (
     [handler] => Zend\Mail\Storage\Pop3 Object
         (
             [protocol:protected] => Zend\Mail\Protocol\Pop3 Object
                 (
                     [hasTop] =>
                     [socket:protected] => Resource id #9
                     [timestamp:protected] =>
                 )

             [has:protected] => Array
                 (
                     [uniqueid] =>
                     [delete] =>
                     [create] =>
                     [top] =>
                     [fetchPart] =>
                     [flags] =>
                 )

             [iterationPos:protected] => 0
             [iterationMax:protected] =>
             [messageClass:protected] => Zend\Mail\Storage\Message
         )

     [id] => 2
     [headers] => Content-Type: multipart/alternative;
  boundary="===============0544532757501787723=="
 MIME-Version: 1.0
 To: sandbox@example.net
 From: test@example.net
 Subject: Test Url in Text
 Message-Id: <157123321515.20730.13355415221665243427@vagrant.vm>

 --===============0544532757501787723==
 Content-Type: text/plain; charset="us-ascii"
 MIME-Version: 1.0
 Content-Transfer-Encoding: 7bit

 No URL here
 --===============0544532757501787723==
 Content-Type: text/html; charset="us-ascii"
 MIME-Version: 1.0
 Content-Transfer-Encoding: 7bit

 https://example.net
 --===============0544532757501787723==--

     [noToplines] => 1
 )

Originally posted by @abulhol at https://github.com/zendframework/zend-mail/issues/245

weierophinney commented 4 years ago

I have further delved into the source code. The function public static function fromString($string, $EOL = self::EOL) in Headers.php which parses the full message in this case contains no condition for a break, so it is logical that the exception is thrown when the parser reaches the multipart message body. I wonder how this bug could go unnoticed until now?


Originally posted by @abulhol at https://github.com/zendframework/zend-mail/issues/245#issuecomment-543100427

abulhol commented 3 years ago

Any news on this?

Ocramius commented 3 years ago

@abulhol if you have a reproducer (test case), that would help pinning the bug down

abulhol commented 3 years ago

@Ocramius I think I have described the issue in enough detail, and @weierophinney has already investigated it sufficiently (and pinned down the bug). I don't have time to write a test case, sorry.

Ocramius commented 3 years ago

@abulhol eh, then don't expect somebody else to have time/interest in trying to reproduce the problem in their local (and then CI) environment 😞

glensc commented 3 years ago

@abulhol you can at least include a .php snippet and .txt attachment of reproducer as attachments to the pull request. be sure it shows the problem when executed standalone.

abulhol commented 3 years ago

ok @glensc I will see what I can do, thx.

abulhol commented 3 years ago

@Ocramius @glensc Here you go with a fully working example, please let me know if it doesn't run on your side: https://github.com/abulhol/pop3test

abulhol commented 3 years ago

Hey guys, I would appreciate some feedback after having made the effort to create a working example.

abulhol commented 3 years ago

ping

ftoledo commented 3 months ago

i recently see dimilasr issue on glpi:

[2024-05-21 18:22:03] glpiphplog.CRITICAL:   *** Uncaught Exception Laminas\Mail\Exception\RuntimeException: Line "--_00" does not match header format! in /var/www/glpi/vendor/laminas/laminas-mail/src/Headers.php at line 116                
  Backtrace :                                                                                                           
  vendor/laminas/laminas-mime/src/Decode.php:162     Laminas\Mail\Headers::fromString()                                 
  ...r/laminas/laminas-mail/src/Storage/Pop3.php:105 Laminas\Mime\Decode::splitMessage()                                
  ...r/laminas/laminas-mail/src/Storage/Part.php:175 Laminas\Mail\Storage\Pop3->getRawContent()                         
  ...r/laminas/laminas-mail/src/Storage/Part.php:249 Laminas\Mail\Storage\Part->cacheContent()                          
  ...r/laminas/laminas-mail/src/Storage/Part.php:471 Laminas\Mail\Storage\Part->countParts()                            
  src/MailCollector.php:1607                         Laminas\Mail\Storage\Part->rewind()                                
  src/MailCollector.php:1778                         MailCollector->getRecursiveAttached()                              
  src/MailCollector.php:1081                         MailCollector->getAttached()                                       
  src/MailCollector.php:811                          MailCollector->buildTicket()                                       
  src/MailCollector.php:1923                         MailCollector->collect()                                           
  src/CronTask.php:1027                              MailCollector::cronMailgate()                                      
  front/cron.php:82                                  CronTask::launch()