summaryrefslogtreecommitdiff
path: root/program
diff options
context:
space:
mode:
authorthomascube <thomas@roundcube.net>2007-09-29 18:15:05 +0000
committerthomascube <thomas@roundcube.net>2007-09-29 18:15:05 +0000
commit97bd2c0537bc3edb3751b3020f37e680944ac41c (patch)
tree3845f62069bbfc9ddb67447f07e504f0f455077a /program
parentca2b4ddfcc7a506925c9d5b3a798a4c74147c2e1 (diff)
Filter linked/imported CSS files (#1484056)
Diffstat (limited to 'program')
-rw-r--r--program/include/main.inc45
-rw-r--r--program/include/rcube_shared.inc4
-rw-r--r--program/steps/mail/func.inc74
3 files changed, 80 insertions, 43 deletions
diff --git a/program/include/main.inc b/program/include/main.inc
index 9809865d4..db0ee6c07 100644
--- a/program/include/main.inc
+++ b/program/include/main.inc
@@ -29,6 +29,7 @@
require_once('lib/des.inc');
require_once('lib/utf7.inc');
require_once('lib/utf8.class.php');
+require_once('include/rcube_shared.inc');
require_once('include/rcmail_template.inc');
@@ -1450,6 +1451,50 @@ function rcmail_mail_domain($host)
/**
+ * Replace all css definitions with #container [def]
+ *
+ * @param string CSS source code
+ * @param string Container ID to use as prefix
+ * @return string Modified CSS source
+ */
+function rcmail_mod_css_styles($source, $container_id, $base_url = '')
+ {
+ $a_css_values = array();
+ $last_pos = 0;
+
+ // cut out all contents between { and }
+ while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos)))
+ {
+ $key = sizeof($a_css_values);
+ $a_css_values[$key] = substr($source, $pos+1, $pos2-($pos+1));
+ $source = substr($source, 0, $pos+1) . "<<str_replacement[$key]>>" . substr($source, $pos2, strlen($source)-$pos2);
+ $last_pos = $pos+2;
+ }
+
+ // remove html commends and add #container to each tag selector.
+ // also replace body definition because we also stripped off the <body> tag
+ $styles = preg_replace(
+ array(
+ '/(^\s*<!--)|(-->\s*$)/',
+ '/(^\s*|,\s*|\}\s*)([a-z0-9\._#][a-z0-9\.\-_]*)/im',
+ '/@import\s+(url\()?[\'"]?([^\)\'"]+)[\'"]?(\))?/ime',
+ '/<<str_replacement\[([0-9]+)\]>>/e',
+ "/$container_id\s+body/i"
+ ),
+ array(
+ '',
+ "\\1#$container_id \\2",
+ "sprintf(\"@import url('./bin/modcss.php?u=%s&c=%s')\", urlencode(make_absolute_url('\\2','$base_url')), urlencode($container_id))",
+ "\$a_css_values[\\1]",
+ "$container_id div.rcmBody"
+ ),
+ $source);
+
+ return $styles;
+ }
+
+
+/**
* Compose a valid attribute string for HTML tags
*
* @param array Named tag attributes
diff --git a/program/include/rcube_shared.inc b/program/include/rcube_shared.inc
index a5a3ca64e..05fa7a2bc 100644
--- a/program/include/rcube_shared.inc
+++ b/program/include/rcube_shared.inc
@@ -434,6 +434,10 @@ function make_absolute_url($path, $base_url)
{
$host_url = $base_url;
$abs_path = $path;
+
+ // check if path is an absolute URL
+ if (preg_match('/^[fhtps]+:\/\//', $path))
+ return $path;
// cut base_url to the last directory
if (strpos($base_url, '/')>7)
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 0712ef8df..30d60e6da 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -946,16 +946,21 @@ function rcmail_sanitize_html($body, $container_id)
// remove any null-byte characters before parsing
$body = preg_replace('/\x00/', '', $body);
+ $base_url = "";
$last_style_pos = 0;
$body_lc = strtolower($body);
+ // check for <base href>
+ if (preg_match(($base_reg = '/(<base.*href=["\']?)([hftps]{3,5}:\/{2}[^"\'\s]+)([^<]*>)/i'), $body, $base_regs))
+ $base_url = $base_regs[2];
+
// find STYLE tags
while (($pos = strpos($body_lc, '<style', $last_style_pos)) && ($pos2 = strpos($body_lc, '</style>', $pos)))
{
$pos = strpos($body_lc, '>', $pos)+1;
// replace all css definitions with #container [def]
- $styles = rcmail_mod_css_styles(substr($body, $pos, $pos2-$pos), $container_id);
+ $styles = rcmail_mod_css_styles(substr($body, $pos, $pos2-$pos), $container_id, $base_url);
$body = substr($body, 0, $pos) . $styles . substr($body, $pos2);
$body_lc = strtolower($body);
@@ -983,17 +988,15 @@ function rcmail_sanitize_html($body, $container_id)
}
// resolve <base href>
- $base_reg = '/(<base.*href=["\']?)([hftps]{3,5}:\/{2}[^"\'\s]+)([^<]*>)/i';
- if (preg_match($base_reg, $body, $regs))
+ if ($base_url)
{
- $base_url = $regs[2];
$body = preg_replace('/(src|background|href)=(["\']?)([\.\/]+[^"\'\s]+)(\2|\s|>)/Uie', "'\\1=\"'.make_absolute_url('\\3', '$base_url').'\"'", $body);
$body = preg_replace('/(url\s*\()(["\']?)([\.\/]+[^"\'\)\s]+)(\2)\)/Uie', "'\\1\''.make_absolute_url('\\3', '$base_url').'\')'", $body);
$body = preg_replace($base_reg, '', $body);
}
// modify HTML links to open a new window if clicked
- $body = preg_replace('/<a\s+([^>]+)>/Uie', "rcmail_alter_html_link('\\1');", $body);
+ $body = preg_replace('/<(a|link)\s+([^>]+)>/Uie', "rcmail_alter_html_link('\\1','\\2', '$container_id');", $body);
// add comments arround html and other tags
$out = preg_replace(array(
@@ -1005,11 +1008,16 @@ function rcmail_sanitize_html($body, $container_id)
'<!--\\1-->',
$body);
- $out = preg_replace(array('/<body([^>]*)>/i',
- '/<\/body>/i'),
- array('<div class="rcmBody"\\1>',
- '</div>'),
- $out);
+ $out = preg_replace(
+ array(
+ '/<body([^>]*)>/i',
+ '/<\/body>/i',
+ ),
+ array(
+ '<div class="rcmBody"\\1>',
+ '</div>',
+ ),
+ $out);
// quote <? of php and xml files that are specified as text/html
$out = preg_replace(array('/<\?/', '/\?>/'), array('&lt;?', '?&gt;'), $out);
@@ -1019,44 +1027,24 @@ function rcmail_sanitize_html($body, $container_id)
// parse link attributes and set correct target
-function rcmail_alter_html_link($in)
+function rcmail_alter_html_link($tag, $attrs, $container_id)
{
$in = preg_replace('/=([^("|\'|\s)]+)(\s|$)/', '="\1"', $in);
- $attrib = parse_attrib_string($in);
-
- if (stristr((string)$attrib['href'], 'mailto:'))
- $attrib['onclick'] = sprintf("return %s.command('compose','%s',this)",
- JS_OBJECT_NAME,
- JQ(substr($attrib['href'], 7)));
- else if (!empty($attrib['href']) && $attrib['href']{0}!='#')
- $attrib['target'] = '_blank';
+ $attrib = parse_attrib_string($attrs);
- return '<a' . create_attrib_string($attrib, array('href', 'name', 'target', 'onclick', 'id', 'class', 'style', 'title')) . '>';
- }
-
-
-// replace all css definitions with #container [def]
-function rcmail_mod_css_styles($source, $container_id)
- {
- $a_css_values = array();
- $last_pos = 0;
+ if ($tag == 'link' && preg_match('/^https?:\/\//i', $attrib['href']))
+ $attrib['href'] = "./bin/modcss.php?u=" . urlencode($attrib['href']) . "&amp;c=" . urlencode($container_id);
+
+ else if (stristr((string)$attrib['href'], 'mailto:'))
+ $attrib['onclick'] = sprintf(
+ "return %s.command('compose','%s',this)",
+ JS_OBJECT_NAME,
+ JQ(substr($attrib['href'], 7)));
- // cut out all contents between { and }
- while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos)))
- {
- $key = sizeof($a_css_values);
- $a_css_values[$key] = substr($source, $pos+1, $pos2-($pos+1));
- $source = substr($source, 0, $pos+1) . "<<str_replacement[$key]>>" . substr($source, $pos2, strlen($source)-$pos2);
- $last_pos = $pos+2;
- }
-
- // remove html commends and add #container to each tag selector.
- // also replace body definition because we also stripped off the <body> tag
- $styles = preg_replace(array('/(^\s*<!--)|(-->\s*$)/', '/(^\s*|,\s*|\}\s*)([a-z0-9\._][a-z0-9\.\-_]*)/im', '/<<str_replacement\[([0-9]+)\]>>/e', "/$container_id\s+body/i"),
- array('', "\\1#$container_id \\2", "\$a_css_values[\\1]", "$container_id div.rcmBody"),
- $source);
+ else if (!empty($attrib['href']) && $attrib['href']{0}!='#')
+ $attrib['target'] = '_blank';
- return $styles;
+ return "<$tag" . create_attrib_string($attrib, array('href','name','target','onclick','id','class','style','title','rel','type','media')) . ' />';
}