Aleksander Machniak
2015-04-03 5a4f3f8266999674baeccfba0df8f911372b55a7
program/lib/Roundcube/rcube_imap_generic.php
@@ -1,6 +1,6 @@
<?php
/**
/*
 +-----------------------------------------------------------------------+
 | This file is part of the Roundcube Webmail client                     |
 | Copyright (C) 2005-2012, The Roundcube Dev Team                       |
@@ -47,8 +47,6 @@
        'MDNSENT'  => '$MDNSent',
        '*'        => '\\*',
    );
    public static $mupdate;
    protected $fp;
    protected $host;
@@ -1108,7 +1106,8 @@
            // folder name with spaces. Let's try to handle this situation
            if (!is_array($items) && ($pos = strpos($response, '(')) !== false) {
                $response = substr($response, $pos);
                $items = $this->tokenizeResponse($response, 1);
                $items    = $this->tokenizeResponse($response, 1);
                if (!is_array($items)) {
                    return $result;
                }
@@ -1704,7 +1703,6 @@
        $encoding  = $encoding ? trim($encoding) : 'US-ASCII';
        $algorithm = $algorithm ? trim($algorithm) : 'REFERENCES';
        $criteria  = $criteria ? 'ALL '.trim($criteria) : 'ALL';
        $data      = '';
        list($code, $response) = $this->execute($return_uid ? 'UID THREAD' : 'THREAD',
            array($algorithm, $encoding, $criteria));
@@ -2041,8 +2039,14 @@
            $flag = $this->flags[strtoupper($flag)];
        }
        if (!$flag || (!in_array($flag, (array) $this->data['PERMANENTFLAGS'])
            && !in_array('\\*', (array) $this->data['PERMANENTFLAGS']))
        if (!$flag) {
            return false;
        }
        // if PERMANENTFLAGS is not specified all flags are allowed
        if (!empty($this->data['PERMANENTFLAGS'])
            && !in_array($flag, (array) $this->data['PERMANENTFLAGS'])
            && !in_array('\\*', (array) $this->data['PERMANENTFLAGS'])
        ) {
            return false;
        }
@@ -2563,50 +2567,61 @@
            return false;
        }
        switch ($encoding) {
        case 'base64':
            $mode = 1;
            break;
        case 'quoted-printable':
            $mode = 2;
            break;
        case 'x-uuencode':
        case 'x-uue':
        case 'uue':
        case 'uuencode':
            $mode = 3;
            break;
        default:
            $mode = 0;
        }
        // Use BINARY extension when possible (and safe)
        $binary     = $mode && preg_match('/^[0-9.]+$/', $part) && $this->hasCapability('BINARY');
        $fetch_mode = $binary ? 'BINARY' : 'BODY';
        $partial    = $max_bytes ? sprintf('<0.%d>', $max_bytes) : '';
        // format request
        $key     = $this->nextTag();
        $request = $key . ($is_uid ? ' UID' : '') . " FETCH $id ($fetch_mode.PEEK[$part]$partial)";
        $result  = false;
        $found   = false;
        // send request
        if (!$this->putLine($request)) {
            $this->setError(self::ERROR_COMMAND, "Unable to send command: $request");
            return false;
        }
        if ($binary) {
            // WARNING: Use $formatted argument with care, this may break binary data stream
            $mode = -1;
        }
        $binary    = true;
        do {
            if (!$initiated) {
                switch ($encoding) {
                case 'base64':
                    $mode = 1;
                    break;
                case 'quoted-printable':
                    $mode = 2;
                    break;
                case 'x-uuencode':
                case 'x-uue':
                case 'uue':
                case 'uuencode':
                    $mode = 3;
                    break;
                default:
                    $mode = 0;
                }
                // Use BINARY extension when possible (and safe)
                $binary     = $binary && $mode && preg_match('/^[0-9.]+$/', $part) && $this->hasCapability('BINARY');
                $fetch_mode = $binary ? 'BINARY' : 'BODY';
                $partial    = $max_bytes ? sprintf('<0.%d>', $max_bytes) : '';
                // format request
                $key       = $this->nextTag();
                $request   = $key . ($is_uid ? ' UID' : '') . " FETCH $id ($fetch_mode.PEEK[$part]$partial)";
                $result    = false;
                $found     = false;
                $initiated = true;
                // send request
                if (!$this->putLine($request)) {
                    $this->setError(self::ERROR_COMMAND, "Unable to send command: $request");
                    return false;
                }
                if ($binary) {
                    // WARNING: Use $formatted argument with care, this may break binary data stream
                    $mode = -1;
                }
            }
            $line = trim($this->readLine(1024));
            if (!$line) {
                break;
            }
            // handle UNKNOWN-CTE response - RFC 3516, try again with standard BODY request
            if ($binary && !$found && preg_match('/^' . $key . ' NO \[UNKNOWN-CTE\]/i', $line)) {
                $binary = $initiated = false;
                continue;
            }
            // skip irrelevant untagged responses (we have a result already)
@@ -2669,7 +2684,7 @@
                    // BASE64
                    if ($mode == 1) {
                        $line = rtrim($line, "\t\r\n\0\x0B");
                        $line = preg_replace('|[^a-zA-Z0-9+=/]|', '', $line);
                        // create chunks with proper length for base64 decoding
                        $line = $prev.$line;
                        $length = strlen($line);
@@ -2714,7 +2729,7 @@
                    }
                }
            }
        } while (!$this->startsWith($line, $key, true));
        } while (!$this->startsWith($line, $key, true) || !$initiated);
        if ($result !== false) {
            if ($file) {
@@ -3254,11 +3269,6 @@
        }
        foreach ($data as $entry) {
            // Workaround cyrus-murder bug, the entry[2] string needs to be escaped
            if (self::$mupdate) {
                $entry[2] = addcslashes($entry[2], '\\"');
            }
            // ANNOTATEMORE drafts before version 08 require quoted parameters
            $entries[] = sprintf('%s (%s %s)', $this->escape($entry[0], true),
                $this->escape($entry[1], true), $this->escape($entry[2], true));
@@ -3821,10 +3831,6 @@
        if (!isset($this->prefs['literal+']) && in_array('LITERAL+', $this->capability)) {
            $this->prefs['literal+'] = true;
        }
        if (preg_match('/(\[| )MUPDATE=.*/', $str)) {
            self::$mupdate = true;
        }
        if ($trusted) {