mirror of
https://github.com/erusev/parsedown.git
synced 2023-08-10 21:13:06 +03:00
Merge branch 'master' into master
This commit is contained in:
commit
07e3b4c123
6
.gitattributes
vendored
Normal file
6
.gitattributes
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
# Ignore all tests for archive
|
||||
/test export-ignore
|
||||
/.gitattributes export-ignore
|
||||
/.gitignore export-ignore
|
||||
/.travis.yml export-ignore
|
||||
/phpunit.xml.dist export-ignore
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
composer.lock
|
||||
vendor/
|
31
.travis.yml
31
.travis.yml
@ -1,15 +1,30 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 7.0
|
||||
- 5.6
|
||||
- 5.5
|
||||
- 5.4
|
||||
- 5.3
|
||||
- hhvm
|
||||
- hhvm-nightly
|
||||
dist: trusty
|
||||
sudo: false
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- php: 5.3
|
||||
dist: precise
|
||||
- php: 5.4
|
||||
- php: 5.5
|
||||
- php: 5.6
|
||||
- php: 7.0
|
||||
- php: 7.1
|
||||
- php: 7.2
|
||||
- php: nightly
|
||||
- php: hhvm
|
||||
- php: hhvm-nightly
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- php: nightly
|
||||
- php: hhvm-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)
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
1393
Parsedown.php
1393
Parsedown.php
File diff suppressed because it is too large
Load Diff
54
README.md
54
README.md
@ -1,4 +1,4 @@
|
||||
> You might also like [Caret](http://caret.io?ref=parsedown) - our Markdown editor for Mac / Windows / Linux.
|
||||
> I also make [Caret](https://caret.io?ref=parsedown) - a Markdown editor for Mac and PC.
|
||||
|
||||
## Parsedown
|
||||
|
||||
@ -14,15 +14,26 @@ Better Markdown Parser in PHP
|
||||
|
||||
### Features
|
||||
|
||||
* One File
|
||||
* No Dependencies
|
||||
* Super Fast
|
||||
* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown)
|
||||
* Extensible
|
||||
* Tested in 5.3 to 7.0 and in HHVM
|
||||
* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown)
|
||||
* Tested in 5.3 to 7.2 and in HHVM
|
||||
* [Markdown Extra extension](https://github.com/erusev/parsedown-extra)
|
||||
|
||||
### Installation
|
||||
#### Composer
|
||||
Install the [composer package] by running the following command:
|
||||
|
||||
Include `Parsedown.php` or install [the composer package](https://packagist.org/packages/erusev/parsedown).
|
||||
composer require erusev/parsedown
|
||||
|
||||
#### Manual
|
||||
1. Download the "Source code" from the [latest release]
|
||||
2. Include `Parsedown.php`
|
||||
|
||||
[composer package]: https://packagist.org/packages/erusev/parsedown "The Parsedown package on packagist.org"
|
||||
[latest release]: https://github.com/erusev/parsedown/releases/latest "The latest release of Parsedown"
|
||||
|
||||
### Example
|
||||
|
||||
@ -30,15 +41,46 @@ Include `Parsedown.php` or install [the composer package](https://packagist.org/
|
||||
$Parsedown = new Parsedown();
|
||||
|
||||
echo $Parsedown->text('Hello _Parsedown_!'); # prints: <p>Hello <em>Parsedown</em>!</p>
|
||||
// you can also parse inline markdown only
|
||||
echo $Parsedown->line('Hello _Parsedown_!'); # prints: Hello <em>Parsedown</em>!
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
**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.
|
||||
|
||||
@ -48,7 +90,7 @@ It passes most of the CommonMark tests. Most of the tests that don't pass deal w
|
||||
|
||||
**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/), [Herbie CMS](http://www.getherbie.org/), [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?**
|
||||
|
||||
|
@ -13,9 +13,21 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
"php": ">=5.3.0",
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35"
|
||||
},
|
||||
"autoload": {
|
||||
"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"?>
|
||||
<phpunit bootstrap="test/bootstrap.php" colors="true">
|
||||
<phpunit bootstrap="vendor/autoload.php" colors="true">
|
||||
<testsuites>
|
||||
<testsuite>
|
||||
<file>test/ParsedownTest.php</file>
|
||||
</testsuite>
|
||||
</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;
|
||||
}
|
||||
}
|
56
test/ParsedownTest.php
Normal file → Executable file
56
test/ParsedownTest.php
Normal file → Executable file
@ -1,6 +1,9 @@
|
||||
<?php
|
||||
require 'SampleExtensions.php';
|
||||
|
||||
class ParsedownTest extends PHPUnit_Framework_TestCase
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ParsedownTest extends TestCase
|
||||
{
|
||||
final function __construct($name = null, array $data = array(), $dataName = '')
|
||||
{
|
||||
@ -10,7 +13,8 @@ class ParsedownTest extends PHPUnit_Framework_TestCase
|
||||
parent::__construct($name, $data, $dataName);
|
||||
}
|
||||
|
||||
private $dirs, $Parsedown;
|
||||
private $dirs;
|
||||
protected $Parsedown;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
@ -27,7 +31,7 @@ class ParsedownTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
protected function initParsedown()
|
||||
{
|
||||
$Parsedown = new Parsedown();
|
||||
$Parsedown = new TestParsedown();
|
||||
|
||||
return $Parsedown;
|
||||
}
|
||||
@ -46,11 +50,48 @@ class ParsedownTest extends PHPUnit_Framework_TestCase
|
||||
$expectedMarkup = str_replace("\r\n", "\n", $expectedMarkup);
|
||||
$expectedMarkup = str_replace("\r", "\n", $expectedMarkup);
|
||||
|
||||
$this->Parsedown->setSafeMode(substr($test, 0, 3) === 'xss');
|
||||
$this->Parsedown->setStrictMode(substr($test, 0, 6) === 'strict');
|
||||
|
||||
$actualMarkup = $this->Parsedown->text($markdown);
|
||||
|
||||
$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()
|
||||
{
|
||||
$data = array();
|
||||
@ -119,12 +160,12 @@ MARKDOWN_WITH_MARKUP;
|
||||
<p><div><em>content</em></div></p>
|
||||
<p>sparse:</p>
|
||||
<p><div>
|
||||
<div class="inner">
|
||||
<div class="inner">
|
||||
<em>content</em>
|
||||
</div>
|
||||
</div></p>
|
||||
<p>paragraph</p>
|
||||
<p><style type="text/css">
|
||||
<p><style type="text/css">
|
||||
p {
|
||||
color: red;
|
||||
}
|
||||
@ -132,15 +173,14 @@ color: red;
|
||||
<p>comment</p>
|
||||
<p><!-- html comment --></p>
|
||||
EXPECTED_HTML;
|
||||
$parsedownWithNoMarkup = new Parsedown();
|
||||
|
||||
$parsedownWithNoMarkup = new TestParsedown();
|
||||
$parsedownWithNoMarkup->setMarkupEscaped(true);
|
||||
$this->assertEquals($expectedHtml, $parsedownWithNoMarkup->text($markdownWithHtml));
|
||||
}
|
||||
|
||||
public function testLateStaticBinding()
|
||||
{
|
||||
include 'test/TestParsedown.php';
|
||||
|
||||
$parsedown = Parsedown::instance();
|
||||
$this->assertInstanceOf('Parsedown', $parsedown);
|
||||
|
||||
|
40
test/SampleExtensions.php
Normal file
40
test/SampleExtensions.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
class UnsafeExtension extends Parsedown
|
||||
{
|
||||
protected function blockFencedCodeComplete($Block)
|
||||
{
|
||||
$text = $Block['element']['element']['text'];
|
||||
unset($Block['element']['element']['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']['element']['rawHtml'] = "<p>$text</p>";
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class TrustDelegatedExtension extends Parsedown
|
||||
{
|
||||
protected function blockFencedCodeComplete($Block)
|
||||
{
|
||||
$text = $Block['element']['element']['text'];
|
||||
unset($Block['element']['element']['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']['element']['rawHtml'] = "<p>$text</p>";
|
||||
$Block['element']['element']['allowRawHtmlInSafeMode'] = true;
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
@ -2,4 +2,8 @@
|
||||
|
||||
class TestParsedown extends Parsedown
|
||||
{
|
||||
public function getTextLevelElements()
|
||||
{
|
||||
return $this->textLevelElements;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +0,0 @@
|
||||
<?php
|
||||
|
||||
include 'Parsedown.php';
|
@ -6,4 +6,8 @@
|
||||
<h6>h6</h6>
|
||||
<p>####### not a heading</p>
|
||||
<h1>closed h1</h1>
|
||||
<p>#</p>
|
||||
<h1></h1>
|
||||
<h2></h2>
|
||||
<h1># of levels</h1>
|
||||
<h1># of levels #</h1>
|
||||
<h1>heading</h1>
|
@ -14,4 +14,12 @@
|
||||
|
||||
# closed h1 #
|
||||
|
||||
#
|
||||
#
|
||||
|
||||
##
|
||||
|
||||
# # of levels
|
||||
|
||||
# # of levels # #
|
||||
|
||||
#heading
|
@ -5,4 +5,9 @@ echo $message;</code></pre>
|
||||
<hr />
|
||||
<pre><code>> not a quote
|
||||
- not a list item
|
||||
[not a reference]: http://foo.com</code></pre>
|
||||
[not a reference]: http://foo.com</code></pre>
|
||||
<hr />
|
||||
<pre><code>foo
|
||||
|
||||
|
||||
bar</code></pre>
|
@ -7,4 +7,11 @@
|
||||
|
||||
> not a quote
|
||||
- not a list item
|
||||
[not a reference]: http://foo.com
|
||||
[not a reference]: http://foo.com
|
||||
|
||||
---
|
||||
|
||||
foo
|
||||
|
||||
|
||||
bar
|
@ -1,12 +1,40 @@
|
||||
<ul>
|
||||
<li>li
|
||||
<li>li<ul>
|
||||
<li>li<ul>
|
||||
<li>li</li>
|
||||
<li>li</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>li</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>li</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<ul>
|
||||
<li>li
|
||||
<li>level 1<ul>
|
||||
<li>level 2<ul>
|
||||
<li>level 3<ul>
|
||||
<li>level 4<ul>
|
||||
<li>level 5</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<ul>
|
||||
<li>li</li>
|
||||
<li>li</li>
|
||||
</ul></li>
|
||||
<li>li</li>
|
||||
</ul></li>
|
||||
<li>li</li>
|
||||
<li>a</li>
|
||||
<li>b</li>
|
||||
<li>c</li>
|
||||
<li>d</li>
|
||||
<li>e</li>
|
||||
<li>f</li>
|
||||
<li>g</li>
|
||||
<li>h</li>
|
||||
<li>i</li>
|
||||
</ul>
|
@ -3,4 +3,24 @@
|
||||
- li
|
||||
- li
|
||||
- li
|
||||
- li
|
||||
- li
|
||||
|
||||
---
|
||||
|
||||
- level 1
|
||||
- level 2
|
||||
- level 3
|
||||
- level 4
|
||||
- level 5
|
||||
|
||||
---
|
||||
|
||||
- a
|
||||
- b
|
||||
- c
|
||||
- d
|
||||
- e
|
||||
- f
|
||||
- g
|
||||
- h
|
||||
- i
|
@ -1 +1,2 @@
|
||||
<p>my email is <a href="mailto:me@example.com">me@example.com</a></p>
|
||||
<p>my email is <a href="mailto:me@example.com">me@example.com</a></p>
|
||||
<p>html tags shouldn't start an email autolink <strong>first.last@example.com</strong></p>
|
@ -1 +1,3 @@
|
||||
my email is <me@example.com>
|
||||
my email is <me@example.com>
|
||||
|
||||
html tags shouldn't start an email autolink <strong>first.last@example.com</strong>
|
@ -3,4 +3,16 @@
|
||||
$message = 'fenced code block';
|
||||
echo $message;</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>the following isn't quite enough to close
|
||||
```
|
||||
still a fenced code block</code></pre>
|
||||
<pre><code>foo
|
||||
|
||||
|
||||
bar</code></pre>
|
@ -11,4 +11,28 @@ tilde
|
||||
|
||||
```php
|
||||
echo 'language identifier';
|
||||
```
|
||||
|
||||
```c#
|
||||
echo 'language identifier with non words';
|
||||
```
|
||||
|
||||
```html+php
|
||||
<?php
|
||||
echo "Hello World";
|
||||
?>
|
||||
<a href="http://auraphp.com" >Aura Project</a>
|
||||
```
|
||||
|
||||
````
|
||||
the following isn't quite enough to close
|
||||
```
|
||||
still a fenced code block
|
||||
````
|
||||
|
||||
```
|
||||
foo
|
||||
|
||||
|
||||
bar
|
||||
```
|
@ -2,4 +2,10 @@
|
||||
<p>paragraph</p>
|
||||
<!--
|
||||
multiline -->
|
||||
<p>paragraph</p>
|
||||
<p>paragraph</p>
|
||||
<!-- sss -->abc
|
||||
<ul>
|
||||
<li>abcd</li>
|
||||
<li>bbbb</li>
|
||||
<li>cccc</li>
|
||||
</ul>
|
@ -5,4 +5,10 @@ paragraph
|
||||
<!--
|
||||
multiline -->
|
||||
|
||||
paragraph
|
||||
paragraph
|
||||
|
||||
<!-- sss -->abc
|
||||
|
||||
* abcd
|
||||
* bbbb
|
||||
* cccc
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,6 +1,8 @@
|
||||
<blockquote>
|
||||
<p>quote
|
||||
the rest of it</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>another paragraph
|
||||
the rest of it</p>
|
||||
</blockquote>
|
3
test/data/markup_consecutive_one.html
Normal file
3
test/data/markup_consecutive_one.html
Normal file
@ -0,0 +1,3 @@
|
||||
<div>Markup</div>
|
||||
_No markdown_ without blank line for **strict** compliance with CommonMark.
|
||||
<p><strong>Markdown</strong></p>
|
4
test/data/markup_consecutive_one.md
Normal file
4
test/data/markup_consecutive_one.md
Normal file
@ -0,0 +1,4 @@
|
||||
<div>Markup</div>
|
||||
_No markdown_ without blank line for **strict** compliance with CommonMark.
|
||||
|
||||
**Markdown**
|
4
test/data/markup_consecutive_one_line.html
Normal file
4
test/data/markup_consecutive_one_line.html
Normal file
@ -0,0 +1,4 @@
|
||||
<div>One markup on
|
||||
two lines</div>
|
||||
_No markdown_
|
||||
<p><strong>Markdown</strong></p>
|
5
test/data/markup_consecutive_one_line.md
Normal file
5
test/data/markup_consecutive_one_line.md
Normal file
@ -0,0 +1,5 @@
|
||||
<div>One markup on
|
||||
two lines</div>
|
||||
_No markdown_
|
||||
|
||||
**Markdown**
|
3
test/data/markup_consecutive_one_stripped.html
Normal file
3
test/data/markup_consecutive_one_stripped.html
Normal file
@ -0,0 +1,3 @@
|
||||
<div><p>Stripped markup</p></div>
|
||||
_No markdown_
|
||||
<p><strong>Markdown</strong></p>
|
4
test/data/markup_consecutive_one_stripped.md
Normal file
4
test/data/markup_consecutive_one_stripped.md
Normal file
@ -0,0 +1,4 @@
|
||||
<div><p>Stripped markup</p></div>
|
||||
_No markdown_
|
||||
|
||||
**Markdown**
|
3
test/data/markup_consecutive_two.html
Normal file
3
test/data/markup_consecutive_two.html
Normal file
@ -0,0 +1,3 @@
|
||||
<div>First markup</div><p>and second markup on the same line.</p>
|
||||
_No markdown_
|
||||
<p><strong>Markdown</strong></p>
|
4
test/data/markup_consecutive_two.md
Normal file
4
test/data/markup_consecutive_two.md
Normal file
@ -0,0 +1,4 @@
|
||||
<div>First markup</div><p>and second markup on the same line.</p>
|
||||
_No markdown_
|
||||
|
||||
**Markdown**
|
4
test/data/markup_consecutive_two_lines.html
Normal file
4
test/data/markup_consecutive_two_lines.html
Normal file
@ -0,0 +1,4 @@
|
||||
<div>First markup</div><p>and partial markup
|
||||
on two lines.</p>
|
||||
_No markdown_
|
||||
<p><strong>Markdown</strong></p>
|
5
test/data/markup_consecutive_two_lines.md
Normal file
5
test/data/markup_consecutive_two_lines.md
Normal file
@ -0,0 +1,5 @@
|
||||
<div>First markup</div><p>and partial markup
|
||||
on two lines.</p>
|
||||
_No markdown_
|
||||
|
||||
**Markdown**
|
4
test/data/markup_consecutive_two_stripped.html
Normal file
4
test/data/markup_consecutive_two_stripped.html
Normal file
@ -0,0 +1,4 @@
|
||||
<div><p>Stripped markup
|
||||
on two lines</p></div>
|
||||
_No markdown_
|
||||
<p><strong>Markdown</strong></p>
|
5
test/data/markup_consecutive_two_stripped.md
Normal file
5
test/data/markup_consecutive_two_stripped.md
Normal file
@ -0,0 +1,5 @@
|
||||
<div><p>Stripped markup
|
||||
on two lines</p></div>
|
||||
_No markdown_
|
||||
|
||||
**Markdown**
|
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,9 @@
|
||||
<li>two</li>
|
||||
</ol>
|
||||
<p>large numbers:</p>
|
||||
<ol>
|
||||
<ol start="123">
|
||||
<li>one</li>
|
||||
</ol>
|
||||
</ol>
|
||||
<p>foo 1. the following should not start a list
|
||||
100.<br />
|
||||
200. </p>
|
@ -8,4 +8,8 @@ repeating numbers:
|
||||
|
||||
large numbers:
|
||||
|
||||
123. one
|
||||
123. one
|
||||
|
||||
foo 1. the following should not start a list
|
||||
100.
|
||||
200.
|
@ -8,5 +8,7 @@
|
||||
<li>
|
||||
<p>li</p>
|
||||
</li>
|
||||
<li>li</li>
|
||||
<li>
|
||||
<p>li</p>
|
||||
</li>
|
||||
</ul>
|
@ -1,12 +1,18 @@
|
||||
<hr>
|
||||
|
||||
paragraph
|
||||
<hr/>
|
||||
|
||||
paragraph
|
||||
<hr />
|
||||
|
||||
paragraph
|
||||
<hr class="foo" id="bar" />
|
||||
|
||||
paragraph
|
||||
<hr class="foo" id="bar"/>
|
||||
|
||||
paragraph
|
||||
<hr class="foo" id="bar" >
|
||||
|
||||
paragraph
|
12
test/data/setext_header_spaces.html
Normal file
12
test/data/setext_header_spaces.html
Normal file
@ -0,0 +1,12 @@
|
||||
<h1>trailing space</h1>
|
||||
<h2>trailing space</h2>
|
||||
<h1>leading and trailing space</h1>
|
||||
<h2>leading and trailing space</h2>
|
||||
<h1>1 leading space</h1>
|
||||
<h2>1 leading space</h2>
|
||||
<h1>3 leading spaces</h1>
|
||||
<h2>3 leading spaces</h2>
|
||||
<p>too many leading spaces
|
||||
==</p>
|
||||
<p>too many leading spaces
|
||||
--</p>
|
29
test/data/setext_header_spaces.md
Normal file
29
test/data/setext_header_spaces.md
Normal file
@ -0,0 +1,29 @@
|
||||
trailing space
|
||||
==
|
||||
|
||||
trailing space
|
||||
--
|
||||
|
||||
leading and trailing space
|
||||
==
|
||||
|
||||
leading and trailing space
|
||||
--
|
||||
|
||||
1 leading space
|
||||
==
|
||||
|
||||
1 leading space
|
||||
--
|
||||
|
||||
3 leading spaces
|
||||
==
|
||||
|
||||
3 leading spaces
|
||||
--
|
||||
|
||||
too many leading spaces
|
||||
==
|
||||
|
||||
too many leading spaces
|
||||
--
|
@ -8,4 +8,19 @@
|
||||
<p>no space after <code>></code>:</p>
|
||||
<blockquote>
|
||||
<p>quote</p>
|
||||
</blockquote>
|
||||
<hr />
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<p>Info 1 text</p>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<p>Info 2 text</p>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
@ -4,4 +4,10 @@ indented:
|
||||
> quote
|
||||
|
||||
no space after `>`:
|
||||
>quote
|
||||
>quote
|
||||
|
||||
---
|
||||
|
||||
>>> Info 1 text
|
||||
|
||||
>>> Info 2 text
|
@ -34,4 +34,42 @@
|
||||
<td>cell 2.2</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
<hr />
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align: left;">header 1</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align: left;">cell 1.1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: left;">cell 2.1</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>header 1</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>cell 1.1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>cell 2.1</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
<p>Not a table, we haven't ended the paragraph:
|
||||
header 1 | header 2
|
||||
-------- | --------
|
||||
cell 1.1 | cell 1.2
|
||||
cell 2.1 | cell 2.2</p>
|
@ -8,4 +8,26 @@ cell 2.1 | cell 2.2
|
||||
header 1 | header 2
|
||||
:------- | --------
|
||||
cell 1.1 | cell 1.2
|
||||
cell 2.1 | cell 2.2
|
||||
|
||||
---
|
||||
|
||||
header 1
|
||||
:-------
|
||||
cell 1.1
|
||||
cell 2.1
|
||||
|
||||
---
|
||||
|
||||
header 1
|
||||
-------|
|
||||
cell 1.1
|
||||
cell 2.1
|
||||
|
||||
---
|
||||
|
||||
Not a table, we haven't ended the paragraph:
|
||||
header 1 | header 2
|
||||
-------- | --------
|
||||
cell 1.1 | cell 1.2
|
||||
cell 2.1 | cell 2.2
|
@ -2,6 +2,10 @@
|
||||
<li>
|
||||
<p>li</p>
|
||||
</li>
|
||||
<li>li</li>
|
||||
<li>li</li>
|
||||
<li>
|
||||
<p>li</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>li</p>
|
||||
</li>
|
||||
</ul>
|
@ -1,8 +1,6 @@
|
||||
<div>
|
||||
line 1
|
||||
|
||||
line 2
|
||||
line 3
|
||||
|
||||
line 4
|
||||
<p>line 2
|
||||
line 3</p>
|
||||
<p>line 4</p>
|
||||
</div>
|
@ -2,7 +2,9 @@
|
||||
<li>
|
||||
<p>li</p>
|
||||
</li>
|
||||
<li>li</li>
|
||||
<li>
|
||||
<p>li</p>
|
||||
</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<ul>
|
||||
|
13
test/data/strict_atx_heading.html
Normal file
13
test/data/strict_atx_heading.html
Normal file
@ -0,0 +1,13 @@
|
||||
<h1>h1</h1>
|
||||
<h2>h2</h2>
|
||||
<h3>h3</h3>
|
||||
<h4>h4</h4>
|
||||
<h5>h5</h5>
|
||||
<h6>h6</h6>
|
||||
<p>####### not a heading</p>
|
||||
<p>#not a heading</p>
|
||||
<h1>closed h1</h1>
|
||||
<h1></h1>
|
||||
<h2></h2>
|
||||
<h1># of levels</h1>
|
||||
<h1># of levels #</h1>
|
25
test/data/strict_atx_heading.md
Normal file
25
test/data/strict_atx_heading.md
Normal file
@ -0,0 +1,25 @@
|
||||
# h1
|
||||
|
||||
## h2
|
||||
|
||||
### h3
|
||||
|
||||
#### h4
|
||||
|
||||
##### h5
|
||||
|
||||
###### h6
|
||||
|
||||
####### not a heading
|
||||
|
||||
#not a heading
|
||||
|
||||
# closed h1 #
|
||||
|
||||
#
|
||||
|
||||
##
|
||||
|
||||
# # of levels
|
||||
|
||||
# # of levels # #
|
@ -1,3 +1,4 @@
|
||||
<p><del>strikethrough</del></p>
|
||||
<p>here's <del>one</del> followed by <del>another one</del></p>
|
||||
<p>~~ this ~~ is not one neither is ~this~</p>
|
||||
<p>~~ this ~~ is not one neither is ~this~</p>
|
||||
<p>escaped ~~this~~</p>
|
@ -2,4 +2,6 @@
|
||||
|
||||
here's ~~one~~ followed by ~~another one~~
|
||||
|
||||
~~ this ~~ is not one neither is ~this~
|
||||
~~ this ~~ is not one neither is ~this~
|
||||
|
||||
escaped \~\~this\~\~
|
@ -2,9 +2,21 @@
|
||||
<li>li</li>
|
||||
<li>li</li>
|
||||
</ul>
|
||||
<p>mixed markers:</p>
|
||||
<p>mixed unordered markers:</p>
|
||||
<ul>
|
||||
<li>li</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>li</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>li</li>
|
||||
</ul>
|
||||
</ul>
|
||||
<p>mixed ordered markers:</p>
|
||||
<ol>
|
||||
<li>starting at 1, list one</li>
|
||||
<li>number 2, list one</li>
|
||||
</ol>
|
||||
<ol start="3">
|
||||
<li>starting at 3, list two</li>
|
||||
</ol>
|
@ -1,8 +1,14 @@
|
||||
- li
|
||||
- li
|
||||
|
||||
mixed markers:
|
||||
mixed unordered markers:
|
||||
|
||||
* li
|
||||
+ li
|
||||
- li
|
||||
- li
|
||||
|
||||
mixed ordered markers:
|
||||
|
||||
1. starting at 1, list one
|
||||
2. number 2, list one
|
||||
3) starting at 3, list two
|
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")
|
||||
|
||||
[xss](https://www.example.com')
|
||||
|
||||
![xss](https://www.example.com')
|
||||
|
||||
![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](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==)
|
||||
|
||||
![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>
|
Loading…
Reference in New Issue
Block a user