- Fix bug in handling of base href and inline content (#1488290)

pull/1/head
alecpl 13 years ago
parent 48be8f6428
commit f5d62f7157

@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail CHANGELOG Roundcube Webmail
=========================== ===========================
- Fix bug in handling of base href and inline content (#1488290)
- Fix SQL Error when saving a contact with many email addresses (#1488286) - Fix SQL Error when saving a contact with many email addresses (#1488286)
- Fix strict email address searching if contact has more than one address - Fix strict email address searching if contact has more than one address
- Use proper timezones from PHP's internal timezonedb (#1485592) - Use proper timezones from PHP's internal timezonedb (#1485592)

@ -2093,7 +2093,68 @@ class rcube_base_replacer
public function callback($matches) public function callback($matches)
{ {
return $matches[1] . '="' . make_absolute_url($matches[3], $this->base_url) . '"'; return $matches[1] . '="' . self::absolute_url($matches[3], $this->base_url) . '"';
}
public function replace($body)
{
return preg_replace_callback(array(
'/(src|background|href)=(["\']?)([^"\'\s]+)(\2|\s|>)/Ui',
'/(url\s*\()(["\']?)([^"\'\)\s]+)(\2)\)/Ui',
),
array($this, 'callback'), $body);
}
/**
* Convert paths like ../xxx to an absolute path using a base url
*
* @param string $path Relative path
* @param string $base_url Base URL
*
* @return string Absolute URL
*/
public static function 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;
}
// check if path is a content-id scheme
if (strpos($path, 'cid:') === 0) {
return $path;
}
// cut base_url to the last directory
if (strrpos($base_url, '/') > 7) {
$host_url = substr($base_url, 0, strpos($base_url, '/', 7));
$base_url = substr($base_url, 0, strrpos($base_url, '/'));
}
// $path is absolute
if ($path[0] == '/') {
$abs_path = $host_url.$path;
}
else {
// strip './' because its the same as ''
$path = preg_replace('/^\.\//', '', $path);
if (preg_match_all('/\.\.\//', $path, $matches, PREG_SET_ORDER)) {
foreach ($matches as $a_match) {
if (strrpos($base_url, '/')) {
$base_url = substr($base_url, 0, strrpos($base_url, '/'));
}
$path = substr($path, 3);
}
}
$abs_path = $base_url.'/'.$path;
}
return $abs_path;
} }
} }

@ -163,52 +163,6 @@ function show_bytes($bytes)
return $str; return $str;
} }
/**
* Convert paths like ../xxx to an absolute path using a base url
*
* @param string Relative path
* @param string Base URL
* @return string Absolute URL
*/
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 (strrpos($base_url, '/')>7)
{
$host_url = substr($base_url, 0, strpos($base_url, '/', 7));
$base_url = substr($base_url, 0, strrpos($base_url, '/'));
}
// $path is absolute
if ($path[0] == '/')
$abs_path = $host_url.$path;
else
{
// strip './' because its the same as ''
$path = preg_replace('/^\.\//', '', $path);
if (preg_match_all('/\.\.\//', $path, $matches, PREG_SET_ORDER))
foreach ($matches as $a_match)
{
if (strrpos($base_url, '/'))
$base_url = substr($base_url, 0, strrpos($base_url, '/'));
$path = substr($path, 3);
}
$abs_path = $base_url.'/'.$path;
}
return $abs_path;
}
/** /**
* Wrapper function for wordwrap * Wrapper function for wordwrap
*/ */

@ -1110,15 +1110,13 @@ function rcmail_resolve_base($body)
// check for <base href=...> // check for <base href=...>
if (preg_match('!(<base.*href=["\']?)([hftps]{3,5}://[a-z0-9/.%-]+)!i', $body, $regs)) { if (preg_match('!(<base.*href=["\']?)([hftps]{3,5}://[a-z0-9/.%-]+)!i', $body, $regs)) {
$replacer = new rcube_base_replacer($regs[2]); $replacer = new rcube_base_replacer($regs[2]);
$body = $replacer->replace($body);
// replace all relative paths
$body = preg_replace_callback('/(src|background|href)=(["\']?)([^"\'\s]+)(\2|\s|>)/Ui', array($replacer, 'callback'), $body);
$body = preg_replace_callback('/(url\s*\()(["\']?)([^"\'\)\s]+)(\2)\)/Ui', array($replacer, 'callback'), $body);
} }
return $body; return $body;
} }
/** /**
* modify a HTML message that it can be displayed inside a HTML page * modify a HTML message that it can be displayed inside a HTML page
*/ */

@ -166,5 +166,9 @@ class rcube_test_mailfunc extends UnitTestCase
$this->assertPattern('|src="http://alec\.pl/dir/img1\.gif"|', $html, "URI base resolving [1]"); $this->assertPattern('|src="http://alec\.pl/dir/img1\.gif"|', $html, "URI base resolving [1]");
$this->assertPattern('|src="http://alec\.pl/dir/img2\.gif"|', $html, "URI base resolving [2]"); $this->assertPattern('|src="http://alec\.pl/dir/img2\.gif"|', $html, "URI base resolving [2]");
$this->assertPattern('|src="http://alec\.pl/img3\.gif"|', $html, "URI base resolving [3]"); $this->assertPattern('|src="http://alec\.pl/img3\.gif"|', $html, "URI base resolving [3]");
// base resolving exceptions
$this->assertPattern('|src="cid:theCID"|', $html, "URI base resolving exception [1]");
$this->assertPattern('|src="http://other\.domain\.tld/img3\.gif"|', $html, "URI base resolving exception [2]");
} }
} }

@ -6,5 +6,7 @@
<img src="img1.gif" /> <img src="img1.gif" />
<img src="./img2.gif" /> <img src="./img2.gif" />
<img src="../img3.gif" /> <img src="../img3.gif" />
<img src="cid:theCID" />
<img src="http://other.domain.tld/img3.gif" />
</body> </body>
</html> </html>

Loading…
Cancel
Save