diff options
-rw-r--r-- | program/include/rcube_imap.php | 42 | ||||
-rw-r--r-- | program/include/rcube_imap_cache.php | 2 | ||||
-rw-r--r-- | program/include/rcube_imap_generic.php | 74 | ||||
-rw-r--r-- | program/steps/mail/func.inc | 22 | ||||
-rw-r--r-- | program/steps/settings/func.inc | 2 |
5 files changed, 76 insertions, 66 deletions
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index c07b39883..d2f954733 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -1508,7 +1508,7 @@ class rcube_imap // I didn't found that SEARCH should return sorted IDs if (is_array($a_index)) sort($a_index); - } else if ($max = $this->_messagecount($mailbox)) { + } else if ($max = $this->_messagecount($mailbox, 'ALL', true, false)) { $a_index = range(1, $max); } @@ -1694,7 +1694,7 @@ class rcube_imap } if ($orig_criteria == 'ALL') { - $max = $this->_messagecount($mailbox); + $max = $this->_messagecount($mailbox, 'ALL', true, false); $a_messages = $max ? range(1, $max) : array(); } else { @@ -1962,6 +1962,10 @@ class rcube_imap $headers = $this->get_headers($uid, $mailbox); + // message doesn't exist? + if (empty($headers)) + return null; + // structure might be cached if (!empty($headers->structure)) return $headers; @@ -2320,9 +2324,14 @@ class rcube_imap // decode filename if (!empty($filename_mime)) { - $part->filename = rcube_imap::decode_mime_string($filename_mime, - $part->charset ? $part->charset : ($this->struct_charset ? $this->struct_charset : - rc_detect_encoding($filename_mime, $this->default_charset))); + if (!empty($part->charset)) + $charset = $part->charset; + else if (!empty($this->struct_charset)) + $charset = $this->struct_charset; + else + $charset = rc_detect_encoding($filename_mime, $this->default_charset); + + $part->filename = rcube_imap::decode_mime_string($filename_mime, $charset); } else if (!empty($filename_encoded)) { // decode filename according to RFC 2231, Section 4 @@ -2330,6 +2339,7 @@ class rcube_imap $filename_charset = $fmatches[1]; $filename_encoded = $fmatches[2]; } + $part->filename = rcube_charset_convert(urldecode($filename_encoded), $filename_charset); } } @@ -2366,25 +2376,23 @@ class rcube_imap */ function &get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL, $skip_charset_conv=false) { - // get part encoding if not provided + // get part data if not provided if (!is_object($o_part)) { $structure = $this->conn->getStructure($this->mailbox, $uid, true); + $part_data = rcube_imap_generic::getStructurePartData($structure, $part); $o_part = new rcube_message_part; - $o_part->ctype_primary = strtolower(rcube_imap_generic::getStructurePartType($structure, $part)); - $o_part->encoding = strtolower(rcube_imap_generic::getStructurePartEncoding($structure, $part)); - $o_part->charset = rcube_imap_generic::getStructurePartCharset($structure, $part); + $o_part->ctype_primary = $part_data['type']; + $o_part->encoding = $part_data['encoding']; + $o_part->charset = $part_data['charset']; + $o_part->size = $part_data['size']; } - // TODO: Add caching for message parts - - if (!$part) { - $part = 'TEXT'; + if ($o_part && $o_part->size) { + $body = $this->conn->handlePartBody($this->mailbox, $uid, true, + $part ? $part : 'TEXT', $o_part->encoding, $print, $fp); } - $body = $this->conn->handlePartBody($this->mailbox, $uid, true, $part, - $o_part->encoding, $print, $fp); - if ($fp || $print) { return true; } @@ -2397,7 +2405,7 @@ class rcube_imap if (!$skip_charset_conv) { if (!$o_part->charset || strtoupper($o_part->charset) == 'US-ASCII') { // try to extract charset information from HTML meta tag (#1488125) - if ($o_part->ctype_secondary == 'html' && preg_match('/<meta[^>]+charset=([a-z0-9-]+)/i', $body, $m)) + if ($o_part->ctype_secondary == 'html' && preg_match('/<meta[^>]+charset=([a-z0-9-_]+)/i', $body, $m)) $o_part->charset = strtoupper($m[1]); else $o_part->charset = $this->default_charset; diff --git a/program/include/rcube_imap_cache.php b/program/include/rcube_imap_cache.php index b51bc6db9..ee4e92542 100644 --- a/program/include/rcube_imap_cache.php +++ b/program/include/rcube_imap_cache.php @@ -853,7 +853,7 @@ class rcube_imap_cache // @TODO: find better validity check for threaded index if ($is_thread) { // check messages number... - if ($mbox_data['EXISTS'] != @max(array_keys($index['depth']))) { + if (!$this->skip_deleted && $mbox_data['EXISTS'] != @max(array_keys($index['depth']))) { return false; } return true; diff --git a/program/include/rcube_imap_generic.php b/program/include/rcube_imap_generic.php index bcfaa812e..5c7a41c73 100644 --- a/program/include/rcube_imap_generic.php +++ b/program/include/rcube_imap_generic.php @@ -2393,8 +2393,10 @@ class rcube_imap_generic $len = strlen($line); $result = false; + if ($a[2] != 'FETCH') { + } // handle empty "* X FETCH ()" response - if ($line[$len-1] == ')' && $line[$len-2] != '(') { + else if ($line[$len-1] == ')' && $line[$len-2] != '(') { // one line response, get everything between first and last quotes if (substr($line, -4, 3) == 'NIL') { // NIL response @@ -3174,47 +3176,48 @@ class rcube_imap_generic return false; } - static function getStructurePartType($structure, $part) + /** + * Returns data of a message part according to specified structure. + * + * @param array $structure Message structure (getStructure() result) + * @param string $part Message part identifier + * + * @return array Part data as hash array (type, encoding, charset, size) + */ + static function getStructurePartData($structure, $part) { $part_a = self::getStructurePartArray($structure, $part); - if (!empty($part_a)) { - if (is_array($part_a[0])) - return 'multipart'; - else if ($part_a[0]) - return $part_a[0]; - } + $data = array(); - return 'other'; - } + if (empty($part_a)) { + return $data; + } - static function getStructurePartEncoding($structure, $part) - { - $part_a = self::getStructurePartArray($structure, $part); - if ($part_a) { - if (!is_array($part_a[0])) - return $part_a[5]; - } + // content-type + if (is_array($part_a[0])) { + $data['type'] = 'multipart'; + } + else { + $data['type'] = strtolower($part_a[0]); - return ''; - } + // encoding + $data['encoding'] = strtolower($part_a[5]); - static function getStructurePartCharset($structure, $part) - { - $part_a = self::getStructurePartArray($structure, $part); - if ($part_a) { - if (is_array($part_a[0])) - return ''; - else { - if (is_array($part_a[2])) { - $name = ''; - while (list($key, $val) = each($part_a[2])) - if (strcasecmp($val, 'charset') == 0) - return $part_a[2][$key+1]; - } - } - } + // charset + if (is_array($part_a[2])) { + while (list($key, $val) = each($part_a[2])) { + if (strcasecmp($val, 'charset') == 0) { + $data['charset'] = $part_a[2][$key+1]; + break; + } + } + } + } - return ''; + // size + $data['size'] = intval($part_a[6]); + + return $data; } static function getStructurePartArray($a, $part) @@ -3247,7 +3250,6 @@ class rcube_imap_generic } } - /** * Creates next command identifier (tag) * diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index 6ece17511..f9352a3df 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -559,7 +559,7 @@ function rcmail_wash_html($html, $p = array(), $cid_replaces) // special replacements (not properly handled by washtml class) $html_search = array( '/(<\/nobr>)(\s+)(<nobr>)/i', // space(s) between <NOBR> - '/<title[^>]*>.*<\/title>/i', // PHP bug #32547 workaround: remove title tag + '/<title[^>]*>[^<]*<\/title>/i', // PHP bug #32547 workaround: remove title tag '/^(\0\0\xFE\xFF|\xFF\xFE\0\0|\xFE\xFF|\xFF\xFE|\xEF\xBB\xBF)/', // byte-order mark (only outlook?) '/<html\s[^>]+>/i', // washtml/DOMDocument cannot handle xml namespaces ); @@ -590,16 +590,16 @@ function rcmail_wash_html($html, $p = array(), $cid_replaces) $html = preg_replace_callback('/(<[\/]*)([^\s>]+)/', 'rcmail_html_tag_callback', $html); // charset was converted to UTF-8 in rcube_imap::get_message_part(), - // -> change charset specification in HTML accordingly - $charset_pattern = '(<meta\s+[^>]*content=)[\'"]?(\w+\/\w+;\s*charset=)([a-z0-9-_]+[\'"]?)'; - if (preg_match("/$charset_pattern/Ui", $html)) { - $html = preg_replace("/$charset_pattern/i", '\\1"\\2'.RCMAIL_CHARSET.'"', $html); - } - else { - // add meta content-type to malformed messages, washtml cannot work without that - if (!preg_match('/<head[^>]*>(.*)<\/head>/Uims', $html)) - $html = '<head></head>'. $html; - $html = substr_replace($html, '<meta http-equiv="Content-Type" content="text/html; charset='.RCMAIL_CHARSET.'" />', intval(stripos($html, '<head>')+6), 0); + // change/add charset specification in HTML accordingly, + // washtml cannot work without that + $meta = '<meta http-equiv="Content-Type" content="text/html; charset='.RCMAIL_CHARSET.'" />'; + + // remove old meta tag and add the new one, making sure + // that it is placed in the head (#1488093) + $html = preg_replace('/<meta[^>]+charset=[a-z0-9-_]+[^>]*>/Ui', '', $html); + $html = preg_replace('/(<head[^>]*>)/Ui', '\\1'.$meta, $html, -1, $rcount); + if (!$rcount) { + $html = '<head>' . $meta . '</head>' . $html; } // turn relative into absolute urls diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc index cb8b91881..bb144d4cb 100644 --- a/program/steps/settings/func.inc +++ b/program/steps/settings/func.inc @@ -178,7 +178,7 @@ function rcmail_user_prefs($current=null) // show page size selection if (!isset($no_override['timezone'])) { $field_id = 'rcmfd_timezone'; - $select_timezone = new html_select(array('name' => '_timezone', 'id' => $field_id, 'onchange' => "document.getElementById('rcmfd_dst').disabled=this.selectedIndex==0")); + $select_timezone = new html_select(array('name' => '_timezone', 'id' => $field_id, 'onchange' => "$('#rcmfd_dst').attr('disabled', this.selectedIndex==0)")); $select_timezone->add(rcube_label('autodetect'), 'auto'); $select_timezone->add('(GMT -11:00) Midway Island, Samoa', '-11'); $select_timezone->add('(GMT -10:00) Hawaii', '-10'); |