1
0
mirror of https://github.com/erusev/parsedown.git synced 2023-08-10 21:13:06 +03:00

Compare commits

..

267 Commits

Author SHA1 Message Date
1f69f7e697 Bump version 2018-05-08 22:46:15 +01:00
c83af0a7d5 Merge pull request #628 from aidantwoods/fix/revert-rawHtml-breaks-insertion
Preserve plain-text in AST to avoid blinding extensions to it
2018-05-08 22:41:44 +01:00
4686daf8c2 Preserve plain-text in AST to avoid blinding extensions to it 2018-05-08 22:32:57 +01:00
c9e7183cfa Merge pull request #627 from aidantwoods/fix/hidden-blocks
Intepret special "hidden" key as an empty element
2018-05-08 22:07:51 +01:00
9eed1104e7 Intepret special "hidden" key as an empty element 2018-05-08 21:54:30 +01:00
fd95703da5 Version bump 2018-05-07 14:26:12 +01:00
8d172a2994 Merge pull request #614 from aidantwoods/enhancement/performance-tweaks
General and performance tweaks
2018-05-07 11:18:21 +01:00
dfab7240a4 Merge pull request #621 from paukenba/master
Tilde characters may be escaped
2018-04-24 17:39:09 +01:00
113c6d2b21 Tilde characters may be escaped 2018-04-23 15:09:30 +02:00
a9764ec90f Remove complex string interpolation expressions 2018-04-14 15:27:06 +01:00
0a842fb5b1 Merge pull request #615 from aidantwoods/fix/old-handler-compat
Compatability fixes
2018-04-12 22:29:29 +01:00
7f4318dbdb PHP 5.3 == 💩 2018-04-12 22:22:53 +01:00
3e70819a20 Readability improvements, thanks @PhrozenByte 2018-04-12 22:16:25 +01:00
2bf7ca41a0 Add compat for extensions using old markup key. 2018-04-12 21:25:50 +01:00
b75fd409ff Must unset text key so that our destination is preferred as content 2018-04-12 21:10:09 +01:00
88a3f31dd7 Rewrite as one statement 2018-04-12 19:33:01 +01:00
726d4ef44a Sanity checks before starting regex engine 2018-04-09 18:09:45 +01:00
450a74fedf More expensive statement last 2018-04-09 18:09:45 +01:00
7e15d99d90 Remove regex from block rule 2018-04-09 18:09:44 +01:00
d2dd736e1b Remove regex from fenced code block
Also remove unused function
2018-04-09 18:09:44 +01:00
e74a5bd7ed In theory PHP stores the length of strings, so looking this up should be quick 2018-04-09 18:09:44 +01:00
b53aa74a72 Use standard library function 2018-04-09 18:09:44 +01:00
3ea08140b6 Remove use of array 2018-04-09 18:09:44 +01:00
c45e41950f Use standard library over while loop 2018-04-09 18:09:44 +01:00
2faba6fef5 Remove unneeded complete function 2018-04-09 18:09:44 +01:00
b42add3762 Make some regexes possesive 2018-04-09 18:09:43 +01:00
107223d3a0 Avoid recomputation 2018-04-09 18:09:43 +01:00
d4f1ac465c String interpolation is slightly faster than concat 2018-04-09 18:09:43 +01:00
d6e306d620 Optimise commonly used regexes to fail fast 2018-04-09 18:09:04 +01:00
dc5cf8770b The AST has high complexity here (and so traversal is hard anyway)
We gain quite a bit of a speed boost by working with text here
since this is a very common function
2018-04-09 18:09:04 +01:00
70f5c02d47 Use non-nestable values as keys for O(1) lookup 2018-04-09 18:09:04 +01:00
90ad738933 General readability 2018-04-09 18:09:04 +01:00
f2327023c1 No need to unset if not set 2018-04-09 18:09:04 +01:00
6f13f97674 Use mutating loop instead of array_map 2018-04-09 18:08:58 +01:00
8091e5586a Merge pull request #612 from aidantwoods/fix/table-columns
Table header should not be allowed to contain new lines
2018-04-09 16:53:07 +01:00
cb33daf0e6 Assert table header does not contain new lines 2018-04-09 16:38:03 +01:00
c440c91af5 Add failing test case 2018-04-09 16:32:36 +01:00
3514881e14 Merge pull request #611 from aidantwoods/enhancement/paragraph-block-semantics
Paragraph block semantics
2018-04-09 16:30:33 +01:00
043c55e4c6 Give paragraph block semantics for overloading 2018-04-09 15:12:17 +01:00
e4cd13350b Remove setLiteralBreaks 2018-04-09 15:11:45 +01:00
ae8067e862 Swap undefined type for type === 'Paragraph' for ease of reading
The way in which we use this assumes that it is a paragraph, for example
appending text into the handler argument — so there is no loss of
generality here, we're simply being explicit.
2018-04-09 14:48:48 +01:00
5353ebb524 Avoid needing two arrays
We only need to collect elements, we can discard finished blocks
2018-04-09 14:48:39 +01:00
39df7d4f8e Swap 'hidden' blocks for empty elements 2018-04-09 14:46:24 +01:00
50f15add44 Merge pull request #610 from aidantwoods/fix/lost-line-breaks
Fix lost line breaks
2018-04-09 14:19:38 +01:00
3f5b0ee781 Count number of interrupts 2018-04-09 14:13:10 +01:00
9a021b2130 Add failing test cases 2018-04-09 14:11:49 +01:00
43d25a74fe Fix function name 2018-04-08 18:40:50 +01:00
1d68e5506c Merge pull request #608 from aidantwoods/fix/recursion
Add seperate depth-first function instead of replacing recursive method
2018-04-08 18:02:17 +01:00
86940be224 Use mutating loop instead of creating new array 2018-04-08 17:49:36 +01:00
cdaf86b039 Add seperate depth-first function instead of replacing recursive method 2018-04-08 17:39:24 +01:00
1d65fb858a Restore file permission to that of 1.7.1 2018-04-08 14:30:23 +01:00
600db7e4de Bump version const to 1.8.0-beta-1 2018-04-08 02:46:30 +01:00
1be2a01de8 Merge pull request #607 from aidantwoods/update/readme-install-instructions
Update readme install instructions
2018-04-07 16:59:49 +01:00
f50ba3d803 Merge pull request #606 from erusev/revert-605-fix/this-php5.3-compat
Replace fix in "Explicitly capture $this for PHP 5.3"
2018-04-06 21:00:52 +01:00
387ef63888 Replace array reduce with foreach loop for PHP 5.3 compat 2018-04-06 20:55:27 +01:00
68be90348c Revert "Explicitly capture $this for PHP 5.3" 2018-04-06 20:50:34 +01:00
48b9f71bdc Merge pull request #605 from aidantwoods/fix/this-php5.3-compat
Explicitly capture $this for PHP 5.3
2018-04-06 20:44:32 +01:00
0039cd00f8 Explicitly capture $this for PHP 5.3 2018-04-06 20:40:25 +01:00
c6b717cc35 Merge pull request #604 from aidantwoods/fix/autobreak
Ensure autobreak false is honoured over empty name
2018-04-06 20:00:32 +01:00
8f3f61883d Merge pull request #603 from aidantwoods/fix/recursion
Apply depth first
2018-04-06 19:57:55 +01:00
4c9ea94d0c Apply depth first to avoid risk of segfault if closure creates subelements 2018-04-06 19:52:25 +01:00
32e69de014 Ensure autobreak false is honoured over empty name 2018-04-06 19:51:27 +01:00
201299ddc2 Merge pull request #602 from aidantwoods/enhancement/text-elements
Split some of `text` into `textElements`
2018-04-06 19:50:24 +01:00
557db7c179 Split some of text into textElements
`process` is no longer needed
2018-04-06 18:11:27 +01:00
0c0ed38290 Don't encourage downloading from master 2018-04-06 16:13:29 +01:00
798bda682e Update README.md
updated installation instructions. fixes #242
2018-04-06 16:09:36 +01:00
9b7b7348b4 Merge pull request #598 from aidantwoods/enhancement/set-literal-breaks
Add literalBreaks support
2018-04-06 15:06:45 +01:00
96581dbe16 Merge pull request #600 from aidantwoods/fix/code-block-closer
Fix fenced code block closer length rules
2018-04-05 18:46:49 +01:00
06b810cd4a Fix fenced code block closer to match CommonMark rules 2018-04-05 16:55:14 +01:00
38ea813b0e Add failing test case 2018-04-05 16:54:35 +01:00
24e48e91c8 Add literalBreaks support
Line breaks will be converted to <br />
2018-04-05 01:01:52 +01:00
e33f1a48c8 Merge pull request #596 from aidantwoods/enhancement/test-on-php72
Test on PHP 7.2
2018-04-02 19:56:02 +01:00
1c8f6bc253 Merge pull request #594 from aidantwoods/enhancement/ast-recursion-helper
Add recursive helper for AST
2018-04-02 19:53:58 +01:00
ed3e967fb6 Update README 2018-04-02 19:52:26 +01:00
3b3d13489b Test on PHP 7.2 2018-04-02 19:51:07 +01:00
498c88c4eb Merge pull request #589 from NathanBaulch/hashtag
Support #hashtag per CommonMark and GFM specs
2018-04-02 17:25:28 +01:00
772c919b05 Fix bug where empty atx headings would not be recognised (CommonMark)
Fixes #595
2018-04-02 17:18:01 +01:00
cf6d23de55 Rename hashtags enabled to strict mode
We can use this to seperate any intentional spec deviations from
spec behaviour so users can pick between compatability and spec
implementations
2018-04-02 17:18:01 +01:00
d0279cdd3b Enable #hashtag support via setting 2018-04-02 17:18:01 +01:00
8a90586218 Support #hashtag per CommonMark and GFM specs 2018-04-02 17:18:00 +01:00
390fa0da1b This is probably faster than duplicating the closure 2018-04-01 17:55:32 +01:00
9026b1abdb Add recursive helper for AST, use this for implementation of calling handler
recursively
2018-04-01 17:10:49 +01:00
68736f8800 Merge pull request #593 from aidantwoods/enhancement/process
Decouple manipulating final AST from `text` method
2018-04-01 16:37:44 +01:00
535110c57e Add process method so extensions may process final AST without
copying implementation of `text`
2018-03-31 23:23:12 +01:00
ce073c9baa Merge pull request #576 from aidantwoods/enhancement/moar-ast
Produce AST prior to render
2018-03-31 23:11:45 +01:00
e4d6c8f911 Add support for recursive handlers 2018-03-31 22:01:38 +01:00
cbe2e74d52 Merge pull request #592 from aidantwoods/fix/html-comment
Fix HTML comment endings
2018-03-30 19:28:40 +01:00
aa90dd481a Match CommonMark spec on HTML comments:
Start condition: line begins with the string `<!--`.
End condition: line contains the string `-->`.
2018-03-30 19:22:50 +01:00
20e592359f Add failing test case 2018-03-30 19:22:13 +01:00
9f1f5de387 Add recursive handle methods to generate entire AST for traversal 2018-03-28 20:59:56 +01:00
40b9da7837 Merge pull request #587 from aidantwoods/fix/ol-interrupt
Fix ordered list interrupt
2018-03-28 15:43:44 +01:00
a9c21447ce Only interrupt paragraph if starting with 1 2018-03-28 15:38:11 +01:00
a3e02c1d0e Add failing test case 2018-03-28 15:37:47 +01:00
40e797031e Old handler compatability layer 2018-03-28 03:42:38 +01:00
448b72a149 Merge pull request #586 from aidantwoods/fix/blockquote-adjacent
Fix merging of adjacent blockquotes
2018-03-28 03:31:36 +01:00
92e426e0e8 Fix merging of adjacent blockquotes 2018-03-28 03:27:09 +01:00
07216480db Change test to comply with CommonMark 2018-03-28 03:26:45 +01:00
caea783006 Add failing test case 2018-03-28 03:24:01 +01:00
d849d64611 Merge pull request #584 from aidantwoods/fix/tables
Permit 1 column tables with less delimiters
2018-03-27 23:18:41 +01:00
00e51ee424 Permit 1 column tables with less delimiters 2018-03-27 23:12:51 +01:00
0550c3eaf9 Merge pull request #583 from aidantwoods/fix/atx-headings
Fix trimming of internal #'s in ATX headers
2018-03-27 22:10:39 +01:00
790aed42ab Fix trimming of internal #'s 2018-03-27 22:04:11 +01:00
1c52cb6b5e Add failing test cases 2018-03-27 22:01:32 +01:00
ae13290221 Merge pull request #574 from aidantwoods/fix/remove-legacy-escaping
Remove legacy escaping
2018-03-27 13:18:30 +01:00
e16162e288 Merge pull request #582 from aidantwoods/fix/formatting
Formatting adjustments
2018-03-27 12:12:01 +01:00
244ea0aaa6 Remove some whitespace 2018-03-27 12:11:00 +01:00
2f291e0b2f Merge pull request #439 from aidantwoods/patch-4
Improve CommonMark mixed-marker list compliance
2018-03-27 11:31:34 +01:00
d2a73f9179 Trim whitespace 2018-03-27 11:23:04 +01:00
f594d4c18b Add more tests for CommonMark compliance 2018-03-27 11:20:04 +01:00
21cdd8a0b3 Merge branch 'master' into patch-4 2018-03-27 11:13:06 +01:00
a52d386250 Merge pull request #579 from aidantwoods/enhancement/gitignore
Add .gitignore for repo specific paths
2018-03-26 19:06:10 +01:00
dd9f4036ee Add .gitignore to export ignore in .gitattribtutes 2018-03-26 18:47:33 +01:00
e7fbbf537b Add repo specific paths to .gitignore 2018-03-26 18:45:34 +01:00
cac63f6fcb Merge pull request #578 from aidantwoods/fix/setext-heading-spaces
Fix setext heading space handling
2018-03-25 23:08:31 +01:00
f71bec00f4 Fix space handling in setext headings 2018-03-25 22:50:42 +01:00
913e04782f Add failing test cases to be fixed 2018-03-25 22:50:16 +01:00
1fa6b038af PHP 5.3 compat 2018-03-25 20:00:31 +01:00
e59fbd736d Remove 'markup' key exception for outputting via AST 2018-03-25 20:00:31 +01:00
8c14c5c239 Use rawHtml to provide conditional escaping for markup 2018-03-25 20:00:30 +01:00
0205a4cbe6 Use rawHtml to provide conditional escaping on special chars 2018-03-25 19:59:11 +01:00
011465bca6 Use rawHtml to provide conditional escaping for specialChars 2018-03-25 19:59:11 +01:00
adcba80502 Implement unmarked text via AST 2018-03-25 19:59:11 +01:00
65d7bc5013 Special casing for elements with no name 2018-03-25 19:59:11 +01:00
1a47e74be1 Quotes are permitted in escaped body 2018-03-25 19:59:05 +01:00
56cc41803a Merge pull request #514 from Daniel-KM/fix/consistency_follow
Added tests for consistency when a markdown follows a markup without blank line
2018-03-25 19:53:21 +01:00
d86d839677 Merge branch 'master' into fix/consistency_follow 2018-03-25 19:37:04 +01:00
d5ded2b935 Decouple handler argument from structure keys 2018-03-21 16:02:57 +00:00
098f24d189 Seperate handler delegation from AST
This also splits 'text' into 'text', 'elements', and
'element' to hopefully better communicate structure
2018-03-21 02:32:01 +00:00
eb55e426b9 Initial refactor to use AST 2018-03-21 02:18:34 +00:00
ced6187ca5 Merge pull request #575 from cebe/patch-3
Added inline example to README
2018-03-20 16:33:53 +00:00
972648ff64 Added inline example to README
see https://github.com/erusev/parsedown/issues/562
2018-03-20 16:56:40 +01:00
77dc0a090a Merge pull request #569 from aidantwoods/feature/unsafe-html
Add unsafeHtml option for extensions to use on trusted input
2018-03-18 21:58:48 +00:00
88dc949890 Refactor based on suggestion by @PhrozenByte 2018-03-18 20:17:12 +00:00
624a08b7eb Update commment 2018-03-15 19:55:33 +00:00
3fc54bc966 Allow extension to "vouch" for raw HTML they produce
Rename "unsafeHtml" to "rawHtml"
2018-03-15 19:46:03 +00:00
ef7ed7b66c Still grab the text if safe mode enabled, but output it escaped 2018-03-15 11:09:55 +00:00
e4c5be026d Further attempt to dissuade this feature's use 2018-03-15 11:00:03 +00:00
e6444bb57e Add unsafeHtml option for extensions to use on trusted input 2018-03-15 10:48:38 +00:00
a3265e7c6f Merge pull request #511 from aidantwoods/feature/null-name-element
Allow element to have no name
2018-03-15 09:41:16 +00:00
aac00ac742 Merge pull request #566 from aidantwoods/fix/email-autolink
Email autolink shouldn't be started by HTML tags
2018-03-10 00:06:59 +00:00
6830c3339f Readability
Thanks @PhrozenByte for the suggestion :)
2018-03-09 17:38:41 +00:00
19f1bb9353 Disable backtracking where the regex doesn't need it 2018-03-09 17:06:14 +00:00
721b885dd3 Fix #565 by validating email as defined in commonmark spec 2018-03-09 17:05:42 +00:00
f70d96479a Add test case for email surrounded by tags 2018-03-09 16:48:32 +00:00
92e9c27ba0 Merge pull request #563 from luizbills/master
bump version
2018-03-08 01:11:30 +00:00
9857334186 bump version 2018-03-07 22:04:55 -03:00
ae7e8e5067 bump version 2018-03-07 21:51:35 -03:00
253822057a refactor who uses it section in readme a bit more 2018-03-02 17:46:45 +02:00
a18bf495ed refactor who uses it section in readme 2018-03-02 17:40:21 +02:00
e5bf9560d7 add Laravel to who uses it 2018-03-02 17:37:16 +02:00
33b51eaefa Fix typo 2018-03-02 01:16:27 +00:00
d686a50292 Merge pull request #557 from aidantwoods/documentation/safe-mode
Talk about safe mode in the README
2018-03-01 19:59:44 +00:00
f3068df45a Remove extra line breaks 2018-03-01 19:54:58 +00:00
9b1f54b9d3 Lets be consistent with hyphenation 2018-03-01 18:45:38 +00:00
90439ef882 Rewrite section 2018-03-01 18:44:11 +00:00
72d30d33bc allow element to have no name 2018-03-01 01:17:32 +00:00
97dd037e6f Merge pull request #561 from PhrozenByte/patch-3
Add mbstring dependency to composer.json
2018-02-28 23:47:01 +00:00
fa89f0d743 Add mbstring dependency to composer.json 2018-02-28 20:42:25 +01:00
d638fd8a25 Merge pull request #560 from PhrozenByte/patch-2
Travis: Issue build error when Parsedown::version isn't up-to-date
2018-02-28 19:09:57 +00:00
cc53d5ae29 Travis: Issue build error when Parsedown::version isn't up-to-date 2018-02-28 20:04:45 +01:00
45f40696f6 Merge pull request #559 from PhrozenByte/patch-1
Update "Who uses it"
2018-02-28 18:07:37 +00:00
e8f3d4efc0 Merge pull request #558 from harikt/issue-232
Add test case to make sure issue 232 no longer exists
2018-02-28 18:02:14 +00:00
096e164756 Update README.md
Sort "Who uses it" alphabetically, add Laravel + Pico
2018-02-28 18:59:34 +01:00
e2f3961f80 Add test case to make sure issue 232 no longer exists 2018-02-28 23:25:38 +05:30
e941dcc3f0 Merge pull request #525 from aidantwoods/fix/infostring
Properly support fenced code block infostring
2018-02-28 17:06:25 +00:00
c192001a7e Merge pull request #433 from aidantwoods/patch-3
Fix Issue #358 – preventing double nested links
2018-02-28 17:05:58 +00:00
48a053fe29 Merge pull request #423 from PhrozenByte/bugfix/CommonMarkTest
Fix CommonMark test
2018-02-28 17:05:24 +00:00
5057e505d8 Merge pull request #475 from aidantwoods/loose-lists
Loose lists
2018-02-28 17:05:00 +00:00
ad62bf5a6f Talk about safe mode in the README 2018-02-28 17:03:46 +00:00
6678d59be4 Merge pull request #495 from aidantwoods/anti-xss
Prevent various XSS attacks [rebase and update of #276]
2018-02-28 13:41:37 +02:00
c999a4b61b improve readme 2018-01-29 20:55:30 +02:00
e938ab4ffe improve readme 2018-01-29 20:54:40 +02:00
e69374af0d improve readme 2018-01-29 20:52:27 +02:00
722b776684 Test multiple multiline lists 2018-01-29 14:38:19 +01:00
7fd92a8fbd update tests 2018-01-29 14:38:19 +01:00
0e1043a8d6 consistent li items for loose list 2018-01-29 14:38:19 +01:00
1196ed9512 Merge pull request #548 from m1guelpf-forks/patch-1
Update license year
2018-01-01 18:48:54 +02:00
1244122b84 Update LICENSE.txt 2018-01-01 14:09:31 +01:00
d98d60aaf3 Update license year 2017-12-31 22:10:48 +01:00
296ebf0e60 Merge pull request #429 from pablotheissen/patch-1
Support html tags containing dashes
2017-11-19 11:15:43 +02:00
a60ba300b1 Merge pull request #540 from jbafford/patch-1
Fix typo in README
2017-11-15 10:31:22 +02:00
089789dfff Fix typo in README 2017-11-14 17:13:31 -05:00
03e1a6ac02 Merge branch 'master' into bugfix/CommonMarkTest
Conflicts:
	.travis.yml
	test/CommonMarkTest.php
	test/ParsedownTest.php
	test/bootstrap.php
2017-11-14 22:09:25 +01:00
fbe3fe878f Merge pull request #539 from gabriel-caruso/phpunit
Use PHPUnit\Framework\TestCase instead of PHPUnit_Framework_TestCase
2017-11-14 22:44:03 +02:00
09827f542c Rewrite Travis CI 2017-11-14 15:19:24 -02:00
70ef6f5521 Make Travis CI use installed PHPUnit version, not global one 2017-11-14 13:21:11 -02:00
691e36b1f2 Use PHPUnit\Framework\TestCase instead of PHPUnit_Framework_TestCase 2017-11-11 00:56:03 -02:00
af6affdc2c improve readme 2017-11-06 16:54:00 +02:00
9cf41f27ab improve readme 2017-10-22 16:01:34 +03:00
16aadff2ed improve readme 2017-10-22 16:00:43 +03:00
07c937583d improve readme 2017-10-22 15:57:58 +03:00
4404201175 Properly support fenced code block infostring
Reference: http://spec.commonmark.org/0.28/#info-string
2017-08-20 10:28:46 +01:00
c05ef0c12a Merge branch 'aidantwoods-htmlblocks' into fix/consistency_follow 2017-06-23 00:00:00 +02:00
47e4163a68 Merge branch 'htmlblocks' of https://github.com/aidantwoods/parsedown into aidantwoods-htmlblocks 2017-06-23 00:00:00 +02:00
c05bff047a correct test to match CommonMark specified input for output 2017-06-22 00:03:12 +01:00
6a4afac0d0 remove ability for htmlblock to allow paragraph after if it closes on the same line 2017-06-22 00:02:03 +01:00
129f807e32 Inverted checks of consistency for markdown following markups. 2017-06-22 00:00:00 +02:00
be963a6531 Added tests for consistency when a markdown follows a markup without blank line. 2017-06-19 00:00:00 +02:00
728952b90a Merge pull request #499 from aidantwoods/fix/hhvm
Fix hhvm build failure
2017-05-14 17:47:48 +03:00
c82af01bd6 add sudo false 2017-05-14 14:39:09 +01:00
67c3efbea0 according to https://tools.ietf.org/html/rfc3986#section-3 the colon is a required part of the syntax, other methods of achieving the colon character (as to browser interpretation) should be taken care of by htmlencoding that is done on all attribute content 2017-05-10 16:57:18 +01:00
593ffd45a3 Merge pull request #406 from adrilo/patch-1
Create .gitattributes
2017-05-10 12:28:53 +03:00
bbb7687f31 safeMode will either apply all sanitisation techniques to an element or none (note that encoding HTML entities is done regardless because it speaks to character context, and that the only attributes/elements we should permit are the ones we actually mean to create) 2017-05-09 19:31:36 +01:00
b1e5aebaf6 add single safeMode option that encompasses protection from link destination xss and plain markup based xss into a single on/off switch 2017-05-09 19:22:58 +01:00
c63b690a79 remove duplicates 2017-05-09 14:50:15 +01:00
226f636360 remove $safe flag 2017-05-07 13:45:59 +01:00
2e4afde68d faster check substr at beginning of string 2017-05-06 16:32:51 +01:00
dc30cb441c add more protocols to the whitelist 2017-05-05 21:32:27 +01:00
f76b10aaab update readme 2017-05-04 10:28:55 +03:00
054ba3c487 urlencode urls that are potentially unsafe:
this should break urls that attempt to include a protocol, or port (these are absolute URLs and should have a whitelisted protocol for use)
but URLs that are relative, or relative from the site root should be preserved (though characters non essential for the URL structure may be urlencoded)

this approach has significant advantages over attempting to locate something like `javascript:alert(1)` or `javascript&colon;alert(1)` (which are both valid) because browsers have been known to ignore ridiculous characters when encountered (meaning something like `jav\ta\0\0script&colon;alert(1)` would be xss :( ). Instead of trying to chase down a way to interpret a URL to decide whether there is a protocol, this approach ensures that two essential characters needed to achieve a colon are encoded `:` (obviously) and `;` (from `&colon;`). If these characters appear in a relative URL then they are equivalent to their URL encoded form and so this change will be non breaking for that case.
2017-05-03 17:01:27 +01:00
4bae1c9834 whitelist regex for good attribute (no
no chars that could form a delimiter allowed
2017-05-03 00:39:01 +01:00
aee3963e6b jpeg, not jpg 2017-05-02 19:55:03 +01:00
4dc98b635d whitelist changes:
* add gif and jpg as allowed data images
* ensure that user controlled content fall only in the "data section" of the data URI (and does not intersect content-type definition in any way (best to be safe than sorry ;-)))
  "data section" as defined in: https://tools.ietf.org/html/rfc2397#section-3
2017-05-02 19:48:25 +01:00
e4bb12329e array_keys is probably faster 2017-05-02 01:32:24 +01:00
6d0156d707 dump attributes that contain characters that are impossible for validity, or very unlikely 2017-05-02 00:48:48 +01:00
29ad172261 Merge pull request #496 from aidantwoods/fix/ditch-hhvm-nightly
replace hhvm nightly with nightly
2017-05-01 19:35:36 +03:00
131ba75851 filter onevent attributes 2017-05-01 15:44:04 +01:00
924b26e16c replace hhvm nightly with nightly 2017-05-01 03:57:07 +01:00
af04ac92e2 add xss tests 2017-05-01 03:33:49 +01:00
6bb66db00f anti-xss
protect all attributes and content from xss via element method
filter special attributes (a href, img src)
expand url whitelist slightly to permit data images and mailto links
2017-05-01 03:25:07 +01:00
b3d45c4bb9 Add html escaping to all attributes capable of holding user input. 2017-05-01 02:00:38 +01:00
1d4296f34d Customizable whitelist of schemas for safeLinks 2017-05-01 01:58:34 +01:00
bf5105cb1a Improve safeLinks with whitelist. 2017-05-01 01:58:34 +01:00
1140613fc7 Prevent various XSS attacks 2017-05-01 01:58:34 +01:00
1d0af35f10 update test to result generated by CommonMark reference parser 2017-03-29 18:26:07 +01:00
d7956e3ade blockmarkup ends on interrupt by newline (CommonMark compliance) 2017-03-29 18:25:56 +01:00
4367f89a74 attempt to fix failing builds on 5.3 2017-03-29 19:30:24 +03:00
67e454e300 Merge pull request #2 from PhrozenByte/aidantwoods/patch-4
Use the list marker width to determine whether a list item is continued
2016-10-14 08:29:11 +01:00
ae0211a84c Travis: Add PHP nightly 2016-10-13 22:17:03 +02:00
a9f696f7bb Improve CommonMark spec example regex
CommonMark spec example [#170](http://spec.commonmark.org/0.26/#example-170) has a empty HTML result.
2016-10-13 22:16:46 +02:00
a3836b1853 Handle subsequent list items which aren't indented sufficiently
Subsequent list items which aren't indented sufficiently are treated as part of the original list, see CommonMark spec example [#256](http://spec.commonmark.org/0.26/#example-256).
2016-10-13 20:44:02 +02:00
a9e1163c85 Fix code formatting 2016-10-13 19:52:38 +02:00
7b1529fff0 Use the list marker width to determine whether a list item is continued
This basically represents [list item parsing](http://spec.commonmark.org/0.26/#list-items), rule 1 of the CommonMark specs.
2016-10-13 19:51:32 +02:00
1d61f90bf9 Support list items starting with indented code 2016-10-13 19:47:06 +02:00
4b3b7df710 Support list items starting with a blank line
According to the CommonMark specs ([list items](http://spec.commonmark.org/0.26/#list-items), rule 3), list items starting with a blank line basically behave like as if the \n doesn't exist. Also see example [#241](http://spec.commonmark.org/0.26/#example-241).
2016-10-13 19:46:29 +02:00
30ff5c6e75 Remove unused $placeholder variable 2016-10-13 19:31:35 +02:00
bdf537e9d5 Fix ordered list start argument
See CommonMark spec examples [#226](http://spec.commonmark.org/0.26/#example-226) to #229
2016-10-13 19:30:50 +02:00
81025cd468 Revert "Break less previously passed CommonMarkWeak tests"
This reverts commit 2db3199510.
2016-10-13 19:25:43 +02:00
e691034861 Revert "Prevent failure with data set 77 in CommonMarkWeak"
This reverts commit 0a43799da4.
2016-10-13 19:25:37 +02:00
eb853da92a Revert "Prevent breaking remaining previously compliant CommonMarkWeak tests"
This reverts commit 6973302ca8.
2016-10-13 19:25:30 +02:00
6973302ca8 Prevent breaking remaining previously compliant CommonMarkWeak tests 2016-10-13 15:55:13 +01:00
0a43799da4 Prevent failure with data set 77 in CommonMarkWeak 2016-10-13 14:29:52 +01:00
2db3199510 Break less previously passed CommonMarkWeak tests 2016-10-12 18:10:44 +01:00
2423644d72 Move test/CommonMarkTest.php to test/CommonMarkTestStrict.php
Add parameter `$id` to CommonMark tests
2016-10-12 02:02:55 +02:00
8965c7864f More appropriate tests for these changes 2016-10-11 20:55:59 +01:00
d26b33c20f Add ) as an ordered list marker
Also added marker check to ordered list case when deciding to continue the current list
2016-10-11 19:18:43 +01:00
d9679141fa Update test to comply with CommonMark 2016-10-11 13:50:47 +01:00
0bd61a73ed Check that the current line is a list before starting a new one 2016-10-11 13:48:38 +01:00
06c4344a71 Contextual limits on indentation stripping 2016-10-11 13:38:47 +01:00
c4d4a6800d (beginning to) improve commonmark compliance:lists
These changes aren't fit for merge, nor do they work correctly (yet)
2016-10-11 12:05:33 +01:00
be671e72a3 Don't let Travis skip Parsedown's phpunit tests 2016-10-09 14:21:17 +02:00
f0587d41a9 Add test/CommonMarkTestWeak.php to .travis.yml
Failing tests don't break builds on purpose, Parsedown doesn't fully comply with the CommonMark specs at the moment. We should switch to test/CommonMarkTest.php later, see #423 for details.
2016-10-09 14:17:03 +02:00
3aef89b399 Line handler may prevent specified element nesting
Swap `under_scores` for `camelCasing`
2016-10-08 17:54:04 +01:00
543a6c4175 Line handler may prevent specified element nesting
Check if array is empty to shave some performance hits in the case than no non nestables are present.
2016-10-04 18:59:36 +01:00
a81aedeb10 Line handler may prevent specified element nesting
Removed granularity controls – elements are assumed to be non nestable indefinitely once declared.
2016-10-04 15:27:11 +01:00
50952b3243 Line handler may prevent specified element nesting
This commit serves to add comments detailing parts of the new functionality, and to adjust syntax preferences to match that of the surrounding document. The commit title also now reflects the most significant change made.
2016-10-02 18:26:13 +01:00
4d3600f273 Extend disallowed assertion depth capabilities
I've built on the functionality of feature 1. in the previous commit to allow non nestables to be asserted indefinitely, or to a specified depth.
2016-10-02 17:37:08 +01:00
d6d5f53ff4 Fix Issue #358 – preventing double nested links
1. Add the ability for a parsed element to enforce that the line handler not parse any (immediate) child elements of a specified type.
2. Use 1. to allow parsed Url elements to tell the line handler not to parse any child Links or Urls where they are immediate children.
2016-10-01 15:56:14 +01:00
1a44cbd62c Update Parsedown.php
Made parsedown compatible with html-tags containing dashes.
see https://github.com/erusev/parsedown/issues/407#issuecomment-248833563
2016-09-22 12:21:39 +02:00
73dbe2fd17 Remove PHPUnit bootstrap in favour of composer 2016-09-05 22:04:46 +02:00
33a23fbfb2 Refactor PHPUnit bootstrap
This allows Parsedown extensions (like Parsedown Extra) to reuse existing Parsedown tests. See erusev/parsedown-extra#96 for details.
2016-09-05 21:10:23 +02:00
228d5f4754 Improve test/CommonMarkTestWeak.php 2016-09-05 15:31:07 +02:00
2cacfb8da4 Improve test/CommonMarkTestWeak.php 2016-09-05 15:17:52 +02:00
d33e736fa3 Add test/CommonMarkTestWeak.php 2016-09-05 14:38:47 +02:00
3a46a31e09 Fix test/CommonMarkTest.php example regex 2016-09-05 14:37:34 +02:00
e1bcc1c472 Fix test/CommonMarkTest.php 2016-09-05 04:51:28 +02:00
b5951e08c6 Create .gitattributes
When using this library, all the files related to tests can be ignored. Tests are only useful when working on the library itself.
2016-06-24 14:18:01 +02:00
67 changed files with 1721 additions and 620 deletions

6
.gitattributes vendored Normal file
View 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
View File

@ -0,0 +1,2 @@
composer.lock
vendor/

View File

@ -1,16 +1,30 @@
language: php
php:
- 7.1
- 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;")" ]'

View File

@ -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.

File diff suppressed because it is too large Load Diff

View File

@ -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
@ -15,15 +15,25 @@ Better Markdown Parser in PHP
### Features
* One File
* No Dependencies
* Super Fast
* Extensible
* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown)
* Tested in 5.3 to 7.1 and in HHVM
* 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
@ -31,10 +41,41 @@ 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?**
@ -49,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/), [Symfony demo](https://github.com/symfony/symfony-demo) and [more](https://packagist.org/packages/erusev/parsedown/dependents).
[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?**

View File

@ -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/"
}
}
}

View File

@ -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>

View File

@ -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;
}
}

