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](<>)`
This commit is contained in:
Estevao Soares dos Santos 2017-05-30 04:11:00 +01:00
parent 230f443442
commit 30aa18c003
18 changed files with 114 additions and 20 deletions

BIN
dist/showdown.js vendored

Binary file not shown.

BIN
dist/showdown.js.map vendored

Binary file not shown.

BIN
dist/showdown.min.js vendored

Binary file not shown.

Binary file not shown.

View File

@ -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(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) {
url = '';
} else if (!url) {
if (!linkId) {
// lower-case and turn embedded newlines into spaces
linkId = linkText.toLowerCase().replace(/ ?\n/g, ' ');
@ -28,15 +27,10 @@ showdown.subParser('anchors', function (text, options, globals) {
if (!showdown.helper.isUndefined(globals.gTitles[linkId])) {
title = globals.gTitles[linkId];
}
} else {
if (wholeMatch.search(/\(\s*\)$/m) > -1) {
// Special case for explicit empty url
url = '';
} else {
return wholeMatch;
}
}
}
//url = showdown.helper.escapeCharacters(url, '*_', false); // replaced line to improve performance
url = url.replace(showdown.helper.regexes.asteriskAndDash, showdown.helper.escapeCharactersCallback);
@ -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]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \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) {

View File

@ -6,7 +6,8 @@ showdown.subParser('images', function (text, options, globals) {
text = globals.converter._dispatch('images.before', text, options, globals);
var inlineRegExp = /!\[(.*?)]\s?\([ \t]*()<?(\S+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(['"])(.*?)\6[ \t]*)?\)/g,
var inlineRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\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(/\(<?\s*>? ?(['"].*['"])?\)$/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 =<width>x<height> "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]

View File

@ -0,0 +1,4 @@
<p>This is a <a href="https://en.wikipedia.org/wiki/Textile">link</a> (some other text)</p>
<p>This is a <a href="https://en.wikipedia.org/wiki/Textile_(markup">link</a> (some other text)</p>
<p>This is a <a href="https://en.wikipedia.org/wiki/Textile_(markup_language)">link</a> (some other text)</p>
<p>This is a <a href="https://en.wikipedia.org/wiki/Textile_(markup_language)/foo">link</a> (some other text)</p>

View File

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

View File

@ -0,0 +1,2 @@
<p><img src="./image/cat1.png" alt="image link" />(some text between brackets)</p>
<p><img src="./image/cat(1).png" alt="image link" />(some text between brackets)</p>

View File

@ -0,0 +1,3 @@
![image link](<./image/cat1.png>)(some text between brackets)
![image link](<./image/cat(1).png>)(some text between brackets)

View File

@ -0,0 +1,4 @@
<p>This is an <img src="./image/cat(1).png" alt="image" /></p>
<p>This is another <img src="./image/cat(1).png" alt="image" /></p>
<p><a href="http://example.com"><img src="./image/cat(1).png" alt="image link" /></a></p>
<p><a href="http://example.com"><img src="./image/cat1).png" alt="image link" /></a></p>

View File

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

View File

@ -1,2 +1,3 @@
<p>This is a <a href="https://en.wikipedia.org/wiki/Textile_(markup_language)" title="Textile">link</a>.</p>
<p>This is another <a href="https://en.wikipedia.org/wiki/Textile_(markup_language)" title="Textile">link</a>.</p>
<p><a href="./image/cat1).png" title="title">link</a></p>

View File

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

View File

@ -0,0 +1,5 @@
<p><a href="./images(1)/cat(1).png">link</a></p>
<p><a href="./images(1)/cat(1).png" title="title">link</a></p>
<p><img src="./images(1)/cat(1).png" alt="image" /></p>
<p><img src="./images(1)/cat(1).png" alt="image" title="title" /></p>
<p><img src="./images(1)/cat(1).png" alt="image" title="title" width="800" height="600" /></p>

View File

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

View File

@ -0,0 +1,14 @@
<p><img src="images(1)/cat(1).png" alt="my cat" /></p>
<p><a href="images(1)/cat(1).png">my cat</a></p>
<p><img src="some.com/crazy url with spaces" alt="foo" /></p>
<p><img src="some.com/crazy url with spaces" alt="foo" title="title" /></p>
<p><a href="some.com/crazy url with spaces">foo</a></p>
<p><a href="some.com/crazy url with spaces" title="title">foo</a></p>
<p><img src="" alt="empty" /></p>
<p><a href="">empty</a></p>
<p><img src="" alt="empty" title="title" /></p>
<p><a href="" title="title">empty</a></p>
<p><img src="" alt="empty" /></p>
<p><a href="">empty</a></p>
<p><img src="" alt="empty" title="title" /></p>
<p><a href="" title="title">empty</a></p>

27
test/issues/crazy-urls.md Normal file
View File

@ -0,0 +1,27 @@
![my cat](<images(1)/cat(1).png>)
[my cat](<images(1)/cat(1).png>)
![foo](<some.com/crazy url with spaces>)
![foo](<some.com/crazy url with spaces> "title")
[foo](<some.com/crazy url with spaces>)
[foo](<some.com/crazy url with spaces> "title")
![empty](<>)
[empty](<>)
![empty](<> "title")
[empty](<> "title")
![empty](< >)
[empty](< >)
![empty](< > "title")
[empty](< > "title")