Skip to content

Commit 9da9a14

Browse files
[TwigBridge] Ensure CodeExtension's filters properly escape their input
1 parent d4a7010 commit 9da9a14

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

src/Symfony/Bridge/Twig/Extension/CodeExtension.php

+14-9
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ public function __construct($fileLinkFormat, string $projectDir, string $charset
4848
public function getFilters()
4949
{
5050
return [
51-
new TwigFilter('abbr_class', [$this, 'abbrClass'], ['is_safe' => ['html']]),
52-
new TwigFilter('abbr_method', [$this, 'abbrMethod'], ['is_safe' => ['html']]),
51+
new TwigFilter('abbr_class', [$this, 'abbrClass'], ['is_safe' => ['html'], 'pre_escape' => 'html']),
52+
new TwigFilter('abbr_method', [$this, 'abbrMethod'], ['is_safe' => ['html'], 'pre_escape' => 'html']),
5353
new TwigFilter('format_args', [$this, 'formatArgs'], ['is_safe' => ['html']]),
5454
new TwigFilter('format_args_as_text', [$this, 'formatArgsAsText']),
5555
new TwigFilter('file_excerpt', [$this, 'fileExcerpt'], ['is_safe' => ['html']]),
@@ -95,22 +95,23 @@ public function formatArgs($args)
9595
$result = [];
9696
foreach ($args as $key => $item) {
9797
if ('object' === $item[0]) {
98+
$item[1] = htmlspecialchars($item[1], \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset);
9899
$parts = explode('\\', $item[1]);
99100
$short = array_pop($parts);
100101
$formattedValue = sprintf('<em>object</em>(<abbr title="%s">%s</abbr>)', $item[1], $short);
101102
} elseif ('array' === $item[0]) {
102-
$formattedValue = sprintf('<em>array</em>(%s)', \is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
103+
$formattedValue = sprintf('<em>array</em>(%s)', \is_array($item[1]) ? $this->formatArgs($item[1]) : htmlspecialchars(var_export($item[1], true), \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset));
103104
} elseif ('null' === $item[0]) {
104105
$formattedValue = '<em>null</em>';
105106
} elseif ('boolean' === $item[0]) {
106-
$formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>';
107+
$formattedValue = '<em>'.strtolower(htmlspecialchars(var_export($item[1], true), \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset)).'</em>';
107108
} elseif ('resource' === $item[0]) {
108109
$formattedValue = '<em>resource</em>';
109110
} else {
110111
$formattedValue = str_replace("\n", '', htmlspecialchars(var_export($item[1], true), \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset));
111112
}
112113

113-
$result[] = \is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
114+
$result[] = \is_int($key) ? $formattedValue : sprintf("'%s' => %s", htmlspecialchars($key, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset), $formattedValue);
114115
}
115116

116117
return implode(', ', $result);
@@ -178,13 +179,17 @@ public function fileExcerpt($file, $line, $srcContext = 3)
178179
public function formatFile($file, $line, $text = null)
179180
{
180181
$file = trim($file);
182+
$line = (int) $line;
181183

182184
if (null === $text) {
183-
$text = $file;
184-
if (null !== $rel = $this->getFileRelative($text)) {
185-
$rel = explode('/', $rel, 2);
186-
$text = sprintf('<abbr title="%s%2$s">%s</abbr>%s', $this->projectDir, $rel[0], '/'.($rel[1] ?? ''));
185+
if (null !== $rel = $this->getFileRelative($file)) {
186+
$rel = explode('/', htmlspecialchars($rel, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset), 2);
187+
$text = sprintf('<abbr title="%s%2$s">%s</abbr>%s', htmlspecialchars($this->projectDir, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset), $rel[0], '/'.($rel[1] ?? ''));
188+
} else {
189+
$text = htmlspecialchars($file, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset);
187190
}
191+
} else {
192+
$text = htmlspecialchars($text, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset);
188193
}
189194

190195
if (0 < $line) {

0 commit comments

Comments
 (0)