mirror of
https://github.com/erusev/parsedown.git
synced 2023-08-10 21:13:06 +03:00
Compare commits
250 Commits
Author | SHA1 | Date | |
---|---|---|---|
cb17b6477d | |||
21f99b156a | |||
791faca8af | |||
add8d18c80 | |||
7073ac3ed1 | |||
3d2b25b79d | |||
6d89393817 | |||
d60bcdc469 | |||
c390a9e406 | |||
0f1e9da8f4 | |||
bc003952fc | |||
92e9c27ba0 | |||
9857334186 | |||
ae7e8e5067 | |||
253822057a | |||
a18bf495ed | |||
e5bf9560d7 | |||
33b51eaefa | |||
d686a50292 | |||
f3068df45a | |||
9b1f54b9d3 | |||
90439ef882 | |||
97dd037e6f | |||
fa89f0d743 | |||
d638fd8a25 | |||
cc53d5ae29 | |||
45f40696f6 | |||
e8f3d4efc0 | |||
096e164756 | |||
e2f3961f80 | |||
e941dcc3f0 | |||
c192001a7e | |||
48a053fe29 | |||
5057e505d8 | |||
ad62bf5a6f | |||
6678d59be4 | |||
c999a4b61b | |||
e938ab4ffe | |||
e69374af0d | |||
722b776684 | |||
7fd92a8fbd | |||
0e1043a8d6 | |||
1196ed9512 | |||
1244122b84 | |||
d98d60aaf3 | |||
296ebf0e60 | |||
a60ba300b1 | |||
089789dfff | |||
03e1a6ac02 | |||
fbe3fe878f | |||
09827f542c | |||
70ef6f5521 | |||
691e36b1f2 | |||
af6affdc2c | |||
9cf41f27ab | |||
16aadff2ed | |||
07c937583d | |||
4404201175 | |||
728952b90a | |||
c82af01bd6 | |||
67c3efbea0 | |||
593ffd45a3 | |||
bbb7687f31 | |||
b1e5aebaf6 | |||
c63b690a79 | |||
226f636360 | |||
2e4afde68d | |||
dc30cb441c | |||
f76b10aaab | |||
054ba3c487 | |||
4bae1c9834 | |||
aee3963e6b | |||
4dc98b635d | |||
e4bb12329e | |||
6d0156d707 | |||
29ad172261 | |||
131ba75851 | |||
924b26e16c | |||
af04ac92e2 | |||
6bb66db00f | |||
b3d45c4bb9 | |||
1d4296f34d | |||
bf5105cb1a | |||
1140613fc7 | |||
4367f89a74 | |||
1bf24f7334 | |||
0a09d5ad45 | |||
3fc442b078 | |||
bd0e31a7dd | |||
dfaf03639a | |||
7081afe8cb | |||
4b6493999a | |||
0172d779d7 | |||
cc5b38ca39 | |||
48351504de | |||
20ff8bbb57 | |||
bc21988fe5 | |||
e3c3e28554 | |||
f053740132 | |||
7a92a31739 | |||
6eca8796fb | |||
8876c0984e | |||
ae0211a84c | |||
a9f696f7bb | |||
2423644d72 | |||
be671e72a3 | |||
f0587d41a9 | |||
cbc4b3f612 | |||
0080ef218e | |||
3aef89b399 | |||
f4e0234af0 | |||
5c22531e4d | |||
3978e33fd0 | |||
a37797ef34 | |||
e3cd271f16 | |||
f0b7b61c16 | |||
ed41fcf3d6 | |||
1fa8fae301 | |||
543a6c4175 | |||
932bafe0f0 | |||
ac857809ab | |||
846274996a | |||
c145a75848 | |||
a81aedeb10 | |||
50952b3243 | |||
4d3600f273 | |||
d6d5f53ff4 | |||
f17aa0438a | |||
38f4027d5e | |||
2cee8d8a2d | |||
cceefafd55 | |||
1c58e9d8d5 | |||
2772b034c6 | |||
1a44cbd62c | |||
73dbe2fd17 | |||
33a23fbfb2 | |||
a2ed1592bd | |||
3d7a473aa9 | |||
228d5f4754 | |||
2cacfb8da4 | |||
d33e736fa3 | |||
3a46a31e09 | |||
e1bcc1c472 | |||
f671ae7364 | |||
b5951e08c6 | |||
490a8f35a4 | |||
94688f21cc | |||
693f2c4842 | |||
9545a295cf | |||
3d649081e5 | |||
32de2cedcc | |||
e7443a2bd8 | |||
10a7ff776c | |||
5ad15b87fa | |||
b166cab9a2 | |||
0f974bf34f | |||
3d7cdeec5f | |||
97953b193e | |||
c046a6b646 | |||
f1fefc257c | |||
6f23ec8203 | |||
23d4544986 | |||
5a4ff5d189 | |||
50ac4a06e8 | |||
003af26499 | |||
aa63058a88 | |||
15d56cdd27 | |||
93d77b0b47 | |||
c8072a1987 | |||
b008290917 | |||
9928c933d8 | |||
ddb3bd2107 | |||
e603c2378d | |||
3ebbd730b5 | |||
1f02626ed6 | |||
fa005fdb95 | |||
5f40cab3e7 | |||
0e89e3714b | |||
6b24125f06 | |||
a589bcac79 | |||
a9dfc97ddc | |||
28774a4359 | |||
b8b5711ee5 | |||
9579e5f5e5 | |||
7f7f6418a3 | |||
ee81967749 | |||
96e0810188 | |||
99bd1bd678 | |||
e7a6a06166 | |||
eca5bb8262 | |||
1312908056 | |||
76b7d7babd | |||
ba802c1c8d | |||
438874e9a8 | |||
8e26f45dee | |||
e2bb3eaaf8 | |||
0de61e7b3a | |||
5b72dceb26 | |||
95699c9ba6 | |||
790066e9a7 | |||
b9e5228e92 | |||
31c8856f53 | |||
d5823ad622 | |||
6736ba9a04 | |||
468d1e3da8 | |||
7aa1d97bba | |||
f768f9c63f | |||
aa83968534 | |||
85eadccc05 | |||
c94fa12d67 | |||
11e02d45fa | |||
ecd53f9add | |||
844b2f49ea | |||
b2ad712644 | |||
65116c3cb0 | |||
147003107a | |||
618b26056c | |||
b828fe7c8d | |||
6c9df528aa | |||
cb8cc57742 | |||
9da19c1108 | |||
ffd9d3b407 | |||
e94ecf4adc | |||
4d3079b908 | |||
70e7a17380 | |||
9518c8e384 | |||
c581284231 | |||
cb1940255a | |||
93d0ec9397 | |||
9c6e7e880a | |||
2d62e29625 | |||
595f33871e | |||
97e1e0efaa | |||
648419467a | |||
6ddb6b2b33 | |||
0008e69a83 | |||
c664785485 | |||
bdf0ef024e | |||
21a3e8790a | |||
e5e8d02934 | |||
7ff0f97811 | |||
596350d1f5 | |||
2cbd3010e4 | |||
3b4aa6bff7 | |||
05a8f16e95 | |||
79d924040a | |||
b4a8eb3315 | |||
4383cce85b | |||
4b7d7cdef2 | |||
97e667ab30 |
5
.gitattributes
vendored
Normal file
5
.gitattributes
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Ignore all tests for archive
|
||||||
|
/test export-ignore
|
||||||
|
/.gitattributes export-ignore
|
||||||
|
/.travis.yml export-ignore
|
||||||
|
/phpunit.xml.dist export-ignore
|
35
.travis.yml
35
.travis.yml
@ -1,10 +1,29 @@
|
|||||||
language: php
|
language: php
|
||||||
|
|
||||||
php:
|
dist: trusty
|
||||||
- 5.6
|
sudo: false
|
||||||
- 5.5
|
|
||||||
- 5.4
|
matrix:
|
||||||
- 5.3
|
include:
|
||||||
- 5.2
|
- php: 5.3
|
||||||
- hhvm
|
dist: precise
|
||||||
|
- php: 5.4
|
||||||
|
- php: 5.5
|
||||||
|
- php: 5.6
|
||||||
|
- php: 7.0
|
||||||
|
- php: 7.1
|
||||||
|
- php: 7.2
|
||||||
|
- php: 7.3
|
||||||
|
- php: 7.4
|
||||||
|
- php: nightly
|
||||||
|
fast_finish: true
|
||||||
|
allow_failures:
|
||||||
|
- php: nightly
|
||||||
|
|
||||||
|
install:
|
||||||
|
- composer install --prefer-dist --no-interaction --no-progress
|
||||||
|
|
||||||
|
script:
|
||||||
|
- vendor/bin/phpunit
|
||||||
|
- vendor/bin/phpunit test/CommonMarkTestWeak.php || true
|
||||||
|
- '[ -z "$TRAVIS_TAG" ] || [ "$TRAVIS_TAG" == "$(php -r "require(\"Parsedown.php\"); echo Parsedown::version;")" ]'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2013 Emanuil Rusev, erusev.com
|
Copyright (c) 2013-2018 Emanuil Rusev, erusev.com
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
@ -17,4 +17,4 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
1163
Parsedown.php
Executable file → Normal file
1163
Parsedown.php
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
62
README.md
62
README.md
@ -1,16 +1,25 @@
|
|||||||
|
> I also make [Caret](https://caret.io?ref=parsedown) - a Markdown editor for Mac and PC.
|
||||||
|
|
||||||
## Parsedown
|
## Parsedown
|
||||||
|
|
||||||
|
[](https://travis-ci.org/erusev/parsedown)
|
||||||
|
<!--[](https://packagist.org/packages/erusev/parsedown)-->
|
||||||
|
|
||||||
Better Markdown Parser in PHP
|
Better Markdown Parser in PHP
|
||||||
|
|
||||||
[[ demo ]](http://parsedown.org/demo)
|
[Demo](http://parsedown.org/demo) |
|
||||||
|
[Benchmarks](http://parsedown.org/speed) |
|
||||||
|
[Tests](http://parsedown.org/tests/) |
|
||||||
|
[Documentation](https://github.com/erusev/parsedown/wiki/)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* [Fast](http://parsedown.org/speed)
|
* One File
|
||||||
* [Consistent](http://parsedown.org/consistency)
|
* No Dependencies
|
||||||
|
* Super Fast
|
||||||
|
* Extensible
|
||||||
* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown)
|
* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown)
|
||||||
* [Tested](http://parsedown.org/tests/) in PHP 5.2, 5.3, 5.4, 5.5, 5.6 and [hhvm](http://www.hhvm.com/)
|
* Tested in 5.3 to 7.1 and in HHVM
|
||||||
* [Extensible](https://github.com/erusev/parsedown/wiki/Writing-Extensions)
|
|
||||||
* [Markdown Extra extension](https://github.com/erusev/parsedown-extra)
|
* [Markdown Extra extension](https://github.com/erusev/parsedown-extra)
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
@ -25,24 +34,53 @@ $Parsedown = new Parsedown();
|
|||||||
echo $Parsedown->text('Hello _Parsedown_!'); # prints: <p>Hello <em>Parsedown</em>!</p>
|
echo $Parsedown->text('Hello _Parsedown_!'); # prints: <p>Hello <em>Parsedown</em>!</p>
|
||||||
```
|
```
|
||||||
|
|
||||||
More examples in [the wiki](https://github.com/erusev/parsedown/wiki/Usage) and in [this video tutorial](http://youtu.be/wYZBY8DEikI).
|
More examples in [the wiki](https://github.com/erusev/parsedown/wiki/) and in [this video tutorial](http://youtu.be/wYZBY8DEikI).
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
Parsedown is capable of escaping user-input within the HTML that it generates. Additionally Parsedown will apply sanitisation to additional scripting vectors (such as scripting link destinations) that are introduced by the markdown syntax itself.
|
||||||
|
|
||||||
|
To tell Parsedown that it is processing untrusted user-input, use the following:
|
||||||
|
```php
|
||||||
|
$parsedown = new Parsedown;
|
||||||
|
$parsedown->setSafeMode(true);
|
||||||
|
```
|
||||||
|
|
||||||
|
If instead, you wish to allow HTML within untrusted user-input, but still want output to be free from XSS it is recommended that you make use of a HTML sanitiser that allows HTML tags to be whitelisted, like [HTML Purifier](http://htmlpurifier.org/).
|
||||||
|
|
||||||
|
In both cases you should strongly consider employing defence-in-depth measures, like [deploying a Content-Security-Policy](https://scotthelme.co.uk/content-security-policy-an-introduction/) (a browser security feature) so that your page is likely to be safe even if an attacker finds a vulnerability in one of the first lines of defence above.
|
||||||
|
|
||||||
|
#### Security of Parsedown Extensions
|
||||||
|
|
||||||
|
Safe mode does not necessarily yield safe results when using extensions to Parsedown. Extensions should be evaluated on their own to determine their specific safety against XSS.
|
||||||
|
|
||||||
|
### Escaping HTML
|
||||||
|
> ⚠️ **WARNING:** This method isn't safe from XSS!
|
||||||
|
|
||||||
|
If you wish to escape HTML **in trusted input**, you can use the following:
|
||||||
|
```php
|
||||||
|
$parsedown = new Parsedown;
|
||||||
|
$parsedown->setMarkupEscaped(true);
|
||||||
|
```
|
||||||
|
|
||||||
|
Beware that this still allows users to insert unsafe scripting vectors, such as links like `[xss](javascript:alert%281%29)`.
|
||||||
|
|
||||||
### Questions
|
### Questions
|
||||||
|
|
||||||
**How does Parsedown work?**
|
**How does Parsedown work?**
|
||||||
|
|
||||||
It tries to read Markdown like a human. First, it looks at the lines. It’s interested in how the lines start. This helps it recognise blocks. It knows, for example, that if a line start with a `-` then it perhaps belong to a list. Once it recognises the blocks, it continues to the content. As it reads, it watches out for special characters. This helps it recognise inline elements (or inlines).
|
It tries to read Markdown like a human. First, it looks at the lines. It’s interested in how the lines start. This helps it recognise blocks. It knows, for example, that if a line starts with a `-` then perhaps it belongs to a list. Once it recognises the blocks, it continues to the content. As it reads, it watches out for special characters. This helps it recognise inline elements (or inlines).
|
||||||
|
|
||||||
We call this approach "line based". We believe that Parsedown is the first Markdown parser to use it. Since the release of Parsedown, other developers have used the same approach to develop other Markdown parsers in PHP and in other languages.
|
We call this approach "line based". We believe that Parsedown is the first Markdown parser to use it. Since the release of Parsedown, other developers have used the same approach to develop other Markdown parsers in PHP and in other languages.
|
||||||
|
|
||||||
**Is Parsedown compliant with CommonMark?**
|
**Is it compliant with CommonMark?**
|
||||||
|
|
||||||
The majority of the CommonMark tests pass. Most of the tests that don't pass deal with cases that are quite extreme. Yet, we are working on them. As CommonMark matures, compliance should improve.
|
It passes most of the CommonMark tests. Most of the tests that don't pass deal with cases that are quite uncommon. Still, as CommonMark matures, compliance should improve.
|
||||||
|
|
||||||
**Who uses Parsedown?**
|
**Who uses it?**
|
||||||
|
|
||||||
[phpDocumentor](http://www.phpdoc.org/), [October CMS](http://octobercms.com/), [Bolt CMS](http://bolt.cm/), [Kirby CMS](http://getkirby.com/), [Grav CMS](http://getgrav.org/), [Statamic CMS](http://www.statamic.com/), [RaspberryPi.org](http://www.raspberrypi.org/) and [more](https://www.versioneye.com/php/erusev:parsedown/references).
|
[Laravel Framework](https://laravel.com/), [Bolt CMS](http://bolt.cm/), [Grav CMS](http://getgrav.org/), [Herbie CMS](http://www.getherbie.org/), [Kirby CMS](http://getkirby.com/), [October CMS](http://octobercms.com/), [Pico CMS](http://picocms.org), [Statamic CMS](http://www.statamic.com/), [phpDocumentor](http://www.phpdoc.org/), [RaspberryPi.org](http://www.raspberrypi.org/), [Symfony demo](https://github.com/symfony/symfony-demo) and [more](https://packagist.org/packages/erusev/parsedown/dependents).
|
||||||
|
|
||||||
**How can I help?**
|
**How can I help?**
|
||||||
|
|
||||||
Use the project, tell friends about it and if you feel generous, [donate some money](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2).
|
Use it, star it, share it and if you feel generous, [donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2).
|
||||||
|
@ -12,7 +12,22 @@
|
|||||||
"homepage": "http://erusev.com"
|
"homepage": "http://erusev.com"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0",
|
||||||
|
"ext-mbstring": "*"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.8.35"
|
||||||
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-0": {"Parsedown": ""}
|
"psr-0": {"Parsedown": ""}
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-0": {
|
||||||
|
"TestParsedown": "test/",
|
||||||
|
"ParsedownTest": "test/",
|
||||||
|
"CommonMarkTest": "test/",
|
||||||
|
"CommonMarkTestWeak": "test/"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<phpunit bootstrap="test/bootstrap.php" colors="true">
|
<phpunit bootstrap="vendor/autoload.php" colors="true">
|
||||||
<testsuites>
|
<testsuites>
|
||||||
<testsuite>
|
<testsuite>
|
||||||
<file>test/ParsedownTest.php</file>
|
<file>test/ParsedownTest.php</file>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
</testsuites>
|
</testsuites>
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test Parsedown against the CommonMark spec.
|
|
||||||
*
|
|
||||||
* Some code based on the original JavaScript test runner by jgm.
|
|
||||||
*
|
|
||||||
* @link http://commonmark.org/ CommonMark
|
|
||||||
* @link http://git.io/8WtRvQ JavaScript test runner
|
|
||||||
*/
|
|
||||||
class CommonMarkTest extends PHPUnit_Framework_TestCase
|
|
||||||
{
|
|
||||||
const SPEC_URL = 'https://raw.githubusercontent.com/jgm/stmd/master/spec.txt';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider data
|
|
||||||
* @param $section
|
|
||||||
* @param $markdown
|
|
||||||
* @param $expectedHtml
|
|
||||||
*/
|
|
||||||
function test_($section, $markdown, $expectedHtml)
|
|
||||||
{
|
|
||||||
$Parsedown = new Parsedown();
|
|
||||||
$Parsedown->setUrlsLinked(false);
|
|
||||||
|
|
||||||
$actualHtml = $Parsedown->text($markdown);
|
|
||||||
$actualHtml = $this->normalizeMarkup($actualHtml);
|
|
||||||
|
|
||||||
$this->assertEquals($expectedHtml, $actualHtml);
|
|
||||||
}
|
|
||||||
|
|
||||||
function data()
|
|
||||||
{
|
|
||||||
$spec = file_get_contents(self::SPEC_URL);
|
|
||||||
$spec = strstr($spec, '<!-- END TESTS -->', true);
|
|
||||||
|
|
||||||
$tests = array();
|
|
||||||
$currentSection = '';
|
|
||||||
|
|
||||||
preg_replace_callback(
|
|
||||||
'/^\.\n([\s\S]*?)^\.\n([\s\S]*?)^\.$|^#{1,6} *(.*)$/m',
|
|
||||||
function($matches) use ( & $tests, & $currentSection, & $testCount) {
|
|
||||||
if (isset($matches[3]) and $matches[3]) {
|
|
||||||
$currentSection = $matches[3];
|
|
||||||
} else {
|
|
||||||
$testCount++;
|
|
||||||
$markdown = $matches[1];
|
|
||||||
$markdown = preg_replace('/→/', "\t", $markdown);
|
|
||||||
$expectedHtml = $matches[2];
|
|
||||||
$expectedHtml = $this->normalizeMarkup($expectedHtml);
|
|
||||||
$tests []= array(
|
|
||||||
$currentSection, # section
|
|
||||||
$markdown, # markdown
|
|
||||||
$expectedHtml, # html
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
$spec
|
|
||||||
);
|
|
||||||
|
|
||||||
return $tests;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function normalizeMarkup($markup)
|
|
||||||
{
|
|
||||||
$markup = preg_replace("/\n+/", "\n", $markup);
|
|
||||||
$markup = preg_replace('/^\s+/m', '', $markup);
|
|
||||||
$markup = preg_replace('/^((?:<[\w]+>)+)\n/m', '$1', $markup);
|
|
||||||
$markup = preg_replace('/\n((?:<\/[\w]+>)+)$/m', '$1', $markup);
|
|
||||||
$markup = trim($markup);
|
|
||||||
|
|
||||||
return $markup;
|
|
||||||
}
|
|
||||||
}
|
|
71
test/CommonMarkTestStrict.php
Normal file
71
test/CommonMarkTestStrict.php
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Parsedown against the CommonMark spec
|
||||||
|
*
|
||||||
|
* @link http://commonmark.org/ CommonMark
|
||||||
|
*/
|
||||||
|
class CommonMarkTestStrict extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
const SPEC_URL = 'https://raw.githubusercontent.com/jgm/CommonMark/master/spec.txt';
|
||||||
|
|
||||||
|
protected $parsedown;
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
$this->parsedown = new TestParsedown();
|
||||||
|
$this->parsedown->setUrlsLinked(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider data
|
||||||
|
* @param $id
|
||||||
|
* @param $section
|
||||||
|
* @param $markdown
|
||||||
|
* @param $expectedHtml
|
||||||
|
*/
|
||||||
|
public function testExample($id, $section, $markdown, $expectedHtml)
|
||||||
|
{
|
||||||
|
$actualHtml = $this->parsedown->text($markdown);
|
||||||
|
$this->assertEquals($expectedHtml, $actualHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function data()
|
||||||
|
{
|
||||||
|
$spec = file_get_contents(self::SPEC_URL);
|
||||||
|
if ($spec === false) {
|
||||||
|
$this->fail('Unable to load CommonMark spec from ' . self::SPEC_URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
$spec = str_replace("\r\n", "\n", $spec);
|
||||||
|
$spec = strstr($spec, '<!-- END TESTS -->', true);
|
||||||
|
|
||||||
|
$matches = array();
|
||||||
|
preg_match_all('/^`{32} example\n((?s).*?)\n\.\n(?:|((?s).*?)\n)`{32}$|^#{1,6} *(.*?)$/m', $spec, $matches, PREG_SET_ORDER);
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
$currentId = 0;
|
||||||
|
$currentSection = '';
|
||||||
|
foreach ($matches as $match) {
|
||||||
|
if (isset($match[3])) {
|
||||||
|
$currentSection = $match[3];
|
||||||
|
} else {
|
||||||
|
$currentId++;
|
||||||
|
$markdown = str_replace('→', "\t", $match[1]);
|
||||||
|
$expectedHtml = isset($match[2]) ? str_replace('→', "\t", $match[2]) : '';
|
||||||
|
|
||||||
|
$data[$currentId] = array(
|
||||||
|
'id' => $currentId,
|
||||||
|
'section' => $currentSection,
|
||||||
|
'markdown' => $markdown,
|
||||||
|
'expectedHtml' => $expectedHtml
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
63
test/CommonMarkTestWeak.php
Normal file
63
test/CommonMarkTestWeak.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
require_once(__DIR__ . '/CommonMarkTestStrict.php');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Parsedown against the CommonMark spec, but less aggressive
|
||||||
|
*
|
||||||
|
* The resulting HTML markup is cleaned up before comparison, so examples
|
||||||
|
* which would normally fail due to actually invisible differences (e.g.
|
||||||
|
* superfluous whitespaces), don't fail. However, cleanup relies on block
|
||||||
|
* element detection. The detection doesn't work correctly when a element's
|
||||||
|
* `display` CSS property is manipulated. According to that this test is only
|
||||||
|
* a interim solution on Parsedown's way to full CommonMark compatibility.
|
||||||
|
*
|
||||||
|
* @link http://commonmark.org/ CommonMark
|
||||||
|
*/
|
||||||
|
class CommonMarkTestWeak extends CommonMarkTestStrict
|
||||||
|
{
|
||||||
|
protected $textLevelElementRegex;
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$textLevelElements = $this->parsedown->getTextLevelElements();
|
||||||
|
array_walk($textLevelElements, function (&$element) {
|
||||||
|
$element = preg_quote($element, '/');
|
||||||
|
});
|
||||||
|
$this->textLevelElementRegex = '\b(?:' . implode('|', $textLevelElements) . ')\b';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider data
|
||||||
|
* @param $id
|
||||||
|
* @param $section
|
||||||
|
* @param $markdown
|
||||||
|
* @param $expectedHtml
|
||||||
|
*/
|
||||||
|
public function testExample($id, $section, $markdown, $expectedHtml)
|
||||||
|
{
|
||||||
|
$expectedHtml = $this->cleanupHtml($expectedHtml);
|
||||||
|
|
||||||
|
$actualHtml = $this->parsedown->text($markdown);
|
||||||
|
$actualHtml = $this->cleanupHtml($actualHtml);
|
||||||
|
|
||||||
|
$this->assertEquals($expectedHtml, $actualHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function cleanupHtml($markup)
|
||||||
|
{
|
||||||
|
// invisible whitespaces at the beginning and end of block elements
|
||||||
|
// however, whitespaces at the beginning of <pre> elements do matter
|
||||||
|
$markup = preg_replace(
|
||||||
|
array(
|
||||||
|
'/(<(?!(?:' . $this->textLevelElementRegex . '|\bpre\b))\w+\b[^>]*>(?:<' . $this->textLevelElementRegex . '[^>]*>)*)\s+/s',
|
||||||
|
'/\s+((?:<\/' . $this->textLevelElementRegex . '>)*<\/(?!' . $this->textLevelElementRegex . ')\w+\b>)/s'
|
||||||
|
),
|
||||||
|
'$1',
|
||||||
|
$markup
|
||||||
|
);
|
||||||
|
|
||||||
|
return $markup;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class ParsedownTest extends PHPUnit_Framework_TestCase
|
require 'SampleExtensions.php';
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class ParsedownTest extends TestCase
|
||||||
{
|
{
|
||||||
final function __construct($name = null, array $data = array(), $dataName = '')
|
final function __construct($name = null, array $data = array(), $dataName = '')
|
||||||
{
|
{
|
||||||
@ -27,7 +31,7 @@ class ParsedownTest extends PHPUnit_Framework_TestCase
|
|||||||
*/
|
*/
|
||||||
protected function initParsedown()
|
protected function initParsedown()
|
||||||
{
|
{
|
||||||
$Parsedown = new Parsedown();
|
$Parsedown = new TestParsedown();
|
||||||
|
|
||||||
return $Parsedown;
|
return $Parsedown;
|
||||||
}
|
}
|
||||||
@ -46,11 +50,47 @@ class ParsedownTest extends PHPUnit_Framework_TestCase
|
|||||||
$expectedMarkup = str_replace("\r\n", "\n", $expectedMarkup);
|
$expectedMarkup = str_replace("\r\n", "\n", $expectedMarkup);
|
||||||
$expectedMarkup = str_replace("\r", "\n", $expectedMarkup);
|
$expectedMarkup = str_replace("\r", "\n", $expectedMarkup);
|
||||||
|
|
||||||
|
$this->Parsedown->setSafeMode(substr($test, 0, 3) === 'xss');
|
||||||
|
|
||||||
$actualMarkup = $this->Parsedown->text($markdown);
|
$actualMarkup = $this->Parsedown->text($markdown);
|
||||||
|
|
||||||
$this->assertEquals($expectedMarkup, $actualMarkup);
|
$this->assertEquals($expectedMarkup, $actualMarkup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testRawHtml()
|
||||||
|
{
|
||||||
|
$markdown = "```php\nfoobar\n```";
|
||||||
|
$expectedMarkup = '<pre><code class="language-php"><p>foobar</p></code></pre>';
|
||||||
|
$expectedSafeMarkup = '<pre><code class="language-php"><p>foobar</p></code></pre>';
|
||||||
|
|
||||||
|
$unsafeExtension = new UnsafeExtension;
|
||||||
|
$actualMarkup = $unsafeExtension->text($markdown);
|
||||||
|
|
||||||
|
$this->assertEquals($expectedMarkup, $actualMarkup);
|
||||||
|
|
||||||
|
$unsafeExtension->setSafeMode(true);
|
||||||
|
$actualSafeMarkup = $unsafeExtension->text($markdown);
|
||||||
|
|
||||||
|
$this->assertEquals($expectedSafeMarkup, $actualSafeMarkup);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testTrustDelegatedRawHtml()
|
||||||
|
{
|
||||||
|
$markdown = "```php\nfoobar\n```";
|
||||||
|
$expectedMarkup = '<pre><code class="language-php"><p>foobar</p></code></pre>';
|
||||||
|
$expectedSafeMarkup = $expectedMarkup;
|
||||||
|
|
||||||
|
$unsafeExtension = new TrustDelegatedExtension;
|
||||||
|
$actualMarkup = $unsafeExtension->text($markdown);
|
||||||
|
|
||||||
|
$this->assertEquals($expectedMarkup, $actualMarkup);
|
||||||
|
|
||||||
|
$unsafeExtension->setSafeMode(true);
|
||||||
|
$actualSafeMarkup = $unsafeExtension->text($markdown);
|
||||||
|
|
||||||
|
$this->assertEquals($expectedSafeMarkup, $actualSafeMarkup);
|
||||||
|
}
|
||||||
|
|
||||||
function data()
|
function data()
|
||||||
{
|
{
|
||||||
$data = array();
|
$data = array();
|
||||||
@ -132,8 +172,27 @@ color: red;
|
|||||||
<p>comment</p>
|
<p>comment</p>
|
||||||
<p><!-- html comment --></p>
|
<p><!-- html comment --></p>
|
||||||
EXPECTED_HTML;
|
EXPECTED_HTML;
|
||||||
$parsedownWithNoMarkup = new Parsedown();
|
|
||||||
|
$parsedownWithNoMarkup = new TestParsedown();
|
||||||
$parsedownWithNoMarkup->setMarkupEscaped(true);
|
$parsedownWithNoMarkup->setMarkupEscaped(true);
|
||||||
$this->assertEquals($expectedHtml, $parsedownWithNoMarkup->text($markdownWithHtml));
|
$this->assertEquals($expectedHtml, $parsedownWithNoMarkup->text($markdownWithHtml));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testLateStaticBinding()
|
||||||
|
{
|
||||||
|
$parsedown = Parsedown::instance();
|
||||||
|
$this->assertInstanceOf('Parsedown', $parsedown);
|
||||||
|
|
||||||
|
// After instance is already called on Parsedown
|
||||||
|
// subsequent calls with the same arguments return the same instance
|
||||||
|
$sameParsedown = TestParsedown::instance();
|
||||||
|
$this->assertInstanceOf('Parsedown', $sameParsedown);
|
||||||
|
$this->assertSame($parsedown, $sameParsedown);
|
||||||
|
|
||||||
|
$testParsedown = TestParsedown::instance('test late static binding');
|
||||||
|
$this->assertInstanceOf('TestParsedown', $testParsedown);
|
||||||
|
|
||||||
|
$sameInstanceAgain = TestParsedown::instance('test late static binding');
|
||||||
|
$this->assertSame($testParsedown, $sameInstanceAgain);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
39
test/SampleExtensions.php
Normal file
39
test/SampleExtensions.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class UnsafeExtension extends Parsedown
|
||||||
|
{
|
||||||
|
protected function blockFencedCodeComplete($Block)
|
||||||
|
{
|
||||||
|
$text = $Block['element']['text']['text'];
|
||||||
|
unset($Block['element']['text']['text']);
|
||||||
|
|
||||||
|
// WARNING: There is almost always a better way of doing things!
|
||||||
|
//
|
||||||
|
// This example is one of them, unsafe behaviour is NOT needed here.
|
||||||
|
// Only use this if you trust the input and have no idea what
|
||||||
|
// the output HTML will look like (e.g. using an external parser).
|
||||||
|
$Block['element']['text']['rawHtml'] = "<p>$text</p>";
|
||||||
|
|
||||||
|
return $Block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TrustDelegatedExtension extends Parsedown
|
||||||
|
{
|
||||||
|
protected function blockFencedCodeComplete($Block)
|
||||||
|
{
|
||||||
|
$text = $Block['element']['text']['text'];
|
||||||
|
unset($Block['element']['text']['text']);
|
||||||
|
|
||||||
|
// WARNING: There is almost always a better way of doing things!
|
||||||
|
//
|
||||||
|
// This behaviour is NOT needed in the demonstrated case.
|
||||||
|
// Only use this if you are sure that the result being added into
|
||||||
|
// rawHtml is safe.
|
||||||
|
// (e.g. using an external parser with escaping capabilities).
|
||||||
|
$Block['element']['text']['rawHtml'] = "<p>$text</p>";
|
||||||
|
$Block['element']['text']['allowRawHtmlInSafeMode'] = true;
|
||||||
|
|
||||||
|
return $Block;
|
||||||
|
}
|
||||||
|
}
|
9
test/TestParsedown.php
Normal file
9
test/TestParsedown.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class TestParsedown extends Parsedown
|
||||||
|
{
|
||||||
|
public function getTextLevelElements()
|
||||||
|
{
|
||||||
|
return $this->textLevelElements;
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
include 'Parsedown.php';
|
|
@ -1,21 +1,21 @@
|
|||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th align="left">header 1</th>
|
<th style="text-align: left;">header 1</th>
|
||||||
<th align="center">header 2</th>
|
<th style="text-align: center;">header 2</th>
|
||||||
<th align="right">header 2</th>
|
<th style="text-align: right;">header 2</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left">cell 1.1</td>
|
<td style="text-align: left;">cell 1.1</td>
|
||||||
<td align="center">cell 1.2</td>
|
<td style="text-align: center;">cell 1.2</td>
|
||||||
<td align="right">cell 1.3</td>
|
<td style="text-align: right;">cell 1.3</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left">cell 2.1</td>
|
<td style="text-align: left;">cell 2.1</td>
|
||||||
<td align="center">cell 2.2</td>
|
<td style="text-align: center;">cell 2.2</td>
|
||||||
<td align="right">cell 2.3</td>
|
<td style="text-align: right;">cell 2.3</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
@ -1,13 +1,12 @@
|
|||||||
<div>_content_</div>
|
<div>_content_</div>
|
||||||
<p>sparse:</p>
|
|
||||||
<div>
|
|
||||||
<div class="inner">
|
|
||||||
_content_
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p>paragraph</p>
|
<p>paragraph</p>
|
||||||
|
<div>
|
||||||
|
<div class="inner">
|
||||||
|
_content_
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
p {
|
p {color: #789;}
|
||||||
color: red;
|
</style>
|
||||||
}
|
<div>
|
||||||
</style>
|
<a href="/">home</a></div>
|
@ -1,17 +1,16 @@
|
|||||||
<div>_content_</div>
|
<div>_content_</div>
|
||||||
|
|
||||||
sparse:
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<div class="inner">
|
|
||||||
_content_
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
paragraph
|
paragraph
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="inner">
|
||||||
|
_content_
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
p {
|
p {color: #789;}
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<a href="/">home</a></div>
|
@ -3,4 +3,11 @@
|
|||||||
$message = 'fenced code block';
|
$message = 'fenced code block';
|
||||||
echo $message;</code></pre>
|
echo $message;</code></pre>
|
||||||
<pre><code>tilde</code></pre>
|
<pre><code>tilde</code></pre>
|
||||||
<pre><code class="language-php">echo 'language identifier';</code></pre>
|
<pre><code class="language-php">echo 'language identifier';</code></pre>
|
||||||
|
<pre><code class="language-c#">echo 'language identifier with non words';</code></pre>
|
||||||
|
<pre><code class="language-html+php"><?php
|
||||||
|
echo "Hello World";
|
||||||
|
?>
|
||||||
|
<a href="http://auraphp.com" >Aura Project</a></code></pre>
|
||||||
|
<pre><code class="language-php"><?php
|
||||||
|
echo "Hello World";</code></pre>
|
@ -11,4 +11,20 @@ tilde
|
|||||||
|
|
||||||
```php
|
```php
|
||||||
echo 'language identifier';
|
echo 'language identifier';
|
||||||
|
```
|
||||||
|
|
||||||
|
```c#
|
||||||
|
echo 'language identifier with non words';
|
||||||
|
```
|
||||||
|
|
||||||
|
```html+php
|
||||||
|
<?php
|
||||||
|
echo "Hello World";
|
||||||
|
?>
|
||||||
|
<a href="http://auraphp.com" >Aura Project</a>
|
||||||
|
```
|
||||||
|
|
||||||
|
```php some-class
|
||||||
|
<?php
|
||||||
|
echo "Hello World";
|
||||||
```
|
```
|
@ -1 +1,2 @@
|
|||||||
<p><img src="/md.png" alt="alt" title="title" /></p>
|
<p><img src="/md.png" alt="alt" title="title" /></p>
|
||||||
|
<p><img src="/md.png" alt="blank title" title="" /></p>
|
@ -1 +1,3 @@
|
|||||||

|

|
||||||
|
|
||||||
|

|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,4 +1,6 @@
|
|||||||
<p><a href="http://example.com" title="Title">single quotes</a></p>
|
<p><a href="http://example.com" title="Title">single quotes</a></p>
|
||||||
<p><a href="http://example.com" title="Title">double quotes</a></p>
|
<p><a href="http://example.com" title="Title">double quotes</a></p>
|
||||||
|
<p><a href="http://example.com" title="">single quotes blank</a></p>
|
||||||
|
<p><a href="http://example.com" title="">double quotes blank</a></p>
|
||||||
<p><a href="http://example.com" title="2 Words">space</a></p>
|
<p><a href="http://example.com" title="2 Words">space</a></p>
|
||||||
<p><a href="http://example.com/url-(parentheses)" title="Title">parentheses</a></p>
|
<p><a href="http://example.com/url-(parentheses)" title="Title">parentheses</a></p>
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
[double quotes](http://example.com "Title")
|
[double quotes](http://example.com "Title")
|
||||||
|
|
||||||
|
[single quotes blank](http://example.com '')
|
||||||
|
|
||||||
|
[double quotes blank](http://example.com "")
|
||||||
|
|
||||||
[space](http://example.com "2 Words")
|
[space](http://example.com "2 Words")
|
||||||
|
|
||||||
[parentheses](http://example.com/url-(parentheses) "Title")
|
[parentheses](http://example.com/url-(parentheses) "Title")
|
10
test/data/multiline_lists.html
Normal file
10
test/data/multiline_lists.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
<p>One
|
||||||
|
First body copy</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Two
|
||||||
|
Last body copy</p>
|
||||||
|
</li>
|
||||||
|
</ol>
|
5
test/data/multiline_lists.md
Normal file
5
test/data/multiline_lists.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
1. One
|
||||||
|
First body copy
|
||||||
|
|
||||||
|
2. Two
|
||||||
|
Last body copy
|
@ -8,6 +8,6 @@
|
|||||||
<li>two</li>
|
<li>two</li>
|
||||||
</ol>
|
</ol>
|
||||||
<p>large numbers:</p>
|
<p>large numbers:</p>
|
||||||
<ol>
|
<ol start="123">
|
||||||
<li>one</li>
|
<li>one</li>
|
||||||
</ol>
|
</ol>
|
@ -8,5 +8,7 @@
|
|||||||
<li>
|
<li>
|
||||||
<p>li</p>
|
<p>li</p>
|
||||||
</li>
|
</li>
|
||||||
<li>li</li>
|
<li>
|
||||||
|
<p>li</p>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
@ -20,17 +20,17 @@
|
|||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th align="left">header 1</th>
|
<th style="text-align: left;">header 1</th>
|
||||||
<th>header 2</th>
|
<th>header 2</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left">cell 1.1</td>
|
<td style="text-align: left;">cell 1.1</td>
|
||||||
<td>cell 1.2</td>
|
<td>cell 1.2</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="left">cell 2.1</td>
|
<td style="text-align: left;">cell 2.1</td>
|
||||||
<td>cell 2.2</td>
|
<td>cell 2.2</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
<li>
|
<li>
|
||||||
<p>li</p>
|
<p>li</p>
|
||||||
</li>
|
</li>
|
||||||
<li>li</li>
|
<li>
|
||||||
<li>li</li>
|
<p>li</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>li</p>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
@ -2,7 +2,9 @@
|
|||||||
<li>
|
<li>
|
||||||
<p>li</p>
|
<p>li</p>
|
||||||
</li>
|
</li>
|
||||||
<li>li</li>
|
<li>
|
||||||
|
<p>li</p>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<hr />
|
<hr />
|
||||||
<ul>
|
<ul>
|
||||||
|
6
test/data/xss_attribute_encoding.html
Normal file
6
test/data/xss_attribute_encoding.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<p><a href="https://www.example.com"">xss</a></p>
|
||||||
|
<p><img src="https://www.example.com"" alt="xss" /></p>
|
||||||
|
<p><a href="https://www.example.com'">xss</a></p>
|
||||||
|
<p><img src="https://www.example.com'" alt="xss" /></p>
|
||||||
|
<p><img src="https://www.example.com" alt="xss"" /></p>
|
||||||
|
<p><img src="https://www.example.com" alt="xss'" /></p>
|
11
test/data/xss_attribute_encoding.md
Normal file
11
test/data/xss_attribute_encoding.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[xss](https://www.example.com")
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
[xss](https://www.example.com')
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
16
test/data/xss_bad_url.html
Normal file
16
test/data/xss_bad_url.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<p><a href="javascript%3Aalert(1)">xss</a></p>
|
||||||
|
<p><a href="javascript%3Aalert(1)">xss</a></p>
|
||||||
|
<p><a href="javascript%3A//alert(1)">xss</a></p>
|
||||||
|
<p><a href="javascript&colon;alert(1)">xss</a></p>
|
||||||
|
<p><img src="javascript%3Aalert(1)" alt="xss" /></p>
|
||||||
|
<p><img src="javascript%3Aalert(1)" alt="xss" /></p>
|
||||||
|
<p><img src="javascript%3A//alert(1)" alt="xss" /></p>
|
||||||
|
<p><img src="javascript&colon;alert(1)" alt="xss" /></p>
|
||||||
|
<p><a href="data%3Atext/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">xss</a></p>
|
||||||
|
<p><a href="data%3Atext/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">xss</a></p>
|
||||||
|
<p><a href="data%3A//text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">xss</a></p>
|
||||||
|
<p><a href="data&colon;text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">xss</a></p>
|
||||||
|
<p><img src="data%3Atext/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==" alt="xss" /></p>
|
||||||
|
<p><img src="data%3Atext/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==" alt="xss" /></p>
|
||||||
|
<p><img src="data%3A//text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==" alt="xss" /></p>
|
||||||
|
<p><img src="data&colon;text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==" alt="xss" /></p>
|
31
test/data/xss_bad_url.md
Normal file
31
test/data/xss_bad_url.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
[xss](javascript:alert(1))
|
||||||
|
|
||||||
|
[xss]( javascript:alert(1))
|
||||||
|
|
||||||
|
[xss](javascript://alert(1))
|
||||||
|
|
||||||
|
[xss](javascript:alert(1))
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
[xss](data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
|
||||||
|
|
||||||
|
[xss]( data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
|
||||||
|
|
||||||
|
[xss](data://text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
|
||||||
|
|
||||||
|
[xss](data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
7
test/data/xss_text_encoding.html
Normal file
7
test/data/xss_text_encoding.html
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<p><script>alert(1)</script></p>
|
||||||
|
<p><script></p>
|
||||||
|
<p>alert(1)</p>
|
||||||
|
<p></script></p>
|
||||||
|
<p><script>
|
||||||
|
alert(1)
|
||||||
|
</script></p>
|
12
test/data/xss_text_encoding.md
Normal file
12
test/data/xss_text_encoding.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<script>alert(1)</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
alert(1)
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
alert(1)
|
||||||
|
</script>
|
Reference in New Issue
Block a user