Skip to content

Commit 16c3235

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 6d6fdd2 commit 16c3235

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed

Diff for: core/SSViewer.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -439,9 +439,10 @@ public function process($item, $cache = null) {
439439
if($this->rewriteHashlinks && self::$options['rewriteHashlinks']) {
440440
if(strpos($output, '<base') !== false) {
441441
if(SSViewer::$options['rewriteHashlinks'] === 'php') {
442-
$thisURLRelativeToBase = "<?php echo \$_SERVER['REQUEST_URI']; ?>";
442+
// Emulate Convert::raw2att() without adding this dependency
443+
$thisURLRelativeToBase = "<?php echo str_replace(array('&','\"',\"'\",'<','>'), array('&amp;','&quot;','&#39;','&lt;','&gt;'), \$_SERVER['REQUEST_URI']); ?>";
443444
} else {
444-
$thisURLRelativeToBase = Director::makeRelative(Director::absoluteURL($_SERVER['REQUEST_URI']));
445+
$thisURLRelativeToBase = Convert::raw2att($_SERVER['REQUEST_URI']);
445446
}
446447
$output = preg_replace('/(<a[^>]+href *= *)"#/i', '\\1"' . $thisURLRelativeToBase . '#', $output);
447448
}

Diff for: tests/SSViewerTest.php

+70
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,76 @@ function testBaseTagGeneration() {
136136
$negotiator->xhtml($response);
137137
$this->assertRegExp('/<head><base href=".*" \/><\/head>/', $response->getBody());
138138
}
139+
140+
function testRewriteHashlinks() {
141+
$oldRewriteHashLinks = SSViewer::getOption('rewriteHashlinks');
142+
SSViewer::setOption('rewriteHashlinks', true);
143+
144+
// Emulate SSViewer::process()
145+
$base = Convert::raw2att($_SERVER['REQUEST_URI']);
146+
147+
$tmplFile = TEMP_FOLDER . '/SSViewerTest_testRewriteHashlinks_' . sha1(rand()) . '.ss';
148+
149+
// Note: SSViewer_FromString doesn't rewrite hash links.
150+
file_put_contents($tmplFile, '<!DOCTYPE html>
151+
<html>
152+
<head><% base_tag %></head>
153+
<body>
154+
<a class="inline" href="#anchor">InlineLink</a>
155+
$InsertedLink
156+
<body>
157+
</html>');
158+
$tmpl = new SSViewer($tmplFile);
159+
$obj = new ViewableData();
160+
$obj->InsertedLink = '<a class="inserted" href="#anchor">InsertedLink</a>';
161+
$result = $tmpl->process($obj);
162+
$this->assertContains(
163+
'<a class="inserted" href="' . $base . '#anchor">InsertedLink</a>',
164+
$result
165+
);
166+
$this->assertContains(
167+
'<a class="inline" href="' . $base . '#anchor">InlineLink</a>',
168+
$result
169+
);
170+
171+
unlink($tmplFile);
172+
173+
SSViewer::setOption('rewriteHashlinks', $oldRewriteHashLinks);
174+
}
175+
176+
function testRewriteHashlinksInPhpMode() {
177+
$oldRewriteHashLinks = SSViewer::getOption('rewriteHashlinks');
178+
SSViewer::setOption('rewriteHashlinks', 'php');
179+
180+
$tmplFile = TEMP_FOLDER . '/SSViewerTest_testRewriteHashlinksInPhpMode_' . sha1(rand()) . '.ss';
181+
182+
// Note: SSViewer_FromString doesn't rewrite hash links.
183+
file_put_contents($tmplFile, '<!DOCTYPE html>
184+
<html>
185+
<head><% base_tag %></head>
186+
<body>
187+
<a class="inline" href="#anchor">InlineLink</a>
188+
$InsertedLink
189+
<body>
190+
</html>');
191+
$tmpl = new SSViewer($tmplFile);
192+
$obj = new ViewableData();
193+
$obj->InsertedLink = '<a class="inserted" href="#anchor">InsertedLink</a>';
194+
$result = $tmpl->process($obj);
195+
$this->assertContains(
196+
'<a class="inserted" href="<?php echo str_replace(',
197+
$result
198+
);
199+
// TODO Fix inline links in PHP mode
200+
// $this->assertContains(
201+
// '<a class="inline" href="<?php echo str_replace(',
202+
// $result
203+
// );
204+
205+
unlink($tmplFile);
206+
207+
SSViewer::setOption('rewriteHashlinks', $oldRewriteHashLinks);
208+
}
139209
}
140210

141211
class SSViewerTest_ViewableData extends ViewableData implements TestOnly {

0 commit comments

Comments
 (0)