From 8439f61d2eaaf3aa5fb0b911e3b410d70232c1c8 Mon Sep 17 00:00:00 2001 From: pdontthink Date: Fri, 27 Jul 2012 23:03:15 +0000 Subject: [PATCH] Account for servers that send extra unsolicited FETCH responses (such as when flags change due to a FETCH request). PLEASE TEST! git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@14333 7612ce4b-ef26-0410-bec9-ea0150e637f0 --- functions/imap_general.php | 15 +++++++++++++++ functions/mime.php | 8 +++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/functions/imap_general.php b/functions/imap_general.php index 4341df2e..017025ed 100755 --- a/functions/imap_general.php +++ b/functions/imap_general.php @@ -109,6 +109,21 @@ function sqimap_run_command ($imap_stream, $query, $handle_errors, &$response, $message = $message[$tag]; if (!empty($read[$tag])) { + /* sqimap_read_data should be called for one response + but since it just calls sqimap_retrieve_imap_response + which handles multiple responses we need to check for + that and merge the $read[$tag] array IF they are + separated and IF it was a FETCH response. */ + + if (isset($read[$tag][1]) && is_array($read[$tag][1]) && isset($read[$tag][1][0]) + && preg_match('/^\* \d+ FETCH/', $read[$tag][1][0])) { + $result = array(); + foreach($read[$tag] as $index => $value) { + $result = array_merge($result, $read[$tag]["$index"]); + } + return $result; + } + return $read[$tag][0]; } else { return $read[$tag]; diff --git a/functions/mime.php b/functions/mime.php index b8c79f53..1fff67ed 100644 --- a/functions/mime.php +++ b/functions/mime.php @@ -137,7 +137,13 @@ function mime_fetch_body($imap_stream, $id, $ent_id=1, $fetch_size=0) { $data = sqimap_run_command ($imap_stream, $cmd, true, $response, $message, TRUE); do { $topline = trim(array_shift($data)); - } while($topline && ($topline[0] == '*') && !preg_match('/\* [0-9]+ FETCH.*/i', $topline)) ; + } while($topline && ($topline[0] == '*') && !preg_match('/\* [0-9]+ FETCH .*BODY.*/i', $topline)) ; + // Matching with "BODY" above is difficult: in most cases "FETCH \(BODY" would work + // but some servers may put other things in the same result, perhaps something such + // as "* 23 FETCH (FLAGS (\Seen) BODY[1] {174}". There is some small chance that + // if the character sequence "BODY" appears in a response where it isn't actually + // a FETCH response data item name, the current regex will break things. The better + // way to do this would be to parse the response correctly and not use a regex. $wholemessage = implode('', $data); if (preg_match('/\{([^\}]*)\}/', $topline, $regs)) { -- 2.25.1