- Fix message structure parsing when it lacks optional fields (#1486881)

release-0.6
alecpl 15 years ago
parent e6ce0062f2
commit 95fd49e4f2

@ -1,6 +1,7 @@
CHANGELOG RoundCube Webmail CHANGELOG RoundCube Webmail
=========================== ===========================
- Fix message structure parsing when it lacks optional fields (#1486881)
- Include all recipients in sendmail log - Include all recipients in sendmail log
- Support HTTP_X_FORWARDED_PROTO header for HTTPS detecting (#1486866) - Support HTTP_X_FORWARDED_PROTO header for HTTPS detecting (#1486866)
- Fix default IMAP port configuration (#1486864) - Fix default IMAP port configuration (#1486864)

@ -1747,6 +1747,18 @@ class rcube_imap
if (is_array($part[0])) { if (is_array($part[0])) {
$struct->ctype_primary = 'multipart'; $struct->ctype_primary = 'multipart';
/* RFC3501: BODYSTRUCTURE fields of multipart part
part1 array
part2 array
part3 array
....
1. subtype
2. parameters (optional)
3. description (optional)
4. language (optional)
5. location (optional)
*/
// find first non-array entry // find first non-array entry
for ($i=1; $i<count($part); $i++) { for ($i=1; $i<count($part); $i++) {
if (!is_array($part[$i])) { if (!is_array($part[$i])) {
@ -1758,8 +1770,9 @@ class rcube_imap
$struct->mimetype = 'multipart/'.$struct->ctype_secondary; $struct->mimetype = 'multipart/'.$struct->ctype_secondary;
// build parts list for headers pre-fetching // build parts list for headers pre-fetching
for ($i=0, $count=0; $i<count($part); $i++) { for ($i=0; $i<count($part); $i++) {
if (is_array($part[$i]) && count($part[$i]) > 4) { if (!is_array($part[$i]))
break;
// fetch message headers if message/rfc822 // fetch message headers if message/rfc822
// or named part (could contain Content-Location header) // or named part (could contain Content-Location header)
if (!is_array($part[$i][0])) { if (!is_array($part[$i][0])) {
@ -1773,7 +1786,6 @@ class rcube_imap
} }
} }
} }
}
// pre-fetch headers of all parts (in one command for better performance) // pre-fetch headers of all parts (in one command for better performance)
// @TODO: we could do this before _structure_part() call, to fetch // @TODO: we could do this before _structure_part() call, to fetch
@ -1787,18 +1799,40 @@ class rcube_imap
$raw_part_headers = $this->conn->fetchMIMEHeaders($this->mailbox, $raw_part_headers = $this->conn->fetchMIMEHeaders($this->mailbox,
$this->_msg_id, $raw_part_headers, false); $this->_msg_id, $raw_part_headers, false);
} }
$struct->parts = array(); $struct->parts = array();
for ($i=0, $count=0; $i<count($part); $i++) { for ($i=0, $count=0; $i<count($part); $i++) {
if (is_array($part[$i]) && count($part[$i]) > 4) { if (!is_array($part[$i]))
break;
$tmp_part_id = $struct->mime_id ? $struct->mime_id.'.'.($i+1) : $i+1; $tmp_part_id = $struct->mime_id ? $struct->mime_id.'.'.($i+1) : $i+1;
$struct->parts[] = $this->_structure_part($part[$i], ++$count, $struct->mime_id, $struct->parts[] = $this->_structure_part($part[$i], ++$count, $struct->mime_id,
$mime_part_headers[$tmp_part_id], $raw_part_headers[$tmp_part_id]); $mime_part_headers[$tmp_part_id], $raw_part_headers[$tmp_part_id]);
} }
}
return $struct; return $struct;
} }
/* RFC3501: BODYSTRUCTURE fields of non-multipart part
0. type
1. subtype
2. parameters
3. id
4. description
5. encoding
6. size
-- text
7. lines
-- message/rfc822
7. envelope structure
8. body structure
9. lines
--
x. md5 (optional)
x. disposition (optional)
x. language (optional)
x. location (optional)
*/
// regular part // regular part
$struct->ctype_primary = strtolower($part[0]); $struct->ctype_primary = strtolower($part[0]);
$struct->ctype_secondary = strtolower($part[1]); $struct->ctype_secondary = strtolower($part[1]);
@ -1825,9 +1859,11 @@ class rcube_imap
$struct->size = intval($part[6]); $struct->size = intval($part[6]);
// read part disposition // read part disposition
$di = count($part) - 2; $di = 8;
if ((is_array($part[$di]) && count($part[$di]) == 2 && is_array($part[$di][1])) || if ($struct->ctype_primary == 'text') $di += 1;
(is_array($part[--$di]) && count($part[$di]) == 2)) { else if ($struct->mimetype == 'message/rfc822') $di += 3;
if (is_array($part[$di]) && count($part[$di]) == 2) {
$struct->disposition = strtolower($part[$di][0]); $struct->disposition = strtolower($part[$di][0]);
if (is_array($part[$di][1])) if (is_array($part[$di][1]))
@ -1835,13 +1871,15 @@ class rcube_imap
$struct->d_parameters[strtolower($part[$di][1][$n])] = $part[$di][1][$n+1]; $struct->d_parameters[strtolower($part[$di][1][$n])] = $part[$di][1][$n+1];
} }
// get child parts // get message/rfc822's child-parts
if (is_array($part[8]) && $di != 8) { if (is_array($part[8]) && $di != 8) {
$struct->parts = array(); $struct->parts = array();
for ($i=0, $count=0; $i<count($part[8]); $i++) for ($i=0, $count=0; $i<count($part[8]); $i++) {
if (is_array($part[8][$i]) && count($part[8][$i]) > 5) if (!is_array($part[8][$i]))
break;
$struct->parts[] = $this->_structure_part($part[8][$i], ++$count, $struct->mime_id); $struct->parts[] = $this->_structure_part($part[8][$i], ++$count, $struct->mime_id);
} }
}
// get part ID // get part ID
if (!empty($part[3]) && $part[3]!='NIL') { if (!empty($part[3]) && $part[3]!='NIL') {

Loading…
Cancel
Save