diff options
Diffstat (limited to 'program/lib/Roundcube/rcube_utils.php')
-rw-r--r-- | program/lib/Roundcube/rcube_utils.php | 173 |
1 files changed, 42 insertions, 131 deletions
diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php index 27a618d83..4dadbb8bd 100644 --- a/program/lib/Roundcube/rcube_utils.php +++ b/program/lib/Roundcube/rcube_utils.php @@ -390,21 +390,20 @@ class rcube_utils * Convert array of request parameters (prefixed with _) * to a regular array with non-prefixed keys. * - * @param int $mode Source to get value from (GPC) - * @param string $ignore PCRE expression to skip parameters by name - * @param boolean $allow_html Allow HTML tags in field value + * @param int $mode Source to get value from (GPC) + * @param string $ignore PCRE expression to skip parameters by name * * @return array Hash array with all request parameters */ - public static function request2param($mode = null, $ignore = 'task|action', $allow_html = false) + public static function request2param($mode = null, $ignore = 'task|action') { $out = array(); $src = $mode == self::INPUT_GET ? $_GET : ($mode == self::INPUT_POST ? $_POST : $_REQUEST); - foreach (array_keys($src) as $key) { + foreach ($src as $key => $value) { $fname = $key[0] == '_' ? substr($key, 1) : $key; if ($ignore && !preg_match('/^(' . $ignore . ')$/', $fname)) { - $out[$fname] = self::get_input_value($key, $mode, $allow_html); + $out[$fname] = self::get_input_value($key, $mode); } } @@ -445,41 +444,34 @@ class rcube_utils $source = self::xss_entity_decode($source); $stripped = preg_replace('/[^a-z\(:;]/i', '', $source); $evilexpr = 'expression|behavior|javascript:|import[^a]' . (!$allow_remote ? '|url\(' : ''); - if (preg_match("/$evilexpr/i", $stripped)) { return '/* evil! */'; } - $strict_url_regexp = '!url\s*\([ "\'](https?:)//[a-z0-9/._+-]+["\' ]\)!Uims'; - // cut out all contents between { and } while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos))) { - $nested = strpos($source, '{', $pos+1); - if ($nested && $nested < $pos2) // when dealing with nested blocks (e.g. @media), take the inner one - $pos = $nested; - $length = $pos2 - $pos - 1; - $styles = substr($source, $pos+1, $length); + $styles = substr($source, $pos+1, $pos2-($pos+1)); // check every line of a style block... if ($allow_remote) { $a_styles = preg_split('/;[\r\n]*/', $styles, -1, PREG_SPLIT_NO_EMPTY); - foreach ($a_styles as $line) { $stripped = preg_replace('/[^a-z\(:;]/i', '', $line); // ... and only allow strict url() values - if (stripos($stripped, 'url(') && !preg_match($strict_url_regexp, $line)) { + $regexp = '!url\s*\([ "\'](https?:)//[a-z0-9/._+-]+["\' ]\)!Uims'; + if (stripos($stripped, 'url(') && !preg_match($regexp, $line)) { $a_styles = array('/* evil! */'); break; } } - $styles = join(";\n", $a_styles); } - $key = $replacements->add($styles); - $repl = $replacements->get_replacement($key); - $source = substr_replace($source, $repl, $pos+1, $length); - $last_pos = $pos2 - ($length - strlen($repl)); + $key = $replacements->add($styles); + $source = substr($source, 0, $pos+1) + . $replacements->get_replacement($key) + . substr($source, $pos2, strlen($source)-$pos2); + $last_pos = $pos+2; } // remove html comments and add #container to each tag selector. @@ -514,24 +506,17 @@ class rcube_utils */ public static function file2class($mimetype, $filename) { - $mimetype = strtolower($mimetype); - $filename = strtolower($filename); - list($primary, $secondary) = explode('/', $mimetype); $classes = array($primary ? $primary : 'unknown'); - if ($secondary) { $classes[] = $secondary; } - - if (preg_match('/\.([a-z0-9]+)$/', $filename, $m)) { - if (!in_array($m[1], $classes)) { - $classes[] = $m[1]; - } + if (preg_match('/\.([a-z0-9]+)$/i', $filename, $m)) { + $classes[] = $m[1]; } - return join(" ", $classes); + return strtolower(join(" ", $classes)); } @@ -674,21 +659,6 @@ class rcube_utils /** - * Returns the real remote IP address - * - * @return string Remote IP address - */ - public static function remote_addr() - { - foreach (array('HTTP_X_FORWARDED_FOR','HTTP_X_REAL_IP','REMOTE_ADDR') as $prop) { - if (!empty($_SERVER[$prop])) - return $_SERVER[$prop]; - } - - return ''; - } - - /** * Read a specific HTTP request header. * * @param string $name Header name @@ -747,88 +717,31 @@ class rcube_utils */ public static function strtotime($date) { - $date = self::clean_datestr($date); - - // unix timestamp - if (is_numeric($date)) { - return (int) $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); - } - - return (int) $ts; - } - - /** - * Date parsing function that turns the given value into a DateTime object - * - * @param string $date Date string - * - * @return object DateTime instance or false on failure - */ - public static function anytodatetime($date) - { - if (is_object($date) && is_a($date, 'DateTime')) { - return $date; - } - - $dt = false; - $date = self::clean_datestr($date); + $date = trim($date); - // try to parse string with DateTime first - if (!empty($date)) { - try { - $dt = new DateTime($date); - } - catch (Exception $e) { - // ignore - } + // check for MS Outlook vCard date format YYYYMMDD + if (preg_match('/^([12][90]\d\d)([01]\d)([0123]\d)$/', $date, $m)) { + return mktime(0,0,0, intval($m[2]), intval($m[3]), intval($m[1])); } - // try our advanced strtotime() method - if (!$dt && ($timestamp = self::strtotime($date))) { - try { - $dt = new DateTime("@".$timestamp); - } - catch (Exception $e) { - // ignore - } + // common little-endian formats, e.g. dd/mm/yyyy (not all are supported by strtotime) + if (preg_match('/^(\d{1,2})[.\/-](\d{1,2})[.\/-](\d{4})$/', $date, $m) + && $m[1] > 0 && $m[1] <= 31 && $m[2] > 0 && $m[2] <= 12 && $m[3] >= 1970 + ) { + return mktime(0,0,0, intval($m[2]), intval($m[1]), intval($m[3])); } - return $dt; - } - - /** - * Clean up date string for strtotime() input - * - * @param string $date Date string - * - * @return string Date string - */ - public static function clean_datestr($date) - { - $date = trim($date); - - // check for MS Outlook vCard date format YYYYMMDD - if (preg_match('/^([12][90]\d\d)([01]\d)([0123]\d)$/', $date, $m)) { - return sprintf('%04d-%02d-%02d 00:00:00', intval($m[1]), intval($m[2]), intval($m[3])); + // unix timestamp + if (is_numeric($date)) { + return (int) $date; } // Clean malformed data $date = preg_replace( array( - '/GMT\s*([+-][0-9]+)/', // support non-standard "GMTXXXX" literal - '/[^a-z0-9\x20\x09:+-\/]/i', // remove any invalid characters - '/\s*(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*/i', // remove weekday names + '/GMT\s*([+-][0-9]+)/', // support non-standard "GMTXXXX" literal + '/[^a-z0-9\x20\x09:+-]/i', // remove any invalid characters + '/\s*(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*/i', // remove weekday names ), array( '\\1', @@ -836,23 +749,21 @@ class rcube_utils '', ), $date); - $date = trim($date); - - // try to fix dd/mm vs. mm/dd discrepancy, we can't do more here - if (preg_match('/^(\d{1,2})[.\/-](\d{1,2})[.\/-](\d{4})$/', $date, $m)) { - $mdy = $m[2] > 12 && $m[1] <= 12; - $day = $mdy ? $m[2] : $m[1]; - $month = $mdy ? $m[1] : $m[2]; - $date = sprintf('%04d-%02d-%02d 00:00:00', intval($m[3]), $month, $day); - } - // I've found that YYYY.MM.DD is recognized wrong, so here's a fix - else if (preg_match('/^(\d{4})\.(\d{1,2})\.(\d{1,2})$/', $date)) { - $date = str_replace('.', '-', $date) . ' 00:00:00'; + // 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); } - return $date; + return (int) $ts; } + /* * Idn_to_ascii wrapper. * Intl/Idn modules version of this function doesn't work with e-mail address |