MDL-84179 tool_messageinbound: Upgrade Roundcube to version 1.6.10
This commit is contained in:
@@ -554,7 +554,7 @@ class rcube_charset
|
||||
}
|
||||
|
||||
// No match, check for UTF-8
|
||||
// from http://w3.org/International/questions/qa-forms-utf-8.html
|
||||
// from https://w3.org/International/questions/qa-forms-utf-8.html
|
||||
if (preg_match('/\A(
|
||||
[\x09\x0A\x0D\x20-\x7E]
|
||||
| [\xC2-\xDF][\x80-\xBF]
|
||||
|
||||
@@ -676,7 +676,7 @@ class rcube_imap_generic
|
||||
$gssapicontext->acquireCredentials($ccache);
|
||||
|
||||
$token = '';
|
||||
$success = $gssapicontext->initSecContext($this->prefs['gssapi_context'], null, null, null, $token);
|
||||
$success = $gssapicontext->initSecContext($this->prefs['gssapi_context'], '', 0, 0, $token);
|
||||
$token = base64_encode($token);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
@@ -1054,8 +1054,8 @@ class rcube_imap_generic
|
||||
}
|
||||
|
||||
if (!empty($this->prefs['socket_options'])) {
|
||||
$options = array_intersect_key($this->prefs['socket_options'], ['ssl' => 1]);
|
||||
$context = stream_context_create($options);
|
||||
$options = array_intersect_key($this->prefs['socket_options'], ['ssl' => 1, 'socket' => 1]);
|
||||
$context = stream_context_create($options);
|
||||
$this->fp = stream_socket_client($host . ':' . $port, $errno, $errstr,
|
||||
$this->prefs['timeout'], STREAM_CLIENT_CONNECT, $context);
|
||||
}
|
||||
@@ -2520,6 +2520,7 @@ class rcube_imap_generic
|
||||
$result[$id]->id = $id;
|
||||
$result[$id]->subject = '';
|
||||
$result[$id]->messageID = 'mid:' . $id;
|
||||
$result[$id]->folder = $mailbox;
|
||||
|
||||
$headers = null;
|
||||
$line = substr($line, strlen($m[0]) + 2);
|
||||
@@ -2551,6 +2552,21 @@ class rcube_imap_generic
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($name == 'ANNOTATION') {
|
||||
$result[$id]->annotations = [];
|
||||
if (!empty($value) && is_array($value)) {
|
||||
$n = 0;
|
||||
while (!empty($value[$n]) && is_string($value[$n])) {
|
||||
$name = $value[$n++];
|
||||
$list = $value[$n++];
|
||||
$result[$id]->annotations[$name] = [];
|
||||
$c = 0;
|
||||
while (!empty($list[$c]) && is_string($list[$c])) {
|
||||
$result[$id]->annotations[$name][$list[$c++]] = $list[$c++];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($name == 'MODSEQ') {
|
||||
$result[$id]->modseq = $value[0];
|
||||
}
|
||||
@@ -2686,14 +2702,15 @@ class rcube_imap_generic
|
||||
* @param mixed $message_set Message(s) sequence identifier(s) or UID(s)
|
||||
* @param bool $is_uid True if $message_set contains UIDs
|
||||
* @param bool $bodystr Enable to add BODYSTRUCTURE data to the result
|
||||
* @param array $add_headers List of additional headers
|
||||
* @param array $add_headers List of additional headers to fetch
|
||||
* @param array $query_items List of additional items to fetch
|
||||
*
|
||||
* @return bool|array List of rcube_message_header elements, False on error
|
||||
*/
|
||||
public function fetchHeaders($mailbox, $message_set, $is_uid = false, $bodystr = false, $add_headers = [])
|
||||
public function fetchHeaders($mailbox, $message_set, $is_uid = false, $bodystr = false, $add_headers = [], $query_items = [])
|
||||
{
|
||||
$query_items = ['UID', 'RFC822.SIZE', 'FLAGS', 'INTERNALDATE'];
|
||||
$headers = ['DATE', 'FROM', 'TO', 'SUBJECT', 'CONTENT-TYPE', 'CC', 'REPLY-TO',
|
||||
$query_items = array_unique(array_merge($query_items, ['UID', 'RFC822.SIZE', 'FLAGS', 'INTERNALDATE']));
|
||||
$headers = ['DATE', 'FROM', 'TO', 'SUBJECT', 'CONTENT-TYPE', 'CC', 'REPLY-TO',
|
||||
'LIST-POST', 'DISPOSITION-NOTIFICATION-TO', 'X-PRIORITY'];
|
||||
|
||||
if (!empty($add_headers)) {
|
||||
@@ -2718,12 +2735,13 @@ class rcube_imap_generic
|
||||
* @param bool $is_uid True if $id is an UID
|
||||
* @param bool $bodystr Enable to add BODYSTRUCTURE data to the result
|
||||
* @param array $add_headers List of additional headers
|
||||
* @param array $query_items List of additional items to fetch
|
||||
*
|
||||
* @return bool|rcube_message_header Message data, False on error
|
||||
*/
|
||||
public function fetchHeader($mailbox, $id, $is_uid = false, $bodystr = false, $add_headers = [])
|
||||
public function fetchHeader($mailbox, $id, $is_uid = false, $bodystr = false, $add_headers = [], $query_items = [])
|
||||
{
|
||||
$a = $this->fetchHeaders($mailbox, $id, $is_uid, $bodystr, $add_headers);
|
||||
$a = $this->fetchHeaders($mailbox, $id, $is_uid, $bodystr, $add_headers, $query_items);
|
||||
|
||||
if (is_array($a)) {
|
||||
return array_shift($a);
|
||||
@@ -2955,7 +2973,7 @@ class rcube_imap_generic
|
||||
}
|
||||
|
||||
if ($result !== false) {
|
||||
$result = $this->decodeContent($result, $mode, true);
|
||||
$result = $this->decodeContent($result, $mode, true, $prev, $formatted);
|
||||
}
|
||||
}
|
||||
// response with string literal
|
||||
@@ -2988,7 +3006,7 @@ class rcube_imap_generic
|
||||
}
|
||||
$bytes -= $len;
|
||||
|
||||
$chunk = $this->decodeContent($chunk, $mode, $bytes <= 0, $prev);
|
||||
$chunk = $this->decodeContent($chunk, $mode, $bytes <= 0, $prev, $formatted);
|
||||
|
||||
if ($file) {
|
||||
if (fwrite($file, $chunk) === false) {
|
||||
@@ -3024,14 +3042,15 @@ class rcube_imap_generic
|
||||
/**
|
||||
* Decodes a chunk of a message part content from a FETCH response.
|
||||
*
|
||||
* @param string $chunk Content
|
||||
* @param int $mode Encoding mode
|
||||
* @param bool $is_last Whether it is a last chunk of data
|
||||
* @param string $prev Extra content from the previous chunk
|
||||
* @param string $chunk Content
|
||||
* @param int $mode Encoding mode
|
||||
* @param bool $is_last Whether it is a last chunk of data
|
||||
* @param string $prev Extra content from the previous chunk
|
||||
* @param bool $formatted Format the content for output
|
||||
*
|
||||
* @return string Encoded string
|
||||
*/
|
||||
protected static function decodeContent($chunk, $mode, $is_last = false, &$prev = '')
|
||||
protected static function decodeContent($chunk, $mode, $is_last = false, &$prev = '', $formatted = false)
|
||||
{
|
||||
// BASE64
|
||||
if ($mode == 1) {
|
||||
@@ -3049,22 +3068,25 @@ class rcube_imap_generic
|
||||
$prev = '';
|
||||
}
|
||||
|
||||
return base64_decode($chunk);
|
||||
}
|
||||
// There might be multiple base64 blocks in a single message part,
|
||||
// we have to pass them separately to base64_decode() (#9290)
|
||||
$result = '';
|
||||
foreach (preg_split('|=+|', $chunk, -1, \PREG_SPLIT_NO_EMPTY) as $_chunk) {
|
||||
$result .= base64_decode($_chunk);
|
||||
}
|
||||
|
||||
$chunk = $result;
|
||||
}
|
||||
// QUOTED-PRINTABLE
|
||||
if ($mode == 2) {
|
||||
elseif ($mode == 2) {
|
||||
if (!self::decodeContentChunk($chunk, $prev, $is_last)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$chunk = preg_replace('/[\t\r\0\x0B]+\n/', "\n", $chunk);
|
||||
|
||||
return quoted_printable_decode($chunk);
|
||||
$chunk = quoted_printable_decode($chunk);
|
||||
}
|
||||
|
||||
// X-UUENCODE
|
||||
if ($mode == 3) {
|
||||
elseif ($mode == 3) {
|
||||
if (!self::decodeContentChunk($chunk, $prev, $is_last)) {
|
||||
return '';
|
||||
}
|
||||
@@ -3079,12 +3101,11 @@ class rcube_imap_generic
|
||||
return '';
|
||||
}
|
||||
|
||||
return convert_uudecode($chunk);
|
||||
$chunk = convert_uudecode($chunk);
|
||||
}
|
||||
|
||||
// Plain text formatted
|
||||
// TODO: Formatting should be handled outside of this class
|
||||
if ($mode == 4) {
|
||||
elseif ($mode == 4) {
|
||||
if (!self::decodeContentChunk($chunk, $prev, $is_last)) {
|
||||
return '';
|
||||
}
|
||||
@@ -3092,8 +3113,10 @@ class rcube_imap_generic
|
||||
if ($is_last) {
|
||||
$chunk = rtrim($chunk, "\t\r\n\0\x0B");
|
||||
}
|
||||
}
|
||||
|
||||
return preg_replace('/[\t\r\0\x0B]+\n/', "\n", $chunk);
|
||||
if ($formatted) {
|
||||
$chunk = preg_replace('/[\t\r\0\x0B]+\n/', "\n", $chunk);
|
||||
}
|
||||
|
||||
return $chunk;
|
||||
@@ -3744,6 +3767,60 @@ class rcube_imap_generic
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the STORE X ANNOTATION command (RFC5257)
|
||||
*
|
||||
* @param string $mailbox Mailbox name
|
||||
* @param array $entries
|
||||
*
|
||||
* @return bool True on success, False on failure
|
||||
*
|
||||
* @since 1.6.10
|
||||
*/
|
||||
public function storeMessageAnnotation($mailbox, $uids, $entries)
|
||||
{
|
||||
if (!$this->hasCapability('ANNOTATE-EXPERIMENT-1')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (empty($entries) || empty($uids)) {
|
||||
$this->setError(self::ERROR_COMMAND, 'Wrong argument for STORE ANNOTATION command');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->select($mailbox)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Example input compatible with rcube_message_header::$annotations:
|
||||
$entries = [
|
||||
'/comment' => [
|
||||
'value.priv' => 'test1',
|
||||
'value.shared' => null,
|
||||
],
|
||||
];
|
||||
*/
|
||||
|
||||
$request = [];
|
||||
foreach ($entries as $name => $annotation) {
|
||||
if (!empty($annotation)) {
|
||||
foreach ($annotation as $key => $value) {
|
||||
$annotation[$key] = $this->escape($key) . ' ' . $this->escape($value, true);
|
||||
}
|
||||
$request[] = $this->escape($name);
|
||||
$request[] = $annotation;
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->execute(
|
||||
'UID STORE',
|
||||
[$this->compressMessageSet($uids), 'ANNOTATION', $request],
|
||||
self::COMMAND_NORESPONSE
|
||||
);
|
||||
|
||||
return $result == self::ERROR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns BODYSTRUCTURE for the specified message.
|
||||
*
|
||||
|
||||
@@ -208,6 +208,13 @@ class rcube_message_header
|
||||
*/
|
||||
public $flags = [];
|
||||
|
||||
/**
|
||||
* Message annotations (RFC 5257)
|
||||
*
|
||||
* @var ?array
|
||||
*/
|
||||
public $annotations;
|
||||
|
||||
/**
|
||||
* Extra flags (for the messages list)
|
||||
*
|
||||
|
||||
@@ -735,8 +735,8 @@ class rcube_mime
|
||||
*
|
||||
* @return string
|
||||
* @author Till Klampaeckel <[email protected]>
|
||||
* @see http://de2.php.net/manual/en/ref.fileinfo.php
|
||||
* @see http://de2.php.net/mime_content_type
|
||||
* @see https://www.php.net/manual/en/ref.fileinfo.php
|
||||
* @see https://www.php.net/mime_content_type
|
||||
*/
|
||||
public static function file_content_type($path, $name, $failover = 'application/octet-stream', $is_stream = false, $skip_suffix = false)
|
||||
{
|
||||
|
||||
@@ -375,7 +375,7 @@ class rcube_result_thread
|
||||
$regexp = '(' . $element . '|' . $item . ')';
|
||||
|
||||
if (isset($this->meta['pos'][$index])) {
|
||||
if (preg_match('/([0-9]+)/', $this->raw_data, $m, null, $this->meta['pos'][$index])) {
|
||||
if (preg_match('/([0-9]+)/', $this->raw_data, $m, 0, $this->meta['pos'][$index])) {
|
||||
$result = $m[1];
|
||||
}
|
||||
}
|
||||
@@ -587,8 +587,8 @@ class rcube_result_thread
|
||||
protected function parse_thread($str, $begin = 0, $end = 0, $depth = 0)
|
||||
{
|
||||
// Don't be tempted to change $str to pass by reference to speed this up - it will slow it down by about
|
||||
// 7 times instead :-) See comments on http://uk2.php.net/references and this article:
|
||||
// http://derickrethans.nl/files/phparch-php-variables-article.pdf
|
||||
// 7 times instead :-) See comments on https://www.php.net/references and this article:
|
||||
// https://derickrethans.nl/files/phparch-php-variables-article.pdf
|
||||
$node = '';
|
||||
if (!$end) {
|
||||
$end = strlen($str);
|
||||
|
||||
@@ -416,23 +416,41 @@ class rcube_utils
|
||||
*/
|
||||
public static function mod_css_styles($source, $container_id, $allow_remote = false, $prefix = '')
|
||||
{
|
||||
$last_pos = 0;
|
||||
$replacements = new rcube_string_replacer;
|
||||
|
||||
// ignore the whole block if evil styles are detected
|
||||
$source = self::xss_entity_decode($source);
|
||||
$stripped = preg_replace('/[^a-z\(:;]/i', '', $source);
|
||||
$evilexpr = 'expression|behavior|javascript:|import[^a]' . (!$allow_remote ? '|url\((?!data:image)' : '');
|
||||
|
||||
if (preg_match("/$evilexpr/i", $stripped)) {
|
||||
// No @import allowed
|
||||
// TODO: We should just remove it, not invalidate the whole content
|
||||
if (stripos($source, '@import') !== false) {
|
||||
return '/* evil! */';
|
||||
}
|
||||
|
||||
$strict_url_regexp = '!url\s*\(\s*["\']?(https?:)//[a-z0-9/._+-]+["\']?\s*\)!Uims';
|
||||
// Incomplete style expression
|
||||
if (strpos($source, '{') === false) {
|
||||
return '/* invalid! */';
|
||||
}
|
||||
|
||||
// To prevent from a double-escaping tricks we consider a script with
|
||||
// any escape sequences (after de-escaping them above) an evil script.
|
||||
// This probably catches many valid scripts, but we\'re on the safe side.
|
||||
if (preg_match('/\\\[0-9a-fA-F]{2}/', $source)) {
|
||||
return '/* evil! */';
|
||||
}
|
||||
|
||||
// remove html comments
|
||||
$source = preg_replace('/(^\s*<\!--)|(-->\s*$)/m', '', $source);
|
||||
|
||||
$url_callback = static function ($url) use ($allow_remote) {
|
||||
if (strpos($url, 'data:image') === 0) {
|
||||
return $url;
|
||||
}
|
||||
if ($allow_remote && preg_match('|^https?://[a-z0-9/._+-]+$|i', $url)) {
|
||||
return $url;
|
||||
}
|
||||
};
|
||||
|
||||
$last_pos = 0;
|
||||
$replacements = new rcube_string_replacer();
|
||||
|
||||
// cut out all contents between { and }
|
||||
while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos))) {
|
||||
$nested = strpos($source, '{', $pos+1);
|
||||
@@ -441,36 +459,9 @@ class rcube_utils
|
||||
}
|
||||
$length = $pos2 - $pos - 1;
|
||||
$styles = substr($source, $pos+1, $length);
|
||||
$output = '';
|
||||
$styles = self::sanitize_css_block($styles, $url_callback);
|
||||
|
||||
// check every css rule in the style block...
|
||||
foreach (self::parse_css_block($styles) as $rule) {
|
||||
// Remove 'page' attributes (#7604)
|
||||
if ($rule[0] == 'page') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Convert position:fixed to position:absolute (#5264)
|
||||
if ($rule[0] == 'position' && strcasecmp($rule[1], 'fixed') === 0) {
|
||||
$rule[1] = 'absolute';
|
||||
}
|
||||
else if ($allow_remote) {
|
||||
$stripped = preg_replace('/[^a-z\(:;]/i', '', $rule[1]);
|
||||
|
||||
// allow data:image and strict url() values only
|
||||
if (
|
||||
stripos($stripped, 'url(') !== false
|
||||
&& stripos($stripped, 'url(data:image') === false
|
||||
&& !preg_match($strict_url_regexp, $rule[1])
|
||||
) {
|
||||
$rule[1] = '/* evil! */';
|
||||
}
|
||||
}
|
||||
|
||||
$output .= sprintf(" %s: %s;", $rule[0] , $rule[1]);
|
||||
}
|
||||
|
||||
$key = $replacements->add($output . ' ');
|
||||
$key = $replacements->add(strlen($styles) ? " {$styles} " : '');
|
||||
$repl = $replacements->get_replacement($key);
|
||||
$source = substr_replace($source, $repl, $pos+1, $length);
|
||||
$last_pos = $pos2 - ($length - strlen($repl));
|
||||
@@ -518,6 +509,63 @@ class rcube_utils
|
||||
return $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse and sanitize single CSS block
|
||||
*
|
||||
* @param string $styles CSS styles block
|
||||
* @param ?callable $url_callback URL validator callback
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function sanitize_css_block($styles, $url_callback = null)
|
||||
{
|
||||
$output = [];
|
||||
|
||||
// check every css rule in the style block...
|
||||
foreach (self::parse_css_block($styles) as $rule) {
|
||||
$property = $rule[0];
|
||||
$value = $rule[1];
|
||||
|
||||
if ($property == 'page') {
|
||||
// Remove 'page' attributes (#7604)
|
||||
continue;
|
||||
} elseif ($property == 'position' && strcasecmp($value, 'fixed') === 0) {
|
||||
// Convert position:fixed to position:absolute (#5264)
|
||||
$value = 'absolute';
|
||||
} elseif (preg_match('/expression|image-set/i', $value)) {
|
||||
continue;
|
||||
} else {
|
||||
$value = '';
|
||||
foreach (self::explode_css_property_block($rule[1]) as $val) {
|
||||
if ($url_callback && preg_match('/^url\s*\(/i', $val)) {
|
||||
if (preg_match('/^url\s*\(\s*[\'"]?([^\'"\)]*)[\'"]?\s*\)/iu', $val, $match)) {
|
||||
if ($url = $url_callback($match[1])) {
|
||||
$value .= ' url(' . $url . ')';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// whitelist ?
|
||||
$value .= ' ' . $val;
|
||||
|
||||
// #1488535: Fix size units, so width:800 would be changed to width:800px
|
||||
if ($val
|
||||
&& preg_match('/^(left|right|top|bottom|width|height)/i', $property)
|
||||
&& preg_match('/^[0-9]+$/', $val)
|
||||
) {
|
||||
$value .= 'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen($value)) {
|
||||
$output[] = $property . ': ' . trim($value);
|
||||
}
|
||||
}
|
||||
|
||||
return count($output) > 0 ? implode('; ', $output) . ';' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Explode css style. Property names will be lower-cased and trimmed.
|
||||
* Values will be trimmed. Invalid entries will be skipped.
|
||||
@@ -590,6 +638,41 @@ class rcube_utils
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Explode css style value
|
||||
*
|
||||
* @param string $style CSS style
|
||||
*
|
||||
* @return array List of CSS values
|
||||
*/
|
||||
public static function explode_css_property_block($style)
|
||||
{
|
||||
$style = preg_replace('/\s+/', ' ', $style);
|
||||
$result = [];
|
||||
$strlen = strlen($style);
|
||||
$q = false;
|
||||
|
||||
// explode value
|
||||
for ($p = $i = 0; $i < $strlen; $i++) {
|
||||
if (($style[$i] == '"' || $style[$i] == "'") && ($i == 0 || $style[$i - 1] != '\\')) {
|
||||
if ($q == $style[$i]) {
|
||||
$q = false;
|
||||
} elseif (!$q) {
|
||||
$q = $style[$i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!$q && $style[$i] == ' ' && ($i == 0 || !preg_match('/[,\(]/', $style[$i - 1]))) {
|
||||
$result[] = substr($style, $p, $i - $p);
|
||||
$p = $i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
$result[] = (string) substr($style, $p);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate CSS classes from mimetype and filename extension
|
||||
*
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
Description of Roundcube Framework 1.6.6 library import into Moodle
|
||||
Description of Roundcube Framework library import into Moodle
|
||||
|
||||
We now use the client part of Roundcube Framework as a library in Moodle.
|
||||
This library is used to receive emails from Moodle.
|
||||
This library is not used to send emails.
|
||||
|
||||
For more information on this version of Roundcube Framework, check out https://github.com/roundcube/roundcubemail/releases/tag/1.6.6
|
||||
For more information on this version of Roundcube Framework, check out https://github.com/roundcube/roundcubemail/releases/tag/X.Y.Z
|
||||
|
||||
To upgrade this library:
|
||||
1. Download the latest release of Roundcube Framework (roundcube-framework-xxx-tar.gz) in https://github.com/roundcube/roundcubemail/releases.
|
||||
1. Download the latest release of Roundcube Framework (roundcube-framework-xyz-tar.gz) in https://github.com/roundcube/roundcubemail/releases.
|
||||
2. Extract the contents of the release archive to a temp folder.
|
||||
3. Copy the following files from the temp folder to the Moodle folder admin/tool/messageinbound/roundcube:
|
||||
- rcube_charset.php
|
||||
@@ -17,8 +17,29 @@ To upgrade this library:
|
||||
- rcube_result_index.php
|
||||
- rcube_result_thread.php
|
||||
- rcube_utils.php
|
||||
4. Find and replace all array_first() calls with array_shift() in the following files:
|
||||
|
||||
To ease the process, you can execute the below command:
|
||||
```
|
||||
cp rcube_charset.php \
|
||||
rcube_imap_generic.php \
|
||||
rcube_message_header.php \
|
||||
rcube_mime.php \
|
||||
rcube_result_index.php \
|
||||
rcube_result_thread.php \
|
||||
rcube_utils.php \
|
||||
/path/to/moodle/admin/tool/messageinbound/roundcube/
|
||||
```
|
||||
4. Enter to the /path/to/moodle/admin/tool/messageinbound/roundcube/.
|
||||
5. Find and replace all array_first() calls with array_shift() in the following files:
|
||||
- rcube_imap_generic.php
|
||||
- rcube_result_index.php
|
||||
- rcube_result_thread.php
|
||||
5. Update admin/tool/messageinbound/thirdpartylibs.xml.
|
||||
|
||||
To ease the process, you can execute the below command:
|
||||
```
|
||||
sed -i 's/array_first(/array_shift(/g' \
|
||||
rcube_imap_generic.php \
|
||||
rcube_result_index.php \
|
||||
rcube_result_thread.php
|
||||
```
|
||||
6. Update admin/tool/messageinbound/thirdpartylibs.xml versions.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<name>Roundcube Framework</name>
|
||||
<license>GPL</license>
|
||||
<licenseversion>3.0+</licenseversion>
|
||||
<version>1.6.6</version>
|
||||
<version>1.6.10</version>
|
||||
<repository>https://github.com/roundcube/roundcubemail</repository>
|
||||
<copyrights>
|
||||
<copyright>The Roundcube Dev Team</copyright>
|
||||
|
||||
Reference in New Issue
Block a user