Changeset 2252 in subversion
- Timestamp:
- Jan 22, 2009 9:47:23 AM (4 years ago)
- Location:
- trunk/roundcubemail
- Files:
-
- 1 added
- 4 edited
-
CHANGELOG (modified) (1 diff)
-
program/include/main.inc (modified) (4 diffs)
-
program/include/rcube_shared.inc (modified) (1 diff)
-
program/include/rcube_string_replacer.php (added)
-
program/steps/mail/func.inc (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/roundcubemail/CHANGELOG
r2245 r2252 1 1 CHANGELOG RoundCube Webmail 2 2 --------------------------- 3 4 2009/01/22 (thomasb) 5 ---------- 6 - Get rid of preg_replace() with eval modifier and create_function usage (#1485686) 7 - Bring back <base> and <link> tags in HTML messages 3 8 4 9 2009/01/20 (thomasb) -
trunk/roundcubemail/program/include/main.inc
r2237 r2252 588 588 * @return string Modified CSS source 589 589 */ 590 function rcmail_mod_css_styles($source, $container_id, $base_url = '') 591 { 592 $a_css_values = array(); 590 function rcmail_mod_css_styles($source, $container_id) 591 { 593 592 $last_pos = 0; 593 $replacements = new rcube_string_replacer; 594 594 595 595 // ignore the whole block if evil styles are detected 596 596 $stripped = preg_replace('/[^a-z\(:]/', '', rcmail_xss_entitiy_decode($source)); 597 597 if (preg_match('/expression|behavior|url\(|import/', $stripped)) 598 return ' ';598 return '/* evil! */'; 599 599 600 600 // cut out all contents between { and } 601 601 while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos))) 602 602 { 603 $key = sizeof($a_css_values); 604 $a_css_values[$key] = substr($source, $pos+1, $pos2-($pos+1)); 605 $source = substr($source, 0, $pos+1) . "<<str_replacement[$key]>>" . substr($source, $pos2, strlen($source)-$pos2); 603 $key = $replacements->add(substr($source, $pos+1, $pos2-($pos+1))); 604 $source = substr($source, 0, $pos+1) . $replacements->get_replacement($key) . substr($source, $pos2, strlen($source)-$pos2); 606 605 $last_pos = $pos+2; 607 606 } 608 607 609 608 // remove html comments and add #container to each tag selector. 610 609 // also replace body definition because we also stripped off the <body> tag … … 622 621 $source); 623 622 624 // replace all @import statements to modify the imported CSS sources too625 $styles = preg_replace_callback(626 '/@import\s+(url\()?[\'"]?([^\)\'"]+)[\'"]?(\))?/im',627 create_function('$matches', "return sprintf(\"@import url('./bin/modcss.php?u=%s&c=%s')\", urlencode(make_absolute_url(\$matches[2],'$base_url')), urlencode('$container_id'));"),628 $styles);629 630 623 // put block contents back in 631 $styles = preg_replace_callback( 632 '/<<str_replacement\[([0-9]+)\]>>/', 633 create_function('$matches', "\$values = ".var_export($a_css_values, true)."; return \$values[\$matches[1]];"), 634 $styles); 624 $styles = $replacements->resolve($styles); 635 625 636 626 return $styles; … … 648 638 { 649 639 $out = html_entity_decode(html_entity_decode($content)); 650 $out = preg_replace_callback('/\\\([0-9a-f]{4})/i', create_function('$matches', 'return chr(hexdec($matches[1]));'), $out);640 $out = preg_replace_callback('/\\\([0-9a-f]{4})/i', 'rcmail_xss_entitiy_decode_callback', $out); 651 641 $out = preg_replace('#/\*.*\*/#Um', '', $out); 652 642 return $out; 653 643 } 654 644 645 646 /** 647 * preg_replace_callback callback for rcmail_xss_entitiy_decode_callback 648 * 649 * @param array matches result from preg_replace_callback 650 * @return string decoded entity 651 */ 652 function rcmail_xss_entitiy_decode_callback($matches) 653 { 654 return chr(hexdec($matches[1])); 655 } 655 656 656 657 /** … … 1210 1211 } 1211 1212 1213 1214 1215 /** 1216 * Helper class to turn relative urls into absolute ones 1217 * using a predefined base 1218 */ 1219 class rcube_base_replacer 1220 { 1221 private $base_url; 1222 1223 public function __construct($base) 1224 { 1225 $this->base_url = $base; 1226 } 1227 1228 public function callback($matches) 1229 { 1230 return $matches[1] . '="' . make_absolute_url($matches[3], $this->base_url) . '"'; 1231 } 1232 } 1233 1234 1212 1235 ?> -
trunk/roundcubemail/program/include/rcube_shared.inc
r2147 r2252 310 310 311 311 // cut base_url to the last directory 312 if (str pos($base_url, '/')>7)312 if (strrpos($base_url, '/')>7) 313 313 { 314 314 $host_url = substr($base_url, 0, strpos($base_url, '/')); -
trunk/roundcubemail/program/steps/mail/func.inc
r2237 r2252 672 672 $html = substr_replace($html, '<meta http-equiv="content-type" content="text/html; charset='.RCMAIL_CHARSET.'" />', intval(stripos($html, '<head>')+6), 0); 673 673 } 674 675 // turn relative into absolute urls 676 $html = rcmail_resolve_base($html); 674 677 675 678 // clean HTML with washhtml by Frederic Motte … … 686 689 $wash_opts['html_elements'] = array('html','head','title','body'); 687 690 } 691 if ($p['safe']) { 692 $wash_opts['html_elements'][] = 'link'; 693 } 688 694 689 695 $washer = new washtml($wash_opts); … … 711 717 712 718 // make links and email-addresses clickable 713 $ convert_patterns = $convert_replaces = $replace_strings = array();719 $replacements = new rcube_string_replacer; 714 720 715 721 $url_chars = 'a-z0-9_\-\+\*\$\/&%=@#:;'; 716 722 $url_chars_within = '\?\.~,!'; 717 718 $convert_patterns[] = "/([\w]+):\/\/([a-z0-9\-\.]+[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/ie";719 $convert_replaces[] = "rcmail_str_replacement('<a href=\"\\1://\\2\" target=\"_blank\">\\1://\\2</a>', \$replace_strings)";720 721 $convert_patterns[] = "/([^\/:]|\s)(www\.)([a-z0-9\-]{2,}[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/ie";722 $convert_replaces[] = "rcmail_str_replacement('\\1<a href=\"http://\\2\\3\" target=\"_blank\">\\2\\3</a>', \$replace_strings)";723 724 $convert_patterns[] = '/([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9]\\.[a-z]{2,5})/ie';725 $convert_replaces[] = "rcmail_str_replacement('<a href=\"mailto:\\1\" onclick=\"return ".JS_OBJECT_NAME.".command(\'compose\',\'\\1\',this)\">\\1</a>', \$replace_strings)";726 723 727 724 // search for patterns like links and e-mail addresses 728 $body = preg_replace($convert_patterns, $convert_replaces, $body); 725 $body = preg_replace_callback("/([\w]+):\/\/([a-z0-9\-\.]+[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/i", array($replacements, 'link_callback'), $body); 726 $body = preg_replace_callback("/([^\/:]|\s)(www\.)([a-z0-9\-]{2,}[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/i", array($replacements, 'link_callback'), $body); 727 $body = preg_replace_callback('/([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9]\\.[a-z]{2,5})/i', array($replacements, 'mailto_callback'), $body); 729 728 730 729 // split body into single lines … … 755 754 756 755 // insert the links for urls and mailtos 757 $body = preg_replace("/##string_replacement\{([0-9]+)\}##/e", "\$replace_strings[\\1]",join("\n", $a_lines));756 $body = $replacements->resolve(join("\n", $a_lines)); 758 757 759 758 return html::tag('pre', array(), $body); … … 957 956 958 957 958 /** 959 * Convert all relative URLs according to a <base> in HTML 960 */ 961 function rcmail_resolve_base($body) 962 { 963 // check for <base href=...> 964 if (preg_match('!(<base.*href=["\']?)([hftps]{3,5}://[a-z0-9/.%-]+)!i', $body, $regs)) { 965 $replacer = new rcube_base_replacer($regs[2]); 966 967 // replace all relative paths 968 $body = preg_replace_callback('/(src|background|href)=(["\']?)([\.\/]+[^"\'\s]+)(\2|\s|>)/Ui', array($replacer, 'callback'), $body); 969 $body = preg_replace_callback('/(url\s*\()(["\']?)([\.\/]+[^"\'\)\s]+)(\2)\)/Ui', array($replacer, 'callback'), $body); 970 } 971 972 return $body; 973 } 959 974 960 975 /** … … 963 978 function rcmail_html4inline($body, $container_id) 964 979 { 965 $base_url = "";966 980 $last_style_pos = 0; 967 981 $body_lc = strtolower($body); 968 969 // check for <base href>970 if (preg_match(($base_reg = '/(<base.*href=["\']?)([hftps]{3,5}:\/{2}[^"\'\s]+)([^<]*>)/i'), $body, $base_regs))971 $base_url = $base_regs[2];972 982 973 983 // find STYLE tags … … 977 987 978 988 // replace all css definitions with #container [def] 979 $styles = rcmail_mod_css_styles(substr($body, $pos, $pos2-$pos), $container_id , $base_url);989 $styles = rcmail_mod_css_styles(substr($body, $pos, $pos2-$pos), $container_id); 980 990 981 991 $body = substr($body, 0, $pos) . $styles . substr($body, $pos2); … … 984 994 } 985 995 986 // resolve <base href>987 if ($base_url)988 {989 $body = preg_replace('/(src|background|href)=(["\']?)([\.\/]+[^"\'\s]+)(\2|\s|>)/Uie', "'\\1=\"'.make_absolute_url('\\3', '$base_url').'\"'", $body);990 $body = preg_replace('/(url\s*\()(["\']?)([\.\/]+[^"\'\)\s]+)(\2)\)/Uie', "'\\1\''.make_absolute_url('\\3', '$base_url').'\')'", $body);991 $body = preg_replace($base_reg, '', $body);992 }993 994 996 // modify HTML links to open a new window if clicked 995 997 $body = preg_replace('/<(a|link)\s+([^>]+)>/Uie', "rcmail_alter_html_link('\\1','\\2', '$container_id');", $body);
Note: See TracChangeset
for help on using the changeset viewer.
