From 30aa18c003d41a309ac61edfbc5428af650f1646 Mon Sep 17 00:00:00 2001 From: Estevao Soares dos Santos Date: Tue, 30 May 2017 04:11:00 +0100 Subject: [PATCH] fix(url parsing): fix url edge case parsing in images and links Allow some edge cases to parse correctly. Example: `![img](.images/cat(1).png)`, `![img](<.image(1)/cat(1).png>)`, `[link](<>)` --- dist/showdown.js | Bin 88464 -> 89044 bytes dist/showdown.js.map | Bin 256454 -> 258017 bytes dist/showdown.min.js | Bin 37210 -> 37565 bytes dist/showdown.min.js.map | Bin 39964 -> 40017 bytes src/subParsers/anchors.js | 35 +++++++++--------- src/subParsers/images.js | 12 +++++- test/cases/anchors-followed-by-brakets.html | 4 ++ test/cases/anchors-followed-by-brakets.md | 7 ++++ test/cases/images-followed-by-brackets.html | 2 + test/cases/images-followed-by-brackets.md | 3 ++ .../#390.brackets-in-URL-break-images.html | 4 ++ .../#390.brackets-in-URL-break-images.md | 9 +++++ .../#390.brackets-in-URL-break-links.html | 1 + .../#390.brackets-in-URL-break-links.md | 2 + .../URLs-with-multiple-parenthesis.html | 5 +++ test/issues/URLs-with-multiple-parenthesis.md | 9 +++++ test/issues/crazy-urls.html | 14 +++++++ test/issues/crazy-urls.md | 27 ++++++++++++++ 18 files changed, 114 insertions(+), 20 deletions(-) create mode 100644 test/cases/anchors-followed-by-brakets.html create mode 100644 test/cases/anchors-followed-by-brakets.md create mode 100644 test/cases/images-followed-by-brackets.html create mode 100644 test/cases/images-followed-by-brackets.md create mode 100644 test/issues/#390.brackets-in-URL-break-images.html create mode 100644 test/issues/#390.brackets-in-URL-break-images.md create mode 100644 test/issues/URLs-with-multiple-parenthesis.html create mode 100644 test/issues/URLs-with-multiple-parenthesis.md create mode 100644 test/issues/crazy-urls.html create mode 100644 test/issues/crazy-urls.md diff --git a/dist/showdown.js b/dist/showdown.js index 2b3e1ba8336c54356e1d811c93593a6e5247495d..089ca1c52c69ef342f83b039161d0d32f1ac225e 100644 GIT binary patch delta 819 zcmbQRnf1zcRsm~$Ek%XmjQsMH{PH{nV}p$Xy4@N%nR(eEsTCzU3LuteijG2QQI3v6 zt|<_k=_r(BmgJ;rDpYe#R@75rgYYJ=`z=ZR}%;we0K_>@}j* zm16a@K%}O9jHZfyuBL*Wg03OR00l4r8m?fgpssEW=GQ8u<`k!H7U|i+I9c+H2Z@#EEmrZiQO9Y zx#pUh3e{W+V32FBV5^|6ZVl$vg30oX{G3$Z#FFF;pj56QM5-*YNFgUPFFPc)q68#t zqysfT0W9p90unUVE6MlCFHbFUPApE<&_pOHEy@AOn}9^bAQqQomgJ;@1kJ6vKt^p2 z>)F9L+3~L=b4;<;@{OGCm)!YI5}jO zXd*t%F&fbdF(t8D8k#otAblW%Ky-{I$Pjx?JA0_SMzp$8tR~p#7&C|%&@N3){d66! z$rpvhCihR?E(o#->N0Jh3p7A(P~KcI*ftUDVW%xrE$4MJ~WwbX9VmWB=m zQK&{4`oj%Qz&@%pR38e{7{Bm2a;j@ERrC%QJ4>J+k_G} zIALQK(oXh$N`kAa%y})cG5g{|_+}U>taHg6$e%{VkbYb!V>y=uiPLB)?7N1fLxu#| z&yWJSFHuoJJ*CYx&8+JUCloy)$gCu&uwUMDLH8b10prJ!h=S1d07tZE?d%@Ck~J2K zP<{+KAP0Qd1YL8HlO-plS1zHstn-X$_~#%d0REcKuJ05?X;ceR8Z?{frb&*QKSdH7|IP+`Q-W_6Y;Lm* z7e3~*&KD)<&2Vdetwbd=z!sV1t;R|R+KWU#_rVXx6|@*7;9$Gp0t+_(ro_g6li-@m z+;M>4ev@SQo#=TRUf!~nJ=^Sr#tgC<`32~Mqq9Y@?kzG5mm`r4YSIlFQR2} zS7jJ{RHy`dxu6_Ag<9D73k7WKNCCUDL}6)Go z!aSMCE>Za=Q25+A%Ssq~4T;9?Q>aIP{3gMEd$E&6lObg_`f^4}xXYI%9zyAmLxIk3 zk%MI&HdG6=UU0JE74u-|U7i>|hukAPNz=bDKFK4Ykey5_|1CYxJ%mKC+|2!m#G(kL zk(pp5VAzkQ4mg#I6=ncrtxngOeH?{5I*seZ}m{sc* zjqKc!&`7eDzw0#8*V~tfL6-xol~$>$WRIRA*2`*;Rivt_ezNrp{N9f>aP(jWye?b{ z=bgALxH6#Y8Bari1l*x2y&_!gu|8DZR+svcDrq3gYG%Rm{eJ=_u|y_jlq&cHf-hde z9^)++ej3BsGE87}KVAg2<@_-)fD53%4A=X7J`#;&Vj1#eZ(k3I?ub0K+tifd0=LCT zwXZiBiN}1=NMDUwoleDpdT=T7S$J)3HAHm1FYM8E_hc1V=?-mb2z%59ci{f1q1zqO zE2_dOpKv{%fU4`Ysv4O31DEBCYkCScEX0fErMB-#MiLey_^26|S$m?l+QaS9^@qaV z0AFOTH@|pHlcp*)pf;GZe@O!9LVVV)>mie+&N0GauNpSI<@j1}quC0Z%)`@YT*Hjw ze`W$#&)~*=oXpKm)ZJvnWLm64tc%5iyV8>leq`TW)BOIP%q;uKDtCxqW=q%`qRTc$ zVE!ofR+uDi&10H~F|;2aMFJsE+=E>=lDXzKk~tOl$!xAafM34jf8|cJT!HNanEW*< L3yg^Yd}_lVYD;84 delta 1185 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 delta 7465 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 BL`eVu diff --git a/src/subParsers/anchors.js b/src/subParsers/anchors.js index b45b56d..5779368 100644 --- a/src/subParsers/anchors.js +++ b/src/subParsers/anchors.js @@ -6,17 +6,16 @@ showdown.subParser('anchors', function (text, options, globals) { text = globals.converter._dispatch('anchors.before', text, options, globals); - var writeAnchorTag = function (wholeMatch, m1, m2, m3, m4, m5, m6, m7) { - if (showdown.helper.isUndefined(m7)) { - m7 = ''; + var writeAnchorTag = function (wholeMatch, linkText, linkId, url, m5, m6, title) { + if (showdown.helper.isUndefined(title)) { + title = ''; } - wholeMatch = m1; - var linkText = m2, - linkId = m3.toLowerCase(), - url = m4, - title = m7; + linkId = linkId.toLowerCase(); - if (!url) { + // Special case for explicit empty url + if (wholeMatch.search(/\(? ?(['"].*['"])?\)$/m) > -1) { + url = ''; + } else if (!url) { if (!linkId) { // lower-case and turn embedded newlines into spaces linkId = linkText.toLowerCase().replace(/ ?\n/g, ' '); @@ -29,12 +28,7 @@ showdown.subParser('anchors', function (text, options, globals) { title = globals.gTitles[linkId]; } } else { - if (wholeMatch.search(/\(\s*\)$/m) > -1) { - // Special case for explicit empty url - url = ''; - } else { - return wholeMatch; - } + return wholeMatch; } } @@ -61,16 +55,21 @@ showdown.subParser('anchors', function (text, options, globals) { }; // First, handle reference-style links: [link text] [id] - text = text.replace(/(\[((?:\[[^\]]*]|[^\[\]])*)][ ]?(?:\n[ ]*)?\[(.*?)])()()()()/g, writeAnchorTag); + text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g, writeAnchorTag); // Next, inline-style links: [link text](url "optional title") - text = text.replace(/(\[((?:\[[^\]]*]|[^\[\]])*)]\([ \t]*()?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, + // cases with crazy urls like ./image/cat1).png + text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, + writeAnchorTag); + + // normal cases + text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]??(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, writeAnchorTag); // handle reference-style shortcuts: [link text] // These must come last in case you've also got [link test][1] // or [link test](/foo) - text = text.replace(/(\[([^\[\]]+)])()()()()()/g, writeAnchorTag); + text = text.replace(/\[([^\[\]]+)]()()()()()/g, writeAnchorTag); // Lastly handle GithubMentions if option is enabled if (options.ghMentions) { diff --git a/src/subParsers/images.js b/src/subParsers/images.js index 201ad24..3dba06b 100644 --- a/src/subParsers/images.js +++ b/src/subParsers/images.js @@ -6,7 +6,8 @@ showdown.subParser('images', function (text, options, globals) { text = globals.converter._dispatch('images.before', text, options, globals); - var inlineRegExp = /!\[(.*?)]\s?\([ \t]*()?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(['"])(.*?)\6[ \t]*)?\)/g, + var inlineRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]??(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g, + crazyRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g, referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[(.*?)]()()()()()/g, refShortcutRegExp = /!\[([^\[\]]+)]()()()()()/g; @@ -21,8 +22,11 @@ showdown.subParser('images', function (text, options, globals) { if (!title) { title = ''; } + // Special case for explicit empty url + if (wholeMatch.search(/\(? ?(['"].*['"])?\)$/m) > -1) { + url = ''; - if (url === '' || url === null) { + } else if (url === '' || url === null) { if (linkId === '' || linkId === null) { // lower-case and turn embedded newlines into spaces linkId = altText.toLowerCase().replace(/ ?\n/g, ' '); @@ -76,6 +80,10 @@ showdown.subParser('images', function (text, options, globals) { text = text.replace(referenceRegExp, writeImageTag); // Next, handle inline images: ![alt text](url =x "optional title") + // cases with crazy urls like ./image/cat1).png + text = text.replace(crazyRegExp, writeImageTag); + + // normal cases text = text.replace(inlineRegExp, writeImageTag); // handle reference-style shortcuts: |[img text] diff --git a/test/cases/anchors-followed-by-brakets.html b/test/cases/anchors-followed-by-brakets.html new file mode 100644 index 0000000..1b1abac --- /dev/null +++ b/test/cases/anchors-followed-by-brakets.html @@ -0,0 +1,4 @@ +