View 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;
}
}

View 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
View 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">&lt;p&gt;foobar&lt;/p&gt;</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>&lt;div&gt;<em>content</em>&lt;/div&gt;</p>
<p>sparse:</p>
<p>&lt;div&gt;
&lt;div class=&quot;inner&quot;&gt;
&lt;div class="inner"&gt;
<em>content</em>
&lt;/div&gt;
&lt;/div&gt;</p>
<p>paragraph</p>
<p>&lt;style type=&quot;text/css&quot;&gt;
<p>&lt;style type="text/css"&gt;
p {
color: red;
}
@ -132,15 +173,14 @@ color: red;
<p>comment</p>
<p>&lt;!-- html comment --&gt;</p>
EXPECTED_HTML;
$parsedownWithNoMarkup = new Parsedown();
$parsedownWithNoMarkup = new TestParsedown();
$parsedownWithNoMarkup->setMarkupEscaped(true);
$this->assertEquals($expectedHtml, $parsedownWithNoMarkup->text($markdownWithHtml));
}
public function testLateStaticBinding()
{
include __DIR__ . '/TestParsedown.php';
$parsedown = Parsedown::instance();
$this->assertInstanceOf('Parsedown', $parsedown);

40
test/SampleExtensions.php Normal file
View 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;
}
}

