alecpl
2011-02-04 e18d992ee1a37bf76e2ef5a0d136df8fe591a914
program/include/rcube_imap_generic.php
@@ -5,7 +5,7 @@
 | program/include/rcube_imap_generic.php                                |
 |                                                                       |
 | This file is part of the Roundcube Webmail client                     |
 | Copyright (C) 2005-2010, Roundcube Dev. - Switzerland                 |
 | Copyright (C) 2005-2010, The Roundcube Dev Team                       |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 | PURPOSE:                                                              |
@@ -371,10 +371,43 @@
        return false;
    }
    function getCapability($name)
    private function hasCapability($name)
    {
        if (empty($this->capability) || $name == '') {
            return false;
        }
        if (in_array($name, $this->capability)) {
            return true;
        }
        else if (strpos($name, '=')) {
            return false;
        }
        $result = array();
        foreach ($this->capability as $cap) {
            $entry = explode('=', $cap);
            if ($entry[0] == $name) {
                $result[] = $entry[1];
            }
        }
        return !empty($result) ? $result : false;
    }
    /**
     * Capabilities checker
     *
     * @param string $name Capability name
     *
     * @return mixed Capability values array for key=value pairs, true/false for others
     */
    function getCapability($name)
    {
        $result = $this->hasCapability($name);
        if (!empty($result)) {
            return $result;
        }
        else if ($this->capability_readed) {
            return false;
@@ -390,11 +423,7 @@
        $this->capability_readed = true;
        if (in_array($name, $this->capability)) {
            return true;
        }
        return false;
        return $this->hasCapability($name);
    }
    function clearCapability()
@@ -735,17 +764,17 @@
        // check for supported auth methods
        if ($auth_method == 'CHECK') {
            if ($this->getCapability('AUTH=DIGEST-MD5')) {
                $auth_methods[] = 'DIGEST-MD5';
            }
            if ($this->getCapability('AUTH=CRAM-MD5') || $this->getCapability('AUTH=CRAM_MD5')) {
                $auth_methods[] = 'CRAM-MD5';
            }
            if ($this->getCapability('AUTH=PLAIN')) {
                $auth_methods[] = 'PLAIN';
            if ($auth_caps = $this->getCapability('AUTH')) {
                $auth_methods = $auth_caps;
            }
            // RFC 2595 (LOGINDISABLED) LOGIN disabled when connection is not secure
            if (!$this->getCapability('LOGINDISABLED')) {
            $login_disabled = $this->getCapability('LOGINDISABLED');
            if (($key = array_search('LOGIN', $auth_methods)) !== false) {
                if ($login_disabled) {
                    unset($auth_methods[$key]);
                }
            }
            else if (!$login_disabled) {
                $auth_methods[] = 'LOGIN';
            }
        }
@@ -766,8 +795,10 @@
        // Authenticate
        foreach ($auth_methods as $method) {
            switch ($method) {
            case 'DIGEST-MD5':
            case 'CRAM_MD5':
                $method = 'CRAM-MD5';
            case 'CRAM-MD5':
            case 'DIGEST-MD5':
            case 'PLAIN':
                $result = $this->authenticate($user, $password, $method);
                break;
@@ -1463,7 +1494,7 @@
                // INTERNALDATE "16-Nov-2008 21:08:46 +0100" BODYSTRUCTURE (...)
                // BODY[HEADER.FIELDS ...
                if (preg_match('/^\* [0-9]+ FETCH \((.*) BODY/s', $line, $matches)) {
                if (preg_match('/^\* [0-9]+ FETCH \((.*) BODY/sU', $line, $matches)) {
                    $str = $matches[1];
                    // swap parents with quotes, then explode
@@ -1500,7 +1531,7 @@
                    // BODYSTRUCTURE
                    if ($bodystr) {
                        while (!preg_match('/ BODYSTRUCTURE (.*) BODY\[HEADER.FIELDS/s', $line, $m)) {
                        while (!preg_match('/ BODYSTRUCTURE (.*) BODY\[HEADER.FIELDS/sU', $line, $m)) {
                            $line2 = $this->readLine(1024);
                            $line .= $this->multLine($line2, true);
                        }
@@ -1600,7 +1631,7 @@
                        break;
                        case 'content-type':
                            $ctype_parts = preg_split('/[; ]/', $string);
                            $result[$id]->ctype = array_shift($ctype_parts);
                            $result[$id]->ctype = strtolower(array_shift($ctype_parts));
                            if (preg_match('/charset\s*=\s*"?([a-z0-9\-\.\_]+)"?/i', $string, $regs)) {
                                $result[$id]->charset = $regs[1];
                            }
@@ -2606,13 +2637,13 @@
     */
    function getACL($mailbox)
    {
        list($code, $response) = $this->execute('GETACL', $this->escape($mailbox));
        list($code, $response) = $this->execute('GETACL', array($this->escape($mailbox)));
        if ($code == self::ERROR_OK && preg_match('/^\* ACL /i', $response)) {
            // Parse server response (remove "* ACL ")
            $response = substr($response, 6);
            $ret  = $this->tokenizeResponse($response);
            $mbox = array_unshift($ret);
            $mbox = array_shift($ret);
            $size = count($ret);
            // Create user-rights hash array
@@ -2679,7 +2710,7 @@
     */
    function myRights($mailbox)
    {
        list($code, $response) = $this->execute('MYRIGHTS', array($this->escape(mailbox)));
        list($code, $response) = $this->execute('MYRIGHTS', array($this->escape($mailbox)));
        if ($code == self::ERROR_OK && preg_match('/^\* MYRIGHTS /i', $response)) {
            // Parse server response (remove "* MYRIGHTS ")
@@ -2881,8 +2912,9 @@
                $value = sprintf("{%d}\r\n%s", strlen($value), $value);
            }
            // ANNOTATEMORE drafts before version 08 require quoted parameters
            $entries[] = sprintf('%s (%s %s)',
                $this->escape($name), $this->escape($attr), $value);
                $this->escape($name, true), $this->escape($attr, true), $value);
        }
        $entries = implode(' ', $entries);
@@ -2932,8 +2964,9 @@
            $entries = array($entries);
        }
        // create entries string
        // ANNOTATEMORE drafts before version 08 require quoted parameters
        foreach ($entries as $idx => $name) {
            $entries[$idx] = $this->escape($name);
            $entries[$idx] = $this->escape($name, true);
        }
        $entries = '(' . implode(' ', $entries) . ')';
@@ -2942,7 +2975,7 @@
        }
        // create entries string
        foreach ($attribs as $idx => $name) {
            $attribs[$idx] = $this->escape($name);
            $attribs[$idx] = $this->escape($name, true);
        }
        $attribs = '(' . implode(' ', $attribs) . ')';
@@ -3190,21 +3223,7 @@
     */
    private function strToTime($date)
    {
        // support non-standard "GMTXXXX" literal
        $date = preg_replace('/GMT\s*([+-][0-9]+)/', '\\1', $date);
        // if date parsing fails, we have a date in non-rfc format.
        // remove token from the end and try again
        while ((($ts = @strtotime($date))===false) || ($ts < 0)) {
            $d = explode(' ', $date);
            array_pop($d);
            if (!$d) {
                break;
            }
            $date = implode(' ', $d);
        }
        $ts = (int) $ts;
        $ts = (int) rcube_strtotime($date);
        return $ts < 0 ? 0 : $ts;
    }
@@ -3237,12 +3256,13 @@
    /**
     * Escapes a string when it contains special characters (RFC3501)
     *
     * @param string $string IMAP string
     * @param string  $string       IMAP string
     * @param boolean $force_quotes Forces string quoting
     *
     * @return string Escaped string
     * @todo String literals, lists
     */
    static function escape($string)
    static function escape($string, $force_quotes=false)
    {
        if ($string === null) {
            return 'NIL';
@@ -3250,7 +3270,9 @@
        else if ($string === '') {
            return '""';
        }
        else if (preg_match('/([\x00-\x20\x28-\x29\x7B\x25\x2A\x22\x5C\x5D\x7F]+)/', $string)) {
        else if ($force_quotes ||
            preg_match('/([\x00-\x20\x28-\x29\x7B\x25\x2A\x22\x5C\x5D\x7F]+)/', $string)
        ) {
            // string: special chars: SP, CTL, (, ), {, %, *, ", \, ]
            return '"' . strtr($string, array('"'=>'\\"', '\\' => '\\\\')) . '"';
        }