diff --git a/src/rules.js b/src/rules.js index d8b60c7d4b..bb8b384884 100644 --- a/src/rules.js +++ b/src/rules.js @@ -25,7 +25,7 @@ export const block = { + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag + '|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag + ')', - def: /^ {0,3}\[(label)\]: *\n? *]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/, + def: /^ {0,3}\[(label)\]: *(?:\n *)?]+)>?(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/, table: noopTest, lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/, // regex template, placeholders will be replaced according to different paragraph @@ -34,7 +34,7 @@ export const block = { text: /^[^\n]+/ }; -block._label = /(?!\s*\])(?:\\[\[\]]|[^\[\]])+/; +block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/; block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/; block.def = edit(block.def) .replace('label', block._label) @@ -162,8 +162,8 @@ export const inline = { + '|^' // declaration, e.g. + '|^', // CDATA section link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/, - reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/, - nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/, + reflink: /^!?\[(label)\]\[(ref)\]/, + nolink: /^!?\[(ref)\](?:\[\])?/, reflinkSearch: 'reflink|nolink(?!\\()', emStrong: { lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/, @@ -230,6 +230,11 @@ inline.link = edit(inline.link) inline.reflink = edit(inline.reflink) .replace('label', inline._label) + .replace('ref', block._label) + .getRegex(); + +inline.nolink = edit(inline.nolink) + .replace('ref', block._label) .getRegex(); inline.reflinkSearch = edit(inline.reflinkSearch, 'g') diff --git a/test/specs/redos/cubic_def.cjs b/test/specs/redos/cubic_def.cjs new file mode 100644 index 0000000000..eb3110bc86 --- /dev/null +++ b/test/specs/redos/cubic_def.cjs @@ -0,0 +1,4 @@ +module.exports = { + markdown: `[x]:${' '.repeat(1500)}x ${' '.repeat(1500)} x`, + html: `

[x]:${' '.repeat(1500)}x ${' '.repeat(1500)} x

`, +}; diff --git a/test/specs/redos/reflink_redos.html b/test/specs/redos/reflink_redos.html new file mode 100644 index 0000000000..2815c0f7b6 --- /dev/null +++ b/test/specs/redos/reflink_redos.html @@ -0,0 +1 @@ +

[[]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([]([

diff --git a/test/specs/redos/reflink_redos.md b/test/specs/redos/reflink_redos.md new file mode 100644 index 0000000000..fe1f0cf08c --- /dev/null +++ b/test/specs/redos/reflink_redos.md @@ -0,0 +1,3 @@ +[x]: x + +[\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\](\[\]([