Skip to content

Commit

Permalink
Support many string literals in a "line response", deduplicate code
Browse files Browse the repository at this point in the history
  • Loading branch information
alecpl committed Mar 20, 2020
1 parent f9c84e2 commit 2965e60
Showing 1 changed file with 32 additions and 38 deletions.
70 changes: 32 additions & 38 deletions program/lib/Roundcube/rcube_imap_generic.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,36 @@ protected function readLine($size = 1024)
return $line;
}

/**
* Reads a line of data from the connection stream inluding all
* string continuation literals.
*
* @param int $size Buffer size
*
* @return string Line of text response
*/
protected function readFullLine($size = 1024)
{
$line = $this->readLine($size);

// include all string literels untile the real end of "line"
while (preg_match('/\{([0-9]+)\}\r\n$/', $line, $m)) {
$bytes = $m[1] + 2;
$out = '';

while (strlen($out) < $bytes) {
$out = $this->readBytes($bytes);
if ($out === null) {
break;
}

$line .= $out;
}
}

return $line;
}

/**
* Reads more data from the connection stream when provided
* data contain string literal
Expand Down Expand Up @@ -2398,7 +2428,7 @@ public function fetch($mailbox, $message_set, $is_uid = false, $query_items = ar
}

do {
$line = $this->readLine(4096);
$line = $this->readFullLine(4096);

if (!$line) {
break;
Expand All @@ -2422,27 +2452,6 @@ public function fetch($mailbox, $message_set, $is_uid = false, $query_items = ar
$line = substr($line, strlen($m[0]) + 2);
$ln = 0;

// get complete entry
while (preg_match('/\{([0-9]+)\}\r\n$/', $line, $m)) {
$bytes = $m[1];
$out = '';

while (strlen($out) < $bytes) {
$out = $this->readBytes($bytes);
if ($out === null) {
break;
}
$line .= $out;
}

$str = $this->readLine(4096);
if ($str === false) {
break;
}

$line .= $str;
}

// Tokenize response and assign to object properties
while (list($name, $value) = $this->tokenizeResponse($line, 2)) {
if ($name == 'UID') {
Expand Down Expand Up @@ -3722,24 +3731,9 @@ public function execute($command, $arguments = array(), $options = 0, $filter =

// Parse response
do {
$line = $this->readLine(4096);
$line = $this->readFullLine(4096);

if ($response !== null) {
// In filter mode we need additional code for string literals.
// We'll merge the following literal data into one chunk, so
// it can be compared with the filter below
if ($filter && preg_match('/\{([0-9]+)\}\r\n$/', $line, $match)) {
// read and append the given bytes
$bytes = $match[1];
$out = '';
while (strlen($out) < $bytes) {
$tmp = $this->readBytes($bytes);
if ($tmp === null) break;
$out .= $tmp;
}
$line .= $out;
}

if (!$filter || preg_match($filter, $line)) {
$response .= $line;
}
Expand Down

0 comments on commit 2965e60

Please sign in to comment.