Fix broken message/part bodies when FETCH response contains more untagged lines (#1488836)

pull/50/head
Aleksander Machniak 12 years ago
parent 876d31d594
commit 7eb7806b21

@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail CHANGELOG Roundcube Webmail
=========================== ===========================
- Fix broken message/part bodies when FETCH response contains more untagged lines (#1488836)
- Fix empty email on identities list after identity update (#1488834) - Fix empty email on identities list after identity update (#1488834)
- Add new identities_level: (4) one identity with possibility to edit only signature - Add new identities_level: (4) one identity with possibility to edit only signature
- Use Delivered-To header as a last resort for identity selection (#1488840) - Use Delivered-To header as a last resort for identity selection (#1488840)

@ -2412,6 +2412,7 @@ class rcube_imap_generic
// format request // format request
$key = $this->nextTag(); $key = $this->nextTag();
$request = $key . ($is_uid ? ' UID' : '') . " FETCH $id ($fetch_mode.PEEK[$part]$partial)"; $request = $key . ($is_uid ? ' UID' : '') . " FETCH $id ($fetch_mode.PEEK[$part]$partial)";
$result = false;
// send request // send request
if (!$this->putLine($request)) { if (!$this->putLine($request)) {
@ -2424,30 +2425,27 @@ class rcube_imap_generic
$mode = -1; $mode = -1;
} }
// receive reply line
do { do {
$line = rtrim($this->readLine(1024)); $line = trim($this->readLine(1024));
$a = explode(' ', $line);
} while (!($end = $this->startsWith($line, $key, true)) && $a[2] != 'FETCH');
$len = strlen($line);
$result = false;
if ($a[2] != 'FETCH') { if (!$line) {
break;
} }
// handle empty "* X FETCH ()" response
else if ($line[$len-1] == ')' && $line[$len-2] != '(') { if (!preg_match('/^\* ([0-9]+) FETCH (.*)$/', $line, $m)) {
// one line response, get everything between first and last quotes continue;
if (substr($line, -4, 3) == 'NIL') {
// NIL response
$result = '';
} else {
$from = strpos($line, '"') + 1;
$to = strrpos($line, '"');
$len = $to - $from;
$result = substr($line, $from, $len);
} }
$line = $m[2];
$last = substr($line, -1);
// handle one line response
if ($line[0] == '(' && $last == ')') {
// tokenize content inside brackets
$tokens = $this->tokenizeResponse(preg_replace('/(^\(|\$)/', '', $line));
$result = count($tokens) == 1 ? $tokens[0] : false;
if ($result !== false) {
if ($mode == 1) { if ($mode == 1) {
$result = base64_decode($result); $result = base64_decode($result);
} }
@ -2457,14 +2455,11 @@ class rcube_imap_generic
else if ($mode == 3) { else if ($mode == 3) {
$result = convert_uudecode($result); $result = convert_uudecode($result);
} }
}
} else if ($line[$len-1] == '}') { }
// multi-line request, find sizes of content and receive that many bytes // response with string literal
$from = strpos($line, '{') + 1; else if (preg_match('/\{([0-9]+)\}$/', $line, $m)) {
$to = strrpos($line, '}'); $bytes = (int) $m[1];
$len = $to - $from;
$sizeStr = substr($line, $from, $len);
$bytes = (int)$sizeStr;
$prev = ''; $prev = '';
while ($bytes > 0) { while ($bytes > 0) {
@ -2493,51 +2488,56 @@ class rcube_imap_generic
$prev = substr($line, $length); $prev = substr($line, $length);
$line = substr($line, 0, $length); $line = substr($line, 0, $length);
} }
else else {
$prev = ''; $prev = '';
}
$line = base64_decode($line); $line = base64_decode($line);
}
// QUOTED-PRINTABLE // QUOTED-PRINTABLE
} else if ($mode == 2) { else if ($mode == 2) {
$line = rtrim($line, "\t\r\0\x0B"); $line = rtrim($line, "\t\r\0\x0B");
$line = quoted_printable_decode($line); $line = quoted_printable_decode($line);
}
// UUENCODE // UUENCODE
} else if ($mode == 3) { else if ($mode == 3) {
$line = rtrim($line, "\t\r\n\0\x0B"); $line = rtrim($line, "\t\r\n\0\x0B");
if ($line == 'end' || preg_match('/^begin\s+[0-7]+\s+.+$/', $line)) if ($line == 'end' || preg_match('/^begin\s+[0-7]+\s+.+$/', $line)) {
continue; continue;
}
$line = convert_uudecode($line); $line = convert_uudecode($line);
}
// default // default
} else if ($formatted) { else if ($formatted) {
$line = rtrim($line, "\t\r\n\0\x0B") . "\n"; $line = rtrim($line, "\t\r\n\0\x0B") . "\n";
} }
if ($file) { if ($file) {
if (fwrite($file, $line) === false) if (fwrite($file, $line) === false) {
break; break;
} }
else if ($print) }
else if ($print) {
echo $line; echo $line;
else }
else {
$result .= $line; $result .= $line;
} }
} }
}
// read in anything up until last line
if (!$end)
do {
$line = $this->readLine(1024);
} while (!$this->startsWith($line, $key, true)); } while (!$this->startsWith($line, $key, true));
if ($result !== false) { if ($result !== false) {
if ($file) { if ($file) {
return fwrite($file, $result); return fwrite($file, $result);
} else if ($print) { }
else if ($print) {
echo $result; echo $result;
} else
return $result;
return true; return true;
} }
return $result;
}
return false; return false;
} }

Loading…
Cancel
Save