From 1a00f138c6d6903d7fc51dca4ef46dd675aec9fa Mon Sep 17 00:00:00 2001 From: alecpl Date: Mon, 12 Oct 2009 16:06:33 +0000 Subject: - Fix IE issue with non-UTF-8 characters in AJAX response (#1486159) --- CHANGELOG | 1 + program/include/rcube_shared.inc | 67 +++++++++++++++++++++++++++++++++++++++- program/steps/mail/func.inc | 5 ++- program/steps/mail/headers.inc | 5 +++ 4 files changed, 76 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ce6e9f381..2a38745cd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ CHANGELOG RoundCube Webmail =========================== +- Fix IE issue with non-UTF-8 characters in AJAX response (#1486159) - Partially fixed "empty body" issue by showing raw body of malformed message (#1486166) - Fix importing/sending to email address with whitespace (#1486214) - Added XIMSS (CommuniGate) driver for Password plugin diff --git a/program/include/rcube_shared.inc b/program/include/rcube_shared.inc index 85a6105b0..d60291012 100644 --- a/program/include/rcube_shared.inc +++ b/program/include/rcube_shared.inc @@ -554,7 +554,6 @@ function rc_mime_content_type($path, $name, $failover = 'application/octet-strea return $mime_type; } - /** * A method to guess encoding of a string. * @@ -585,6 +584,72 @@ function rc_detect_encoding($string, $failover='') return $result ? $result : $failover; } +/** + * Removes non-unicode characters from input + * + * @param mixed $input String or array. + * @return string + */ +function rc_utf8_clean($input) +{ + // handle input of type array + if (is_array($input)) { + foreach ($input as $idx => $val) + $input[$idx] = rc_utf8_clean($val); + return $input; + } + + if (!is_string($input)) + return $input; + + // iconv is 10x faster + if (function_exists('iconv')) + return iconv('UTF8', 'UTF8//IGNORE', $input); + + $regexp = '/^('. +// '[\x00-\x7F]'. // UTF8-1 + '|[\xC2-\xDF][\x80-\xBF]'. // UTF8-2 + '|\xE0[\xA0-\xBF][\x80-\xBF]'. // UTF8-3 + '|[\xE1-\xEC][\x80-\xBF][\x80-\xBF]'. // UTF8-3 + '|\xED[\x80-\x9F][\x80-\xBF]'. // UTF8-3 + '|[\xEE-\xEF][\x80-\xBF][\x80-\xBF]'. // UTF8-3 + '|\xF0[\x90-\xBF][\x80-\xBF][\x80-\xBF]'. // UTF8-4 + '|[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.// UTF8-4 + '|\xF4[\x80-\x8F][\x80-\xBF][\x80-\xBF]'. // UTF8-4 + ')$/'; + + $seq = ''; + $out = ''; + + for ($i = 0, $len = strlen($input)-1; $i < $len; $i++) { + $chr = $input[$i]; + $ord = ord($chr); + // 1-byte character + if ($ord <= 0x7F) { + if ($seq) + $out .= preg_match($regexp, $seq) ? $seq : ''; + $seq = ''; + $out .= $chr; + // first (or second) byte of multibyte sequence + } else if ($ord >= 0xC0) { + if (strlen($seq)>1) { + $out .= preg_match($regexp, $seq) ? $seq : ''; + $seq = ''; + } else if ($seq && ord($seq) < 0xC0) { + $seq = ''; + } + $seq .= $chr; + // next byte of multibyte sequence + } else if ($seq) { + $seq .= $chr; + } + } + + if ($seq) + $out .= preg_match($regexp, $seq) ? $seq : ''; + + return $out; +} /** * Explode quoted string diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index bca2f8cd1..0a8664cde 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -457,7 +457,10 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $replace=TRUE) $a_msg_flags['forwarded'] = 1; if ($header->flagged) $a_msg_flags['flagged'] = 1; - + + if ($browser->ie) + $a_msg_cols = rc_utf8_clean($a_msg_cols); + $OUTPUT->command('add_message_row', $header->uid, $a_msg_cols, diff --git a/program/steps/mail/headers.inc b/program/steps/mail/headers.inc index 653fb9647..4e3f969bd 100644 --- a/program/steps/mail/headers.inc +++ b/program/steps/mail/headers.inc @@ -24,6 +24,11 @@ if ($uid = get_input_value('_uid', RCUBE_INPUT_POST)) if ($source) { + $browser = new rcube_browser; + + if ($browser->ie) + $source = rc_utf8_clean($source); + $source = htmlspecialchars(trim($source)); $source = preg_replace('/\t/', '    ', $source); $source = preg_replace('/^([a-z0-9_:-]+)/im', ''.'\1'.'', $source); -- cgit v1.2.3