Thomas Bruederli
2012-11-17 6ddb16d181e285d4f0ef0ef55bdd0ba787f1b583
program/include/rcube_utils.php
@@ -18,16 +18,14 @@
 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
 | Author: Aleksander Machniak <alec@alec.pl>                            |
 +-----------------------------------------------------------------------+
 $Id$
*/
/**
 * Utility class providing common functions
 *
 * @package Core
 * @package    Framework
 * @subpackage Utils
 */
class rcube_utils
{
@@ -50,7 +48,7 @@
        }
        $cookie = session_get_cookie_params();
        $secure = self::https_check();
        $secure = $cookie['secure'] || self::https_check();
        setcookie($name, $value, $exp, $cookie['path'], $cookie['domain'], $secure, true);
    }
@@ -87,17 +85,17 @@
        // from PEAR::Validate
        $regexp = '&^(?:
           ("\s*(?:[^"\f\n\r\t\v\b\s]+\s*)+")|                          #1 quoted name
           ([-\w!\#\$%\&\'*+~/^`|{}=]+(?:\.[-\w!\#\$%\&\'*+~/^`|{}=]+)*))    #2 OR dot-atom (RFC5322)
           $&xi';
            ("\s*(?:[^"\f\n\r\t\v\b\s]+\s*)+")|                             #1 quoted name
            ([-\w!\#\$%\&\'*+~/^`|{}=]+(?:\.[-\w!\#\$%\&\'*+~/^`|{}=]+)*))  #2 OR dot-atom (RFC5322)
            $&xi';
        if (!preg_match($regexp, $local_part)) {
            return false;
        }
        // Check domain part
        if (preg_match('/^\[*(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\]*$/', $domain_part)) {
            return true; // IP address
        // Validate domain part
        if (preg_match('/^\[((IPv6:[0-9a-f:.]+)|([0-9.]+))\]$/i', $domain_part, $matches)) {
            return self::check_ip(preg_replace('/^IPv6:/i', '', $matches[1])); // valid IPv4 or IPv6 address
        }
        else {
            // If not an IP address
@@ -111,6 +109,11 @@
                if (!preg_match('/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]))$/', $part)) {
                    return false;
                }
            }
            // last domain part
            if (preg_match('/[^a-zA-Z]/', array_pop($domain_array))) {
                return false;
            }
            $rcube = rcube::get_instance();
@@ -144,6 +147,52 @@
        return false;
    }
    /**
     * Validates IPv4 or IPv6 address
     *
     * @param string $ip IP address in v4 or v6 format
     *
     * @return bool True if the address is valid
     */
    public static function check_ip($ip)
    {
        // IPv6, but there's no build-in IPv6 support
        if (strpos($ip, ':') !== false && !defined('AF_INET6')) {
            $parts = explode(':', $domain_part);
            $count = count($parts);
            if ($count > 8 || $count < 2) {
                return false;
            }
            foreach ($parts as $idx => $part) {
                $length = strlen($part);
                if (!$length) {
                    // there can be only one ::
                    if ($found_empty) {
                        return false;
                    }
                    $found_empty = true;
                }
                // last part can be an IPv4 address
                else if ($idx == $count - 1) {
                    if (!preg_match('/^[0-9a-f]{1,4}$/i', $part)) {
                        return @inet_pton($part) !== false;
                    }
                }
                else if (!preg_match('/^[0-9a-f]{1,4}$/i', $part)) {
                    return false;
                }
            }
            return true;
        }
        return @inet_pton($ip) !== false;
    }
    /**
     * Check whether the HTTP referer matches the current request
     *
@@ -152,8 +201,8 @@
    public static function check_referer()
    {
        $uri = parse_url($_SERVER['REQUEST_URI']);
        $referer = parse_url(rcube_request_header('Referer'));
        return $referer['host'] == rcube_request_header('Host') && $referer['path'] == $uri['path'];
        $referer = parse_url(self::request_header('Referer'));
        return $referer['host'] == self::request_header('Host') && $referer['path'] == $uri['path'];
    }
@@ -172,6 +221,10 @@
        static $html_encode_arr = false;
        static $js_rep_table = false;
        static $xml_rep_table = false;
        if (!is_string($str)) {
            $str = strval($str);
        }
        // encode for HTML output
        if ($enctype == 'html') {
@@ -197,9 +250,6 @@
            }
            $out = strtr($str, $encode_arr);
            // avoid douple quotation of &
            $out = preg_replace('/&amp;([A-Za-z]{2,6}|#[0-9]{2,4});/', '&\\1;', $out);
            return $newlines ? nl2br($out) : $out;
        }
@@ -619,8 +669,10 @@
    {
        // %n - host
        $n = preg_replace('/:\d+$/', '', $_SERVER['SERVER_NAME']);
        // %d - domain name without first part, e.g. %n=mail.domain.tld, %d=domain.tld
        $d = preg_replace('/^[^\.]+\./', '', $n);
        // %t - host name without first part, e.g. %n=mail.domain.tld, %t=domain.tld
        $t = preg_replace('/^[^\.]+\./', '', $n);
        // %d - domain name without first part
        $d = preg_replace('/^[^\.]+\./', '', $_SERVER['HTTP_HOST']);
        // %h - IMAP host
        $h = $_SESSION['storage_host'] ? $_SESSION['storage_host'] : $host;
        // %z - IMAP domain without first part, e.g. %h=imap.domain.tld, %z=domain.tld
@@ -628,14 +680,14 @@
        // %s - domain name after the '@' from e-mail address provided at login screen. Returns FALSE if an invalid email is provided
        if (strpos($name, '%s') !== false) {
            $user_email = self::get_input_value('_user', self::INPUT_POST);
            $user_email = rcube_utils::idn_convert($user_email, true);
            $user_email = self::idn_convert($user_email, true);
            $matches    = preg_match('/(.*)@([a-z0-9\.\-\[\]\:]+)/i', $user_email, $s);
            if ($matches < 1 || filter_var($s[1]."@".$s[2], FILTER_VALIDATE_EMAIL) === false) {
                return false;
            }
        }
        $name = str_replace(array('%n', '%d', '%h', '%z', '%s'), array($n, $d, $h, $z, $s[2]), $name);
        $name = str_replace(array('%n', '%t', '%d', '%h', '%z', '%s'), array($n, $t, $d, $h, $z, $s[2]), $name);
        return $name;
    }
@@ -710,7 +762,7 @@
            }
        }
        $result[] = substr($string, $p);
        $result[] = (string) substr($string, $p);
        return $result;
    }