Repository: showdownjs/showdown
Pull request #702 (2019-05-25 18:12:17)

fix link definition impostors
This change fixes an issue where we entirely strip out text that may be erroneously detected to be a link definition.  Without these changes, `converter.makeHtml('[Jim] said to [him]: Ahoy!')` returns an empty string.

To address this, we add two constraints when detecting link definitions...

1) Tighter regex matching the content of the square brackets.  Instead of `[(.+)]` we make sure the contents of the square brackets doesn't include square brackets with `[([^\]])`.  Otherwise for example with input `[a] [b] [c]` we match `a] [b] [c` as the linkId.

2) Back out if there are not two occurrences of the detected link id, since if there is no previous occurrence, it must not be a link definition.




Patch:
diff --git a/src/subParsers/makehtml/stripLinkDefinitions.js b/src/subParsers/makehtml/stripLinkDefinitions.js
index 350da9a..567fb57 100644
--- a/src/subParsers/makehtml/stripLinkDefinitions.js
+++ b/src/subParsers/makehtml/stripLinkDefinitions.js
@@ -6,14 +6,19 @@
 showdown.subParser('makehtml.stripLinkDefinitions', function (text, options, globals) {
   'use strict';
 
-  var regex       = /^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?([^>\s]+)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=¨0))/gm,
-      base64Regex = /^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n\n|(?=¨0)|(?=\n\[))/gm;
+  var regex       = /^ {0,3}\[([^\]]+)]:[ \t]*\n?[ \t]*<?([^>\s]+)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=¨0))/gm,
+      base64Regex = /^ {0,3}\[([^\]]+)]:[ \t]*\n?[ \t]*<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n\n|(?=¨0)|(?=\n\[))/gm;
 
   // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
   text += '¨0';
 
   var replaceFunc = function (wholeMatch, linkId, url, width, height, blankLines, title) {
+
+    // if there aren't two instances of linkId it must not be a reference link so back out
     linkId = linkId.toLowerCase();
+    if (text.toLowerCase().split(linkId).length - 1 < 2) {
+      return wholeMatch;
+    }
     if (url.match(/^data:.+?\/.+?;base64,/)) {
       // remove newlines
       globals.gUrls[linkId] = url.replace(/\s/g, '');


Test patch:
diff --git a/test/functional/makehtml/cases/issues/reference-link-impostors.html b/test/functional/makehtml/cases/issues/reference-link-impostors.html
new file mode 100644
index 0000000..706117a
--- /dev/null
+++ b/test/functional/makehtml/cases/issues/reference-link-impostors.html
@@ -0,0 +1,3 @@
+<p>[We] are going to show [you]: sunshine!</p>
+<p>[x]: take out the garbage<br />
+[ ]: bring up the coal</p>
diff --git a/test/functional/makehtml/cases/issues/reference-link-impostors.md b/test/functional/makehtml/cases/issues/reference-link-impostors.md
new file mode 100644
index 0000000..f71ed03
--- /dev/null
+++ b/test/functional/makehtml/cases/issues/reference-link-impostors.md
@@ -0,0 +1,4 @@
+[We] are going to show [you]: sunshine!
+
+[x]: take out the garbage  
+[ ]: bring up the coal