mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-15 20:06:31 +00:00
Add JSON escape strategy
This commit is contained in:
committed by
Fabien Potencier
parent
c35ad8c4e3
commit
5c7b080b31
@@ -1,6 +1,6 @@
|
|||||||
* 1.35.4 (2018-XX-XX)
|
* 1.35.4 (2018-XX-XX)
|
||||||
|
|
||||||
* n/a
|
* "js" filter now produces valid JSON
|
||||||
|
|
||||||
* 1.35.3 (2018-03-20)
|
* 1.35.3 (2018-03-20)
|
||||||
|
|
||||||
|
|||||||
@@ -1040,7 +1040,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
|
|||||||
|
|
||||||
case 'js':
|
case 'js':
|
||||||
// escape all non-alphanumeric characters
|
// escape all non-alphanumeric characters
|
||||||
// into their \xHH or \uHHHH representations
|
// into their \x or \uHHHH representations
|
||||||
if ('UTF-8' !== $charset) {
|
if ('UTF-8' !== $charset) {
|
||||||
$string = twig_convert_encoding($string, 'UTF-8', $charset);
|
$string = twig_convert_encoding($string, 'UTF-8', $charset);
|
||||||
}
|
}
|
||||||
@@ -1152,9 +1152,23 @@ function _twig_escape_js_callback($matches)
|
|||||||
{
|
{
|
||||||
$char = $matches[0];
|
$char = $matches[0];
|
||||||
|
|
||||||
// \xHH
|
/*
|
||||||
if (!isset($char[1])) {
|
* A few characters have short escape sequences in JSON and JavaScript.
|
||||||
return '\\x'.strtoupper(substr('00'.bin2hex($char), -2));
|
* Escape sequences supported only by JavaScript, not JSON, are ommitted.
|
||||||
|
* \" is also supported but omitted, because the resulting string is not HTML safe.
|
||||||
|
*/
|
||||||
|
static $shortMap = array(
|
||||||
|
'\\' => '\\\\',
|
||||||
|
'/' => '\\/',
|
||||||
|
"\x08" => '\b',
|
||||||
|
"\x0C" => '\f',
|
||||||
|
"\x0A" => '\n',
|
||||||
|
"\x0D" => '\r',
|
||||||
|
"\x09" => '\t',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($shortMap[$char])) {
|
||||||
|
return $shortMap[$char];
|
||||||
}
|
}
|
||||||
|
|
||||||
// \uHHHH
|
// \uHHHH
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
|
|||||||
));
|
));
|
||||||
|
|
||||||
$this->assertEquals('foo<br/ > foo<br/ >', $twig->render('html', array('foo' => 'foo<br/ >')));
|
$this->assertEquals('foo<br/ > foo<br/ >', $twig->render('html', array('foo' => 'foo<br/ >')));
|
||||||
$this->assertEquals('foo\x3Cbr\x2F\x20\x3E foo\x3Cbr\x2F\x20\x3E', $twig->render('js', array('bar' => 'foo<br/ >')));
|
$this->assertEquals('foo\u003Cbr\/\u0020\u003E foo\u003Cbr\/\u0020\u003E', $twig->render('js', array('bar' => 'foo<br/ >')));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function escapingStrategyCallback($name)
|
public function escapingStrategyCallback($name)
|
||||||
|
|||||||
@@ -17,6 +17,6 @@ return array('br' => '<br />')
|
|||||||
return array('autoescape' => 'name')
|
return array('autoescape' => 'name')
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
<br />
|
<br />
|
||||||
\x3Cbr\x20\x2F\x3E
|
\u003Cbr\u0020\/\u003E
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
|
|||||||
@@ -5,4 +5,4 @@
|
|||||||
--DATA--
|
--DATA--
|
||||||
return array()
|
return array()
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
\u00E9\x20\u265C\x20\uD834\uDF06
|
\u00E9\u0020\u265C\u0020\uD834\uDF06
|
||||||
|
|||||||
@@ -14,5 +14,5 @@
|
|||||||
return array()
|
return array()
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
foo<br />
|
foo<br />
|
||||||
\x20\x20\x20\x20foo\x3Cbr\x20\x2F\x3E\x0A
|
\u0020\u0020\u0020\u0020foo\u003Cbr\u0020\/\u003E\n
|
||||||
foo<br />
|
foo<br />
|
||||||
|
|||||||
@@ -80,4 +80,4 @@ unsafe_br()|escape
|
|||||||
autoescape js
|
autoescape js
|
||||||
|
|
||||||
safe_br
|
safe_br
|
||||||
\x3Cbr\x20\x2F\x3E
|
\u003Cbr\u0020\/\u003E
|
||||||
|
|||||||
@@ -7,5 +7,5 @@
|
|||||||
--DATA--
|
--DATA--
|
||||||
return array('var' => '<br />"')
|
return array('var' => '<br />"')
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
\x3Cbr\x20\x2F\x3E\x22
|
\u003Cbr\u0020\/\u003E\u0022
|
||||||
<br />"
|
<br />"
|
||||||
|
|||||||
@@ -7,5 +7,5 @@
|
|||||||
--DATA--
|
--DATA--
|
||||||
return array('var' => '<br />"')
|
return array('var' => '<br />"')
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
\x3Cbr\x20\x2F\x3E\x22
|
\u003Cbr\u0020\/\u003E\u0022
|
||||||
<br />"
|
<br />"
|
||||||
|
|||||||
@@ -44,15 +44,15 @@ return array('msg' => "<>\n'\"")
|
|||||||
|
|
||||||
1. autoescape 'html' |escape('js')
|
1. autoescape 'html' |escape('js')
|
||||||
|
|
||||||
<a onclick="alert("\x3C\x3E\x0A\x27\x22")"></a>
|
<a onclick="alert("\u003C\u003E\n\u0027\u0022")"></a>
|
||||||
|
|
||||||
2. autoescape 'html' |escape('js')
|
2. autoescape 'html' |escape('js')
|
||||||
|
|
||||||
<a onclick="alert("\x3C\x3E\x0A\x27\x22")"></a>
|
<a onclick="alert("\u003C\u003E\n\u0027\u0022")"></a>
|
||||||
|
|
||||||
3. autoescape 'js' |escape('js')
|
3. autoescape 'js' |escape('js')
|
||||||
|
|
||||||
<a onclick="alert("\x3C\x3E\x0A\x27\x22")"></a>
|
<a onclick="alert("\u003C\u003E\n\u0027\u0022")"></a>
|
||||||
|
|
||||||
4. no escape
|
4. no escape
|
||||||
|
|
||||||
@@ -61,9 +61,9 @@ return array('msg' => "<>\n'\"")
|
|||||||
|
|
||||||
5. |escape('js')|escape('html')
|
5. |escape('js')|escape('html')
|
||||||
|
|
||||||
<a onclick="alert("\x3C\x3E\x0A\x27\x22")"></a>
|
<a onclick="alert("\u003C\u003E\n\u0027\u0022")"></a>
|
||||||
|
|
||||||
6. autoescape 'html' |escape('js')|escape('html')
|
6. autoescape 'html' |escape('js')|escape('html')
|
||||||
|
|
||||||
<a onclick="alert("\x3C\x3E\x0A\x27\x22")"></a>
|
<a onclick="alert("\u003C\u003E\n\u0027\u0022")"></a>
|
||||||
|
|
||||||
|
|||||||
@@ -51,13 +51,15 @@ class Twig_Test_EscapingTest extends \PHPUnit\Framework\TestCase
|
|||||||
|
|
||||||
protected $jsSpecialChars = array(
|
protected $jsSpecialChars = array(
|
||||||
/* HTML special chars - escape without exception to hex */
|
/* HTML special chars - escape without exception to hex */
|
||||||
'<' => '\\x3C',
|
'<' => '\\u003C',
|
||||||
'>' => '\\x3E',
|
'>' => '\\u003E',
|
||||||
'\'' => '\\x27',
|
'\'' => '\\u0027',
|
||||||
'"' => '\\x22',
|
'"' => '\\u0022',
|
||||||
'&' => '\\x26',
|
'&' => '\\u0026',
|
||||||
|
'/' => '\\/',
|
||||||
/* Characters beyond ASCII value 255 to unicode escape */
|
/* Characters beyond ASCII value 255 to unicode escape */
|
||||||
'Ā' => '\\u0100',
|
'Ā' => '\\u0100',
|
||||||
|
'😀' => '\\uD83D\\uDE00',
|
||||||
/* Immune chars excluded */
|
/* Immune chars excluded */
|
||||||
',' => ',',
|
',' => ',',
|
||||||
'.' => '.',
|
'.' => '.',
|
||||||
@@ -70,12 +72,14 @@ class Twig_Test_EscapingTest extends \PHPUnit\Framework\TestCase
|
|||||||
'0' => '0',
|
'0' => '0',
|
||||||
'9' => '9',
|
'9' => '9',
|
||||||
/* Basic control characters and null */
|
/* Basic control characters and null */
|
||||||
"\r" => '\\x0D',
|
"\r" => '\r',
|
||||||
"\n" => '\\x0A',
|
"\n" => '\n',
|
||||||
"\t" => '\\x09',
|
"\x08" => '\b',
|
||||||
"\0" => '\\x00',
|
"\t" => '\t',
|
||||||
|
"\x0C" => '\f',
|
||||||
|
"\0" => '\\u0000',
|
||||||
/* Encode spaces for quoteless attribute protection */
|
/* Encode spaces for quoteless attribute protection */
|
||||||
' ' => '\\x20',
|
' ' => '\\u0020',
|
||||||
);
|
);
|
||||||
|
|
||||||
protected $urlSpecialChars = array(
|
protected $urlSpecialChars = array(
|
||||||
|
|||||||
Reference in New Issue
Block a user