summaryrefslogtreecommitdiff
path: root/program/lib/Roundcube/rcube_utils.php
diff options
context:
space:
mode:
authorAleksander Machniak <alec@alec.pl>2013-10-12 12:28:40 +0200
committerAleksander Machniak <alec@alec.pl>2013-10-12 12:28:40 +0200
commitd1abd8e339a1346b02ebbca5365cd824adf5f897 (patch)
treeeb35fd54930cbccaa6d392c1169240f913f25773 /program/lib/Roundcube/rcube_utils.php
parentb5216621ba79599157ac868c7f9b935a54e39b57 (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.php18
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.