Skip to content

Commit 01e2d7f

Browse files
committed
allowed including HTML in <script type=html>
1 parent 0d7d933 commit 01e2d7f

5 files changed

Lines changed: 51 additions & 7 deletions

File tree

src/Latte/Compiler/Escaper.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ final class Escaper
7070
self::HtmlAttributeQuoted . '+' . self::Url => 'convertHtmlToHtmlAttr',
7171
self::HtmlComment => 'escapeHtmlComment',
7272
self::HtmlAttributeUnquoted => 'convertHtmlToUnquotedAttr',
73+
self::HtmlRawText . '+' . self::HtmlText => 'convertHtmlToHtmlRawText',
7374
],
7475
self::HtmlAttributeQuoted => [
7576
self::HtmlText => 'convertHtmlToHtmlAttr',

src/Latte/Runtime/Filters.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,15 @@ public static function convertJSToHtmlRawText($s): string
191191
}
192192

193193

194+
/**
195+
* Converts HTML for usage in <script type=text/html>
196+
*/
197+
public static function convertHtmlToHtmlRawText(string $s): string
198+
{
199+
return preg_replace('#<(/?)script#i', '&lt;$1script', $s);
200+
}
201+
202+
194203
/**
195204
* Converts ... to ...
196205
*/

tests/common/contentType.compatibility.phpt

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ Assert::same('<!-- </script>-->', $latte->renderToString('context6'));
277277

278278
$latte = new Latte\Engine;
279279
$latte->setLoader(new Latte\Loaders\StringLoader([
280-
'html.latte' => '<hr> " &quot; &lt;',
280+
'html.latte' => '<hr><script></script> " &quot; &lt;',
281281

282282
'context1' => '<p>{include html.latte}</p>',
283283
'context1a' => '<p>{include html.latte|noescape}</p>',
@@ -289,37 +289,40 @@ $latte->setLoader(new Latte\Loaders\StringLoader([
289289
'context2c' => '<p title="{include html.latte|stripHtml|upper|noescape}"></p>',
290290
'context3' => '<p title={include html.latte}></p>',
291291
'context4' => '<script>{include html.latte}</script>',
292+
'context4a' => '<script type="text/html">{include html.latte}</script>',
292293
'context5' => '<style>{include html.latte}</style>',
293294
'context6' => '<!--{include html.latte}-->',
294295
]));
295296

296-
Assert::same('<p><hr> " &quot; &lt;</p>', $latte->renderToString('context1'));
297+
Assert::same('<p><hr><script></script> " &quot; &lt;</p>', $latte->renderToString('context1'));
297298

298-
Assert::same('<p><hr> " &quot; &lt;</p>', $latte->renderToString('context1a'));
299+
Assert::same('<p><hr><script></script> " &quot; &lt;</p>', $latte->renderToString('context1a'));
299300
Assert::same('<p> " " &lt;</p>', $latte->renderToString('context1b'));
300301
Assert::same('<p> " " <</p>', $latte->renderToString('context1c'));
301302

302-
Assert::same('<p title="&lt;hr&gt; &quot; &quot; &lt;"></p>', $latte->renderToString('context2'));
303+
Assert::same('<p title="&lt;hr&gt;&lt;script&gt;&lt;/script&gt; &quot; &quot; &lt;"></p>', $latte->renderToString('context2'));
303304

304-
Assert::same('<p title="<hr> " &quot; &lt;"></p>', $latte->renderToString('context2a'));
305+
Assert::same('<p title="<hr><script></script> " &quot; &lt;"></p>', $latte->renderToString('context2a'));
305306
Assert::same('<p title=" &quot; &quot; &lt;"></p>', $latte->renderToString('context2b'));
306307
Assert::same('<p title=" " " <"></p>', $latte->renderToString('context2c'));
307308

308-
Assert::same('<p title="&lt;hr&gt; &quot; &quot; &lt;"></p>', $latte->renderToString('context3'));
309+
Assert::same('<p title="&lt;hr&gt;&lt;script&gt;&lt;/script&gt; &quot; &quot; &lt;"></p>', $latte->renderToString('context3'));
309310

310311
Assert::exception(
311312
fn() => $latte->renderToString('context4'),
312313
Latte\RuntimeException::class,
313314
"Including 'html.latte' with content type HTML into incompatible type HTML/RAW+JS.",
314315
);
315316

317+
Assert::same('<script type="text/html"><hr>&lt;script>&lt;/script> " &quot; &lt;</script>', $latte->renderToString('context4a'));
318+
316319
Assert::exception(
317320
fn() => $latte->renderToString('context5'),
318321
Latte\RuntimeException::class,
319322
"Including 'html.latte' with content type HTML into incompatible type HTML/RAW+CSS.",
320323
);
321324

322-
Assert::same('<!--<hr> " &quot; &lt;-->', $latte->renderToString('context6'));
325+
Assert::same('<!--<hr><script></script> " &quot; &lt;-->', $latte->renderToString('context6'));
323326

324327

325328

tests/common/contentType.html.html.phpt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ Assert::match(
3030
),
3131
);
3232

33+
// include
34+
Assert::match(
35+
' <script type="text/html">&lt;script>&lt;/script></script>',
36+
$latte->renderToString('{define a}<script></script>{/define} <script type="text/html">{include a}</script>'),
37+
);
38+
3339
// content of <script> is RAWTEXT
3440
Assert::match(
3541
<<<'XX'
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/**
4+
* Test: Latte\Runtime\Filters::convertHtmlToHtmlRawText
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
use Latte\Runtime\Filters;
10+
use Tester\Assert;
11+
12+
require __DIR__ . '/../bootstrap.php';
13+
14+
15+
Assert::same('', Filters::convertHtmlToHtmlRawText(''));
16+
Assert::same('string', Filters::convertHtmlToHtmlRawText('string'));
17+
Assert::same('< & \' " >', Filters::convertHtmlToHtmlRawText('< & \' " >'));
18+
Assert::same('</p>', Filters::convertHtmlToHtmlRawText('</p>'));
19+
Assert::same('foo </STYLE>', Filters::convertHtmlToHtmlRawText('foo </STYLE>'));
20+
Assert::same('foo &lt;script>', Filters::convertHtmlToHtmlRawText('foo <script>'));
21+
Assert::same('foo &lt;/script>', Filters::convertHtmlToHtmlRawText('foo </script>'));
22+
23+
// invalid UTF-8
24+
Assert::same("foo \u{D800} bar", Filters::convertHtmlToHtmlRawText("foo \u{D800} bar")); // invalid codepoint high surrogates
25+
Assert::same("foo \xE3\x80\x22 bar", Filters::convertHtmlToHtmlRawText("foo \xE3\x80\x22 bar")); // stripped UTF

0 commit comments

Comments
 (0)