Skip to content

Commit 21f99b1

Browse files
authored
Merge pull request #745 from aidantwoods/dev-1.7.x/opt-in-rawHtml
Opt in raw html
2 parents 3d2b25b + 791faca commit 21f99b1

File tree

4 files changed

+99
-4
lines changed

4 files changed

+99
-4
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ matrix:
1414
- php: 7.1
1515
- php: 7.2
1616
- php: 7.3
17+
- php: 7.4
1718
- php: nightly
1819
fast_finish: true
1920
allow_failures:

Parsedown.php

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class Parsedown
1717
{
1818
# ~
1919

20-
const version = '1.7.3';
20+
const version = '1.7.4-dev';
2121

2222
# ~
2323

@@ -1489,22 +1489,41 @@ protected function element(array $Element)
14891489
}
14901490
}
14911491

1492+
$permitRawHtml = false;
1493+
14921494
if (isset($Element['text']))
1495+
{
1496+
$text = $Element['text'];
1497+
}
1498+
// very strongly consider an alternative if you're writing an
1499+
// extension
1500+
elseif (isset($Element['rawHtml']))
1501+
{
1502+
$text = $Element['rawHtml'];
1503+
$allowRawHtmlInSafeMode = isset($Element['allowRawHtmlInSafeMode']) && $Element['allowRawHtmlInSafeMode'];
1504+
$permitRawHtml = !$this->safeMode || $allowRawHtmlInSafeMode;
1505+
}
1506+
1507+
if (isset($text))
14931508
{
14941509
$markup .= '>';
14951510

1496-
if (!isset($Element['nonNestables']))
1511+
if (!isset($Element['nonNestables']))
14971512
{
14981513
$Element['nonNestables'] = array();
14991514
}
15001515

15011516
if (isset($Element['handler']))
15021517
{
1503-
$markup .= $this->{$Element['handler']}($Element['text'], $Element['nonNestables']);
1518+
$markup .= $this->{$Element['handler']}($text, $Element['nonNestables']);
1519+
}
1520+
elseif (!$permitRawHtml)
1521+
{
1522+
$markup .= self::escape($text, true);
15041523
}
15051524
else
15061525
{
1507-
$markup .= self::escape($Element['text'], true);
1526+
$markup .= $text;
15081527
}
15091528

15101529
$markup .= '</'.$Element['name'].'>';

test/ParsedownTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
require 'SampleExtensions.php';
4+
35
use PHPUnit\Framework\TestCase;
46

57
class ParsedownTest extends TestCase
@@ -55,6 +57,40 @@ function test_($test, $dir)
5557
$this->assertEquals($expectedMarkup, $actualMarkup);
5658
}
5759

60+
function testRawHtml()
61+
{
62+
$markdown = "```php\nfoobar\n```";
63+
$expectedMarkup = '<pre><code class="language-php"><p>foobar</p></code></pre>';
64+
$expectedSafeMarkup = '<pre><code class="language-php">&lt;p&gt;foobar&lt;/p&gt;</code></pre>';
65+
66+
$unsafeExtension = new UnsafeExtension;
67+
$actualMarkup = $unsafeExtension->text($markdown);
68+
69+
$this->assertEquals($expectedMarkup, $actualMarkup);
70+
71+
$unsafeExtension->setSafeMode(true);
72+
$actualSafeMarkup = $unsafeExtension->text($markdown);
73+
74+
$this->assertEquals($expectedSafeMarkup, $actualSafeMarkup);
75+
}
76+
77+
function testTrustDelegatedRawHtml()
78+
{
79+
$markdown = "```php\nfoobar\n```";
80+
$expectedMarkup = '<pre><code class="language-php"><p>foobar</p></code></pre>';
81+
$expectedSafeMarkup = $expectedMarkup;
82+
83+
$unsafeExtension = new TrustDelegatedExtension;
84+
$actualMarkup = $unsafeExtension->text($markdown);
85+
86+
$this->assertEquals($expectedMarkup, $actualMarkup);
87+
88+
$unsafeExtension->setSafeMode(true);
89+
$actualSafeMarkup = $unsafeExtension->text($markdown);
90+
91+
$this->assertEquals($expectedSafeMarkup, $actualSafeMarkup);
92+
}
93+
5894
function data()
5995
{
6096
$data = array();

test/SampleExtensions.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
class UnsafeExtension extends Parsedown
4+
{
5+
protected function blockFencedCodeComplete($Block)
6+
{
7+
$text = $Block['element']['text']['text'];
8+
unset($Block['element']['text']['text']);
9+
10+
// WARNING: There is almost always a better way of doing things!
11+
//
12+
// This example is one of them, unsafe behaviour is NOT needed here.
13+
// Only use this if you trust the input and have no idea what
14+
// the output HTML will look like (e.g. using an external parser).
15+
$Block['element']['text']['rawHtml'] = "<p>$text</p>";
16+
17+
return $Block;
18+
}
19+
}
20+
21+
class TrustDelegatedExtension extends Parsedown
22+
{
23+
protected function blockFencedCodeComplete($Block)
24+
{
25+
$text = $Block['element']['text']['text'];
26+
unset($Block['element']['text']['text']);
27+
28+
// WARNING: There is almost always a better way of doing things!
29+
//
30+
// This behaviour is NOT needed in the demonstrated case.
31+
// Only use this if you are sure that the result being added into
32+
// rawHtml is safe.
33+
// (e.g. using an external parser with escaping capabilities).
34+
$Block['element']['text']['rawHtml'] = "<p>$text</p>";
35+
$Block['element']['text']['allowRawHtmlInSafeMode'] = true;
36+
37+
return $Block;
38+
}
39+
}

0 commit comments

Comments
 (0)