summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--program/include/rcube_imap.php42
-rw-r--r--program/include/rcube_imap_cache.php2
-rw-r--r--program/include/rcube_imap_generic.php74
-rw-r--r--program/steps/mail/func.inc22
-rw-r--r--program/steps/settings/func.inc2
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');