Filter linked/imported CSS files (#1484056)

release-0.6
thomascube 17 years ago
parent ca2b4ddfcc
commit 97bd2c0537

@ -1,6 +1,11 @@
CHANGELOG RoundCube Webmail
---------------------------
2007/09/29 (thomasb)
----------
- Filter linked/imported CSS files (closes #1484056)
2007/09/27 (tomekp)
----------
- Update brazilian portuguese localization (#1484580)

@ -0,0 +1,67 @@
<?php
/*
+-----------------------------------------------------------------------+
| program/bin/modcss.php |
| |
| This file is part of the RoundCube Webmail client |
| Copyright (C) 2007, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
| Modify CSS source from a URL |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
$Id: $
*/
$INSTALL_PATH = realpath("./../") . "/";
ini_set('include_path', $INSTALL_PATH.PATH_SEPARATOR.$INSTALL_PATH.'program'.PATH_SEPARATOR.ini_get('include_path'));
require 'include/main.inc';
$source = "";
if ($url = preg_replace('/[^a-z0-9.-_\?\$&=%]/i', '', $_GET['u']))
{
$a_uri = parse_url($url);
$port = $a_uri['port'] ? $a_uri['port'] : 80;
$host = $a_uri['host'];
$path = $a_uri['path'] . ($a_uri['query'] ? '?'.$a_uri['query'] : '');
if ($fp = fsockopen($host, $port, $errno, $errstr, 30))
{
$out = "GET $path HTTP/1.0\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
$header = true;
while (!feof($fp))
{
$line = trim(fgets($fp, 4048));
if ($header && preg_match('/^HTTP\/1\..\s+(\d+)/', $line, $regs) && intval($regs[1]) != 200)
break;
else if (empty($line) && $header)
$header = false;
else if (!$header)
$source .= "$line\n";
}
fclose($fp);
}
}
if (!empty($source))
{
header("Content-Type: text/css");
echo rcmail_mod_css_styles($source, preg_replace('/[^a-z0-9]/i', '', $_GET['c']), $url);
}
else
header("HTTP/1.0 404 Not Found");
?>

@ -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');
@ -1449,6 +1450,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
*

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

@ -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')) . ' />';
}

Loading…
Cancel
Save