This is a link (some other text)

+

This is a link (some other text)

+

This is a link (some other text)

+

This is a link (some other text)

\ No newline at end of file diff --git a/test/cases/anchors-followed-by-brakets.md b/test/cases/anchors-followed-by-brakets.md new file mode 100644 index 0000000..974fdd3 --- /dev/null +++ b/test/cases/anchors-followed-by-brakets.md @@ -0,0 +1,7 @@ +This is a [link](https://en.wikipedia.org/wiki/Textile) (some other text) + +This is a [link](https://en.wikipedia.org/wiki/Textile_(markup) (some other text) + +This is a [link](https://en.wikipedia.org/wiki/Textile_(markup_language)) (some other text) + +This is a [link](https://en.wikipedia.org/wiki/Textile_(markup_language)/foo) (some other text) \ No newline at end of file diff --git a/test/cases/images-followed-by-brackets.html b/test/cases/images-followed-by-brackets.html new file mode 100644 index 0000000..20e2292 --- /dev/null +++ b/test/cases/images-followed-by-brackets.html @@ -0,0 +1,2 @@ +

image link(some text between brackets)

+

image link(some text between brackets)

\ No newline at end of file diff --git a/test/cases/images-followed-by-brackets.md b/test/cases/images-followed-by-brackets.md new file mode 100644 index 0000000..1481067 --- /dev/null +++ b/test/cases/images-followed-by-brackets.md @@ -0,0 +1,3 @@ +![image link](<./image/cat1.png>)(some text between brackets) + +![image link](<./image/cat(1).png>)(some text between brackets) diff --git a/test/issues/#390.brackets-in-URL-break-images.html b/test/issues/#390.brackets-in-URL-break-images.html new file mode 100644 index 0000000..d5290b4 --- /dev/null +++ b/test/issues/#390.brackets-in-URL-break-images.html @@ -0,0 +1,4 @@ +

This is an image

+

This is another image

+

image link

+

image link

diff --git a/test/issues/#390.brackets-in-URL-break-images.md b/test/issues/#390.brackets-in-URL-break-images.md new file mode 100644 index 0000000..6340f75 --- /dev/null +++ b/test/issues/#390.brackets-in-URL-break-images.md @@ -0,0 +1,9 @@ +This is an ![image][] + +[image]: ./image/cat(1).png + +This is another ![image](./image/cat(1).png) + +[![image link](./image/cat(1).png)](http://example.com) + +[![image link](<./image/cat1).png>)](http://example.com) diff --git a/test/issues/#390.brackets-in-URL-break-links.html b/test/issues/#390.brackets-in-URL-break-links.html index 46379c8..acff8f9 100644 --- a/test/issues/#390.brackets-in-URL-break-links.html +++ b/test/issues/#390.brackets-in-URL-break-links.html @@ -1,2 +1,3 @@

This is a link.

This is another link.

+

link

diff --git a/test/issues/#390.brackets-in-URL-break-links.md b/test/issues/#390.brackets-in-URL-break-links.md index 4a3e2c1..338fcdd 100644 --- a/test/issues/#390.brackets-in-URL-break-links.md +++ b/test/issues/#390.brackets-in-URL-break-links.md @@ -3,3 +3,5 @@ This is a [link][]. [link]: https://en.wikipedia.org/wiki/Textile_(markup_language) "Textile" This is another [link](https://en.wikipedia.org/wiki/Textile_(markup_language) "Textile"). + +[link](<./image/cat1).png> "title") diff --git a/test/issues/URLs-with-multiple-parenthesis.html b/test/issues/URLs-with-multiple-parenthesis.html new file mode 100644 index 0000000..166a9d3 --- /dev/null +++ b/test/issues/URLs-with-multiple-parenthesis.html @@ -0,0 +1,5 @@ +

link

+

link

+

image

+

image

+

image

diff --git a/test/issues/URLs-with-multiple-parenthesis.md b/test/issues/URLs-with-multiple-parenthesis.md new file mode 100644 index 0000000..5d32457 --- /dev/null +++ b/test/issues/URLs-with-multiple-parenthesis.md @@ -0,0 +1,9 @@ +[link](<./images(1)/cat(1).png>) + +[link](<./images(1)/cat(1).png> "title") + +![image](<./images(1)/cat(1).png>) + +![image](<./images(1)/cat(1).png> "title") + +![image](<./images(1)/cat(1).png> =800x600 "title") diff --git a/test/issues/crazy-urls.html b/test/issues/crazy-urls.html new file mode 100644 index 0000000..d5a1f3a --- /dev/null +++ b/test/issues/crazy-urls.html @@ -0,0 +1,14 @@ +

my cat

+

my cat

+

foo

+

foo

+

foo

+

foo

+

empty

+

empty

+

empty

+

empty

+

empty

+

empty

+

empty

+

empty

diff --git a/test/issues/crazy-urls.md b/test/issues/crazy-urls.md new file mode 100644 index 0000000..3299d5b --- /dev/null +++ b/test/issues/crazy-urls.md @@ -0,0 +1,27 @@ +![my cat]() + +[my cat]() + +![foo]() + +![foo]( "title") + +[foo]() + +[foo]( "title") + +![empty](<>) + +[empty](<>) + +![empty](<> "title") + +[empty](<> "title") + +![empty](< >) + +[empty](< >) + +![empty](< > "title") + +[empty](< > "title")