diff options
author | Aleksander Machniak <alec@alec.pl> | 2013-10-12 12:28:40 +0200 |
---|---|---|
committer | Aleksander Machniak <alec@alec.pl> | 2013-10-12 12:28:40 +0200 |
commit | d1abd8e339a1346b02ebbca5365cd824adf5f897 (patch) | |
tree | eb35fd54930cbccaa6d392c1169240f913f25773 /program/lib/Roundcube/rcube_utils.php | |
parent | b5216621ba79599157ac868c7f9b935a54e39b57 (diff) |
Fix infinite loop in rcube_utils::mod_css_styles() after recent changes in rcube_string_replacer
Diffstat (limited to 'program/lib/Roundcube/rcube_utils.php')
-rw-r--r-- | program/lib/Roundcube/rcube_utils.php | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php index c1ad3823b..771602fa7 100644 --- a/program/lib/Roundcube/rcube_utils.php +++ b/program/lib/Roundcube/rcube_utils.php @@ -445,34 +445,38 @@ 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))) { $styles = substr($source, $pos+1, $pos2-($pos+1)); + $length = strlen($styles); // 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 - $regexp = '!url\s*\([ "\'](https?:)//[a-z0-9/._+-]+["\' ]\)!Uims'; - if (stripos($stripped, 'url(') && !preg_match($regexp, $line)) { + if (stripos($stripped, 'url(') && !preg_match($strict_url_regexp, $line)) { $a_styles = array('/* evil! */'); break; } } + $styles = join(";\n", $a_styles); } - $key = $replacements->add($styles); - $source = substr($source, 0, $pos+1) - . $replacements->get_replacement($key) - . substr($source, $pos2, strlen($source)-$pos2); - $last_pos = $pos+2; + $key = $replacements->add($styles); + $repl = $replacements->get_replacement($key); + $source = substr_replace($source, $repl, $pos+1, $length); + $last_pos = $pos2 - ($length - strlen($repl)); } // remove html comments and add #container to each tag selector. |