BUGFIX Escaping base URLs for anchor links rewritten by SSViewer::process() with the 'rewriteHashlinks' option enabled (which is a framework default, and necessary because of the use of a <base> tag). Also added escaping for base URLs rendered through the 'php' variation of 'rewriteHashlinks'

This commit is contained in:
Ingo Schommer 2011-10-18 11:42:55 +02:00
parent 2ce1882e38
commit e2bf21ba1a
4 changed files with 74 additions and 4 deletions

View File

@ -513,6 +513,76 @@ after')
// Remove all the test themes we created
Filesystem::removeFolder($testThemeBaseDir);
}
function testRewriteHashlinks() {
$oldRewriteHashLinks = SSViewer::getOption('rewriteHashlinks');
SSViewer::setOption('rewriteHashlinks', true);
// Emulate SSViewer::process()
$base = Convert::raw2att($_SERVER['REQUEST_URI']);
$tmplFile = TEMP_FOLDER . '/SSViewerTest_testRewriteHashlinks_' . sha1(rand()) . '.ss';
// Note: SSViewer_FromString doesn't rewrite hash links.
file_put_contents($tmplFile, '<!DOCTYPE html>
<html>
<head><% base_tag %></head>
<body>
<a class="inline" href="#anchor">InlineLink</a>
$InsertedLink
<body>
</html>');
$tmpl = new SSViewer($tmplFile);
$obj = new ViewableData();
$obj->InsertedLink = '<a class="inserted" href="#anchor">InsertedLink</a>';
$result = $tmpl->process($obj);
$this->assertContains(
'<a class="inserted" href="' . $base . '#anchor">InsertedLink</a>',
$result
);
$this->assertContains(
'<a class="inline" href="' . $base . '#anchor">InlineLink</a>',
$result
);
unlink($tmplFile);
SSViewer::setOption('rewriteHashlinks', $oldRewriteHashLinks);
}
function testRewriteHashlinksInPhpMode() {
$oldRewriteHashLinks = SSViewer::getOption('rewriteHashlinks');
SSViewer::setOption('rewriteHashlinks', 'php');
$tmplFile = TEMP_FOLDER . '/SSViewerTest_testRewriteHashlinksInPhpMode_' . sha1(rand()) . '.ss';
// Note: SSViewer_FromString doesn't rewrite hash links.
file_put_contents($tmplFile, '<!DOCTYPE html>
<html>
<head><% base_tag %></head>
<body>
<a class="inline" href="#anchor">InlineLink</a>
$InsertedLink
<body>
</html>');
$tmpl = new SSViewer($tmplFile);
$obj = new ViewableData();
$obj->InsertedLink = '<a class="inserted" href="#anchor">InsertedLink</a>';
$result = $tmpl->process($obj);
$this->assertContains(
'<a class="inserted" href="<?php echo strip_tags(',
$result
);
// TODO Fix inline links in PHP mode
// $this->assertContains(
// '<a class="inline" href="<?php echo str_replace(',
// $result
// );
unlink($tmplFile);
SSViewer::setOption('rewriteHashlinks', $oldRewriteHashLinks);
}
}

View File

@ -3882,7 +3882,7 @@ class SSTemplateParser extends Parser {
// TODO: This is pretty ugly & gets applied on all files not just html. I wonder if we can make this non-dynamically calculated
$text = preg_replace(
'/href\s*\=\s*\"\#/',
'href="\' . (SSViewer::$options[\'rewriteHashlinks\'] ? Convert::raw2att( $_SERVER[\'REQUEST_URI\'] ) : "") . \'#',
'href="\' . (SSViewer::$options[\'rewriteHashlinks\'] ? strip_tags( $_SERVER[\'REQUEST_URI\'] ) : "") . \'#',
$text
);

View File

@ -870,7 +870,7 @@ class SSTemplateParser extends Parser {
// TODO: This is pretty ugly & gets applied on all files not just html. I wonder if we can make this non-dynamically calculated
$text = preg_replace(
'/href\s*\=\s*\"\#/',
'href="\' . (SSViewer::$options[\'rewriteHashlinks\'] ? Convert::raw2att( $_SERVER[\'REQUEST_URI\'] ) : "") . \'#',
'href="\' . (SSViewer::$options[\'rewriteHashlinks\'] ? strip_tags( $_SERVER[\'REQUEST_URI\'] ) : "") . \'#',
$text
);

View File

@ -503,9 +503,9 @@ class SSViewer {
if($this->rewriteHashlinks && self::$options['rewriteHashlinks']) {
if(strpos($output, '<base') !== false) {
if(SSViewer::$options['rewriteHashlinks'] === 'php') {
$thisURLRelativeToBase = "<?php echo \$_SERVER['REQUEST_URI']; ?>";
$thisURLRelativeToBase = "<?php echo strip_tags(\$_SERVER['REQUEST_URI']); ?>";
} else {
$thisURLRelativeToBase = Director::makeRelative(Director::absoluteURL($_SERVER['REQUEST_URI']));
$thisURLRelativeToBase = strip_tags($_SERVER['REQUEST_URI']);
}
$output = preg_replace('/(<a[^>]+href *= *)"#/i', '\\1"' . $thisURLRelativeToBase . '#', $output);
}