From 64e3e80743415e5fb121eb5c66416593c38ef288 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Tue, 08 Jun 2010 08:46:05 -0400
Subject: [PATCH] - Fix some IMAP errors handling when opening the message (#1485443)

---
 CHANGELOG                                 |    1 
 program/include/rcube_imap.php            |    4 
 program/steps/mail/func.inc               |   20 ++++++
 program/steps/mail/show.inc               |   20 +-----
 skins/default/templates/messageerror.html |   52 +++++++++++++++++
 program/include/rcube_message.php         |    9 ++-
 program/include/rcube_imap_generic.php    |   14 ++--
 program/js/app.js                         |    4 
 program/steps/mail/headers.inc            |   41 +++++++------
 9 files changed, 116 insertions(+), 49 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index bbeb6d9..f01e089 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG RoundCube Webmail
 ===========================
 
+- Fix some IMAP errors handling when opening the message (#1485443)
 - Fix related parts aren't displayed when got mimetype other than image/* (#1486432)
 - Multiple identity and database support for squirrelmail_usercopy plugin (#1486517)
 - Support dynamic hostname (%d/%n) variables in configuration options (#1485438)
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index f48372a..6f3b402 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -2061,7 +2061,7 @@
             return true;
 
         // convert charset (if text or message part)
-        if ($o_part->ctype_primary == 'text' || $o_part->ctype_primary == 'message') {
+        if ($body && ($o_part->ctype_primary == 'text' || $o_part->ctype_primary == 'message')) {
             // assume default if no charset specified
             if (empty($o_part->charset) || strtolower($o_part->charset) == 'us-ascii')
                 $o_part->charset = $this->default_charset;
@@ -2628,7 +2628,7 @@
             // retrieve list of folders from IMAP server
             $a_mboxes = $this->conn->listMailboxes($this->mod_mailbox($root), $filter);
         }
-        
+
         $a_folders = array();
         if (!is_array($a_mboxes))
             $a_mboxes = array();
diff --git a/program/include/rcube_imap_generic.php b/program/include/rcube_imap_generic.php
index d5a5e3d..7669ceb 100644
--- a/program/include/rcube_imap_generic.php
+++ b/program/include/rcube_imap_generic.php
@@ -1777,12 +1777,11 @@
 		    	$mode = 0;
 	    }
 
-   		$reply_key = '* ' . $id;
-    	$result = false;
-
     	// format request
-		$key     = 'ftch0';
-		$request = $key . ($is_uid ? ' UID' : '') . " FETCH $id (BODY.PEEK[$part])";
+   		$reply_key = '* ' . $id;
+		$key       = 'ftch0';
+		$request   = $key . ($is_uid ? ' UID' : '') . " FETCH $id (BODY.PEEK[$part])";
+
     	// send request
 		if (!$this->putLine($request)) {
 		    return false;
@@ -1794,7 +1793,8 @@
        		$a    = explode(' ', $line);
    		} while (!($end = $this->startsWith($line, $key, true)) && $a[2] != 'FETCH');
 
-   		$len = strlen($line);
+   		$len    = strlen($line);
+    	$result = false;
 
 		// handle empty "* X FETCH ()" response
     	if ($line[$len-1] == ')' && $line[$len-2] != '(') {
@@ -1890,7 +1890,7 @@
         			$line = $this->readLine(1024);
 			} while (!$this->startsWith($line, $key, true));
 
-   		if ($result) {
+   		if ($result !== false) {
 	    	if ($file) {
 		    	fwrite($file, $result);
    			} else if ($print) {
diff --git a/program/include/rcube_message.php b/program/include/rcube_message.php
index 35a8f4a..e51ab26 100644
--- a/program/include/rcube_message.php
+++ b/program/include/rcube_message.php
@@ -5,7 +5,7 @@
  | program/include/rcube_message.php                                     |
  |                                                                       |
  | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2008-2009, RoundCube Dev. - Switzerland                 |
+ | Copyright (C) 2008-2010, RoundCube Dev. - Switzerland                 |
  | Licensed under the GNU GPL                                            |
  |                                                                       |
  | PURPOSE:                                                              |
@@ -63,14 +63,17 @@
     {
         $this->app = rcmail::get_instance();
         $this->imap = $this->app->imap;
-    
+
         $this->uid = $uid;
         $this->headers = $this->imap->get_headers($uid, NULL, true, true);
+
+        if (!$this->headers)
+            return;
 
         $this->subject = rcube_imap::decode_mime_string(
             $this->headers->subject, $this->headers->charset);
         list(, $this->sender) = each($this->imap->decode_address_list($this->headers->from));
-    
+
         $this->set_safe((intval($_GET['_safe']) || $_SESSION['safe_messages'][$uid]));
         $this->opt = array(
             'safe' => $this->is_safe,
diff --git a/program/js/app.js b/program/js/app.js
index 370bdd4..df512d0 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -203,7 +203,7 @@
           'open', 'mark', 'edit', 'viewsource', 'download', 'print', 'load-attachment', 'load-headers'];
 
         if (this.env.action=='show' || this.env.action=='preview') {
-          this.enable_command(this.env.message_commands, true);
+          this.enable_command(this.env.message_commands, this.env.uid);
 
           if (this.env.next_uid) {
             this.enable_command('nextmessage', 'lastmessage', true);
@@ -243,7 +243,7 @@
           this.init_messageform();
         }
         // show printing dialog
-        else if (this.env.action == 'print')
+        else if (this.env.action == 'print' && this.env.uid)
           window.print();
 
         // get unread count for each mailbox
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index d1850d6..defb6f9 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -964,6 +964,11 @@
         if (!isset($part->body))
           $part->body = $MESSAGE->get_part_content($part->mime_id);
 
+        // message is cached but not exists (#1485443), or other error
+        if ($part->body === false) {
+          rcmail_message_error($MESSAGE->uid);
+        }
+
         // re-format format=flowed content
         if ($part->ctype_secondary == "plain" && $part->ctype_parameters['format'] == "flowed")
           $part->body = rcube_message::unfold_flowed($part->body);
@@ -1550,6 +1555,21 @@
   return $out;
 }
 
+function rcmail_message_error($uid=null)
+{
+  global $RCMAIL;
+
+  // Set env variables for messageerror.html template
+  if ($RCMAIL->action == 'show') {
+    $mbox_name = $RCMAIL->imap->get_mailbox_name();
+    $RCMAIL->output->set_env('mailbox', $mbox_name);
+    $RCMAIL->output->set_env('uid', null);
+  }
+  // display error message
+  $RCMAIL->output->show_message('messageopenerror', 'error');
+  // ... display message error page
+  $RCMAIL->output->send('messageerror');
+}
 
 // register UI objects
 $OUTPUT->add_handlers(array(
diff --git a/program/steps/mail/headers.inc b/program/steps/mail/headers.inc
index 946a688..aa10655 100644
--- a/program/steps/mail/headers.inc
+++ b/program/steps/mail/headers.inc
@@ -20,28 +20,31 @@
 
 if ($uid = get_input_value('_uid', RCUBE_INPUT_POST))
 {
-  $source = $IMAP->get_raw_headers($uid);
+    $source = $IMAP->get_raw_headers($uid);
 
-  if ($source)
-    {
-    $source = htmlspecialchars(trim($source));
-    $source = preg_replace(
-      array(
-        '/\n[\t\s]+/',
-        '/^([a-z0-9_:-]+)/im',
-        '/\r?\n/'
-      ),
-      array(
-        "\n&nbsp;&nbsp;&nbsp;&nbsp;",
-        '<font class="bold">\1</font>',
-        '<br />'
-      ), $source);
-    
-    $OUTPUT->command('set_headers', $source);
-    $OUTPUT->send();
+    if ($source !== false) {
+        $source = htmlspecialchars(trim($source));
+        $source = preg_replace(
+            array(
+                '/\n[\t\s]+/',
+                '/^([a-z0-9_:-]+)/im',
+                '/\r?\n/'
+            ),
+            array(
+                "\n&nbsp;&nbsp;&nbsp;&nbsp;",
+                '<font class="bold">\1</font>',
+                '<br />'
+            ), $source);
+
+        $OUTPUT->command('set_headers', $source);
     }
+    else {
+        $RCMAIL->output->show_message('messageopenerror', 'error');
+    }
+
+    $OUTPUT->send();
 }
-  
+
 exit;
 
 ?>
diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc
index 82af478..e130ecb 100644
--- a/program/steps/mail/show.inc
+++ b/program/steps/mail/show.inc
@@ -22,28 +22,18 @@
 $PRINT_MODE = $RCMAIL->action=='print' ? TRUE : FALSE;
 
 // similar code as in program/steps/mail/get.inc
-if ($_GET['_uid']) {
-  $MESSAGE = new rcube_message(get_input_value('_uid', RCUBE_INPUT_GET));
+if ($uid = get_input_value('_uid', RCUBE_INPUT_GET)) {
+  $MESSAGE = new rcube_message($uid);
 
   // if message not found (wrong UID)...
   if (empty($MESSAGE->headers)) {
-    $OUTPUT->show_message('messageopenerror', 'error');
-    // ... display error or preview page
-    if ($RCMAIL->action=='preview' && $OUTPUT->template_exists('messageerror'))
-      $OUTPUT->send('messageerror');
-    else if ($RCMAIL->action=='preview' && $OUTPUT->template_exists('messagepreview'))
-      $OUTPUT->send('messagepreview');
-    // ... go back to the list
-    else {
-      rcmail_overwrite_action('');
-      return;
-    }
+    rcmail_message_error($uid);
   }
 
   send_nocacheing_headers();
 
   $mbox_name = $IMAP->get_mailbox_name();
-  
+
   // show images?
   rcmail_check_safe($MESSAGE);
 
@@ -52,7 +42,7 @@
     $IMAP->set_charset($MESSAGE->headers->charset);
 
   $OUTPUT->set_pagetitle($MESSAGE->subject);
-  
+
   // give message uid to the client
   $OUTPUT->set_env('uid', $MESSAGE->uid);
   // set environement
diff --git a/skins/default/templates/messageerror.html b/skins/default/templates/messageerror.html
index d180e74..0bd591a 100644
--- a/skins/default/templates/messageerror.html
+++ b/skins/default/templates/messageerror.html
@@ -1,8 +1,11 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-<title></title>
+<title><roundcube:object name='productname' /> :: <roundcube:label name='servererror' /></title>
 <roundcube:include file="/includes/links.html" />
+
+<roundcube:if condition="env:action!='show'" />
+
 </head>
 <body class="iframe" style="background-color:#F2F2F2;">
 
@@ -11,4 +14,51 @@
 </div>
 
 </body>
+
+<roundcube:else />
+
+<script type="text/javascript" src="/splitter.js"></script>
+<script type="text/javascript" src="/functions.js"></script>
+<style type="text/css">
+#mailboxlist-container { width: <roundcube:exp expression="!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv-5 : 170" />px; }
+#messageframe { left: <roundcube:exp expression="!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv+5 : 180" />px;
+<roundcube:exp expression="browser:ie ? ('width: expression((parseInt(this.parentNode.offsetWidth)-'.(!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv+5 : 180).')+\\'px\\');') : ''" />
+}
+</style>
+</head>
+
+<body onload="rcube_init_mail_ui()">
+
+<roundcube:include file="/includes/taskbar.html" />
+<roundcube:include file="/includes/header.html" />
+
+<div id="messagetoolbar">
+<roundcube:button command="list" type="link" class="button back" classAct="button back" classSel="button backSel" title="backtolist" content=" " />
+<roundcube:button command="compose" type="link" class="button compose" classAct="button compose" classSel="button composeSel" title="writenewmessage" content=" " />
+</div>
+
+<div id="mainscreen">
+<div id="mailleftcontainer">
+<div id="mailboxlist-container">
+<div class="boxtitle"><roundcube:label name="mailboxlist" /></div>
+<roundcube:object name="mailboxlist" id="mailboxlist" maxlength="25" />
+</div>
+</div>
+
+<div id="messageframe" style="background-color:#F2F2F2;">
+<div style="margin:20px auto; text-align:center">
+<img src="/images/watermark.gif" width="260" height="228" alt="" />
+</div>
+</div>
+
+</div>
+
+<script type="text/javascript">
+    var mailviewsplitv = new rcube_splitter({id:'mailviewsplitterv', p1: 'mailboxlist-container', p2: 'messageframe', orientation: 'v', relative: true, start: 165});
+    rcmail.add_onload('mailviewsplitv.init()');
+</script>
+
+</body>
+<roundcube:endif />
+
 </html>

--
Gitblit v1.9.1