Skip to content

Commit 52a895f

Browse files
committed
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'
1 parent 5bc0d00 commit 52a895f

File tree

2 files changed

+74
-4
lines changed

2 files changed

+74
-4
lines changed

Diff for: core/SSViewer.php

+5-4
Original file line numberDiff line numberDiff line change
@@ -366,13 +366,14 @@ public function process($item) {
366366
// If we have our crazy base tag, then fix # links referencing the current page.
367367
if(strpos($output, '<base') !== false) {
368368
if(SSViewer::$options['rewriteHashlinks'] === 'php') {
369-
$thisURLRelativeToBase = "<?php echo \$_SERVER['REQUEST_URI']; ?>";
369+
// Emulate Convert::raw2att() without adding this dependency
370+
$thisURLRelativeToBase = "<?php echo str_replace(array('&','\"',\"'\",'<','>'), array('&amp;','&quot;','&#39;','&lt;','&gt;'), \$_SERVER['REQUEST_URI']); ?>";
370371
} else {
371-
$thisURLRelativeToBase = Director::makeRelative(Director::absoluteURL($_SERVER['REQUEST_URI']));
372+
$thisURLRelativeToBase = Convert::raw2att($_SERVER['REQUEST_URI']);
372373
}
373374
$output = preg_replace('/(<a[^>+]href *= *)"#/i', '\\1"' . $thisURLRelativeToBase . '#', $output);
374-
}
375-
375+
}
376+
376377
return $output;
377378
}
378379

Diff for: tests/SSViewerTest.php

+69
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,73 @@ function testComments() {
4343

4444
$this->assertEquals("This is my templateThis is some contentThis is the final content", preg_replace("/\n?<!--.*-->\n?/U",'',$output));
4545
}
46+
47+
function testRewriteHashlinks() {
48+
$oldRewriteHashLinks = SSViewer::getOption('rewriteHashlinks');
49+
SSViewer::setOption('rewriteHashlinks', true);
50+
51+
// Emulate SSViewer::process()
52+
$base = Convert::raw2att($_SERVER['REQUEST_URI']);
53+
$tmplFile = TEMP_FOLDER . '/SSViewerTest_testRewriteHashlinks_' . sha1(rand()) . '.ss';
54+
55+
// Note: SSViewer_FromString doesn't rewrite hash links.
56+
file_put_contents($tmplFile, '<!DOCTYPE html>
57+
<html>
58+
<head><% base_tag %></head>
59+
<body>
60+
<a class="inline" href="#anchor">InlineLink</a>
61+
$InsertedLink
62+
<body>
63+
</html>');
64+
$tmpl = new SSViewer($tmplFile);
65+
$obj = new ViewableData();
66+
$obj->InsertedLink = '<a class="inserted" href="#anchor">InsertedLink</a>';
67+
$result = $tmpl->process($obj);
68+
$this->assertContains(
69+
'<a class="inserted" href="' . $base . '#anchor">InsertedLink</a>',
70+
$result
71+
);
72+
$this->assertContains(
73+
'<a class="inline" href="' . $base . '#anchor">InlineLink</a>',
74+
$result
75+
);
76+
77+
unlink($tmplFile);
78+
79+
SSViewer::setOption('rewriteHashlinks', $oldRewriteHashLinks);
80+
}
81+
82+
function testRewriteHashlinksInPhpMode() {
83+
$oldRewriteHashLinks = SSViewer::getOption('rewriteHashlinks');
84+
SSViewer::setOption('rewriteHashlinks', 'php');
85+
86+
$tmplFile = TEMP_FOLDER . '/SSViewerTest_testRewriteHashlinksInPhpMode_' . sha1(rand()) . '.ss';
87+
88+
// Note: SSViewer_FromString doesn't rewrite hash links.
89+
file_put_contents($tmplFile, '<!DOCTYPE html>
90+
<html>
91+
<head><% base_tag %></head>
92+
<body>
93+
<a class="inline" href="#anchor">InlineLink</a>
94+
$InsertedLink
95+
<body>
96+
</html>');
97+
$tmpl = new SSViewer($tmplFile);
98+
$obj = new ViewableData();
99+
$obj->InsertedLink = '<a class="inserted" href="#anchor">InsertedLink</a>';
100+
$result = $tmpl->process($obj);
101+
$this->assertContains(
102+
'<a class="inserted" href="<?php echo str_replace(',
103+
$result
104+
);
105+
// TODO Fix inline links in PHP mode
106+
// $this->assertContains(
107+
// '<a class="inline" href="<?php echo str_replace(',
108+
// $result
109+
// );
110+
111+
unlink($tmplFile);
112+
113+
SSViewer::setOption('rewriteHashlinks', $oldRewriteHashLinks);
114+
}
46115
}

0 commit comments

Comments
 (0)