Aleksander Machniak
2014-10-23 89984d01ba5c29bd5361759e40c39d2bb9878eb1
Fix handling of UNKNOWN-CTE response, try do decode content client-side (#1490046)
2 files modified
88 ■■■■■ changed files
CHANGELOG 1 ●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_imap_generic.php 87 ●●●●● patch | view | raw | blame | history
CHANGELOG
@@ -8,6 +8,7 @@
- Fix download of attachments that are part of TNEF message (#1490091)
- Fix handling of uuencoded messages if messages_cache is enabled (#1490108)
- Fix handling of base64-encoded attachments with extra spaces (#1490111)
- Fix handling of UNKNOWN-CTE response, try do decode content client-side (#1490046)
RELEASE 1.0.3
-------------
program/lib/Roundcube/rcube_imap_generic.php
@@ -2530,48 +2530,59 @@
            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;
        }
        $initiated = false;
        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_err && $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));
            // handle UNKNOWN-CTE response - RFC 3516, try standard BODY request instead of BINARY
            if ($binary && preg_match('/^' . $key . ' NO \[UNKNOWN-CTE\]/i', $line)) {
                $initiated = false;
                continue;
            }
            if (!$line) {
                break;
            }