ZF-10489: Zend_Mail_Protocol_Imap : problem to get multiline response

Description

Hello,

I have a problem with multiline send by IMAP server. "_nextTaggedLine()" doesn't decode it correctly.

Multiple lines are sent with something similar to that string "{123}\n". So, if a tagged line contains this at the end, get next lines and add them to current one, while there is a tagged line. Please find here a quick patch :


public function readLine(&$tokens = array(), $wantedTag = '*', $dontParse = false)
    {
        $line = $this->_nextTaggedLine($tag); 

        while (preg_match('/\{\d+\}\s*$/', $line))
        {
         $line = preg_replace('/\{\d+\}\s*$/', '', $line) . $this->_nextLine(); 
        }
        
        if (!$dontParse) {
            $tokens = $this->_decodeLine($line);
        } else {
            $tokens = $line;
        }

        // if tag is wanted tag we might be at the end of a multiline response
        return $tag == $wantedTag;
    }

Comments

It seems the problem is more complex. The end "{123}\n" depends of some requests I think.

When i use $imap->fetch('RFC822.HEADERS', 1), the response for the server look like this :


* 42 FETCH (RFC822.HEADER {1606}
Return-Path: 
X-Original-To: test@test.com
Delivered-To: test@test.com
Received: from xxx.ovh.net (localhost.localdomain [127.0.0.1])
[...]

{1606} correspond to the number of bytes to get for the response.

But when i use $imap->requestAndResponse('FETCH', array(1, 'BODYSTRUCTURE'), false), it fails. I expected to get one line, for all response. Following, as you can see, {9} and others are not the bytes of line length.


* 44 FETCH (FLAGS (\Seen) RFC822.SIZE 486546 UID 99 BODYSTRUCTURE (("application" "pdf" ("name" {9}
16"35.pdf) NIL NIL "base64" 485408 NIL ("inline" ("filename" {9}
16"35.pdf)) NIL NIL) "mixed" ("boundary" "Apple-Mail-1--762503508") NIL NIL NIL) ENVELOPE ("Thu, 16 Sep 2010 13:00:57 +0200" {36}
test piece jointe avec " dans le nom (("Vincent Clair" NIL "test" "test.com")) (("Vincent Clair" NIL "test" "test.com")) (("Vincent Clair" NIL "test" "test.com")) ((NIL NIL "other" "test.com")) NIL NIL NIL ""))

Maybe the issue http://framework.zend.com/issues/browse/ZF-9714 is linked to this. Please take this patch, but i'm not sure that is sufficient :


public function readLine(&$tokens = array(), $wantedTag = '*', $dontParse = false)
    {
        $line = $this->_nextTaggedLine($tag); 

        if (!$dontParse) {
            $tokens = $this->_decodeLine($line);
        } else {
            while (preg_match('/\{\d+\}\s*$/', $line))
            {
             $line = preg_replace('/\{\d+\}\s*$/', '', $line) . $this->_nextLine(); 
            }
        
            $tokens = $line;
        }

        // if tag is wanted tag we might be at the end of a multiline response
        return $tag == $wantedTag;
    }