View File

@ -2,4 +2,8 @@
class TestParsedown extends Parsedown
{
public function getTextLevelElements()
{
return $this->textLevelElements;
}
}

View File

@ -1,7 +0,0 @@
<?php
include 'Parsedown.php';
if ( ! class_exists('\PHPUnit\Framework\TestCase') && class_exists('\PHPUnit_Framework_TestCase')) {
class_alias('\PHPUnit_Framework_TestCase', '\PHPUnit\Framework\TestCase');
}

View File

@ -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>

View File

@ -14,4 +14,12 @@
# closed h1 #
#
#
##
# # of levels
# # of levels # #
#heading

View File

@ -5,4 +5,9 @@ echo $message;</code></pre>
<hr />
<pre><code>&gt; 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>

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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">&lt;?php
echo "Hello World";
?&gt;
&lt;a href="http://auraphp.com" &gt;Aura Project&lt;/a&gt;</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>

View File

@ -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
```

View File

@ -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>

View File

@ -5,4 +5,10 @@ paragraph
<!--
multiline -->
paragraph
paragraph
<!-- sss -->abc
* abcd
* bbbb
* cccc

View File

@ -1,6 +1,8 @@
<blockquote>
<p>quote
the rest of it</p>
</blockquote>
<blockquote>
<p>another paragraph
the rest of it</p>
</blockquote>

View File

@ -0,0 +1,3 @@
<div>Markup</div>
_No markdown_ without blank line for **strict** compliance with CommonMark.
<p><strong>Markdown</strong></p>

View File

@ -0,0 +1,4 @@
<div>Markup</div>
_No markdown_ without blank line for **strict** compliance with CommonMark.
**Markdown**

View File

@ -0,0 +1,4 @@
<div>One markup on
two lines</div>
_No markdown_
<p><strong>Markdown</strong></p>

View File

@ -0,0 +1,5 @@
<div>One markup on
two lines</div>
_No markdown_
**Markdown**

View File

@ -0,0 +1,3 @@
<div><p>Stripped markup</p></div>
_No markdown_
<p><strong>Markdown</strong></p>

View File

@ -0,0 +1,4 @@
<div><p>Stripped markup</p></div>
_No markdown_
**Markdown**

View 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>

View File

@ -0,0 +1,4 @@
<div>First markup</div><p>and second markup on the same line.</p>
_No markdown_
**Markdown**

View File

@ -0,0 +1,4 @@
<div>First markup</div><p>and partial markup
on two lines.</p>
_No markdown_
<p><strong>Markdown</strong></p>

View File

@ -0,0 +1,5 @@
<div>First markup</div><p>and partial markup
on two lines.</p>
_No markdown_
**Markdown**

View File

@ -0,0 +1,4 @@
<div><p>Stripped markup
on two lines</p></div>
_No markdown_
<p><strong>Markdown</strong></p>

View File

@ -0,0 +1,5 @@
<div><p>Stripped markup
on two lines</p></div>
_No markdown_
**Markdown**

View File

@ -0,0 +1,10 @@
<ol>
<li>
<p>One
First body copy</p>
</li>
<li>
<p>Two
Last body copy</p>
</li>
</ol>

View File

@ -0,0 +1,5 @@
1. One
First body copy
2. Two
Last body copy

View File

@ -10,4 +10,7 @@
<p>large numbers:</p>
<ol start="123">
<li>one</li>
</ol>
</ol>
<p>foo 1. the following should not start a list
100.<br />
200. </p>

View File

@ -8,4 +8,8 @@ repeating numbers:
large numbers:
123. one
123. one
foo 1. the following should not start a list
100.
200.

View File

@ -8,5 +8,7 @@
<li>
<p>li</p>
</li>
<li>li</li>
<li>
<p>li</p>
</li>
</ul>

View File

@ -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

View 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>

View 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
--

View File

@ -8,4 +8,19 @@
<p>no space after <code>&gt;</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>

View File

@ -4,4 +4,10 @@ indented:
> quote
no space after `>`:
>quote
>quote
---
>>> Info 1 text
>>> Info 2 text

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -1,8 +1,6 @@
<div>
line 1
line 2
line 3
line 4
<p>line 2
line 3</p>
<p>line 4</p>
</div>

View File

@ -2,7 +2,9 @@
<li>
<p>li</p>
</li>
<li>li</li>
<li>
<p>li</p>
</li>
</ul>
<hr />
<ul>

View 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>

View File

@ -0,0 +1,25 @@
# h1
## h2
### h3
#### h4
##### h5
###### h6
####### not a heading
#not a heading
# closed h1 #
#
##
# # of levels
# # of levels # #

View File

@ -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>

View File

@ -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\~\~

View File

@ -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>

View File

@ -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

View File

@ -0,0 +1,6 @@
<p><a href="https://www.example.com&quot;">xss</a></p>
<p><img src="https://www.example.com&quot;" alt="xss" /></p>
<p><a href="https://www.example.com&#039;">xss</a></p>
<p><img src="https://www.example.com&#039;" alt="xss" /></p>
<p><img src="https://www.example.com" alt="xss&quot;" /></p>
<p><img src="https://www.example.com" alt="xss&#039;" /></p>

View 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)

View 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&amp;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&amp;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&amp;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&amp;colon;text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==" alt="xss" /></p>

31
test/data/xss_bad_url.md Normal file
View File

@ -0,0 +1,31 @@
[xss](javascript:alert(1))
[xss]( javascript:alert(1))
[xss](javascript://alert(1))
[xss](javascript&colon;alert(1))
![xss](javascript:alert(1))
![xss]( javascript:alert(1))
![xss](javascript://alert(1))
![xss](javascript&colon;alert(1))
[xss](data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
[xss]( data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
[xss](data://text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
[xss](data&colon;text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
![xss](data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
![xss]( data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
![xss](data://text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)
![xss](data&colon;text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)

View File

@ -0,0 +1,7 @@
<p>&lt;script&gt;alert(1)&lt;/script&gt;</p>
<p>&lt;script&gt;</p>
<p>alert(1)</p>
<p>&lt;/script&gt;</p>
<p>&lt;script&gt;
alert(1)
&lt;/script&gt;</p>

View File

@ -0,0 +1,12 @@
<script>alert(1)</script>
<script>
alert(1)
</script>
<script>
alert(1)
</script>