Fix infinite loop in rcube_utils::mod_css_styles() after recent changes in rcube_string_replacer

pull/136/head
Aleksander Machniak 11 years ago
parent b5216621ba
commit d1abd8e339

@ -24,7 +24,7 @@
*/
class rcube_string_replacer
{
public static $pattern = '/##str_replacement\{([0-9]+)\}##/';
public static $pattern = '/##str_replacement_(\d+)##/';
public $mailto_pattern;
public $link_pattern;
public $linkref_index;
@ -50,7 +50,7 @@ class rcube_string_replacer
."@$utf_domain" // domain-part
."(\?[$url1$url2]+)?" // e.g. ?subject=test...
.")/";
$this->linkref_index = '/\[([^\]#]+)\](:?\s*##str_replacement\{(\d+)\}##)/';
$this->linkref_index = '/\[([^\]#]+)\](:?\s*##str_replacement_(\d+)##)/';
$this->linkref_pattern = '/\[([^\]#]+)\]/';
$this->options = $options;
@ -74,7 +74,7 @@ class rcube_string_replacer
*/
public function get_replacement($i)
{
return '##str_replacement{'.$i.'}##';
return '##str_replacement_' . $i . '##';
}
/**

@ -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.

Loading…
Cancel
Save