diff --git a/lib/marked.js b/lib/marked.js index 9d7c1555f3..39c25f2610 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -546,7 +546,7 @@ var inline = { code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, br: /^( {2,}|\\)\n(?!\s*$)/, del: noop, - text: /^(`+|[^`])[\s\S]*?(?=[\\a${' '.repeat(50000)}

` +}; diff --git a/test/redos/quadratic_email.js b/test/redos/quadratic_email.js new file mode 100644 index 0000000000..08243fe5fa --- /dev/null +++ b/test/redos/quadratic_email.js @@ -0,0 +1,4 @@ +module.exports = { + markdown: 'a'.repeat(50000), + html: `

${'a'.repeat(50000)}

` +}; diff --git a/test/specs/gfm/gfm.0.28.json b/test/specs/gfm/gfm.0.28.json index f9c28eb2ab..75bffc64ce 100644 --- a/test/specs/gfm/gfm.0.28.json +++ b/test/specs/gfm/gfm.0.28.json @@ -141,8 +141,7 @@ "section": "Autolinks", "html": "

a.b-c_d@a.b

\n

a.b-c_d@a.b.

\n

a.b-c_d@a.b-

\n

a.b-c_d@a.b_

", "markdown": "a.b-c_d@a.b\n\na.b-c_d@a.b.\n\na.b-c_d@a.b-\n\na.b-c_d@a.b_", - "example": 607, - "shouldFail": true + "example": 607 }, { "section": "Disallowed Raw HTML", diff --git a/test/specs/redos-spec.js b/test/specs/redos-spec.js new file mode 100644 index 0000000000..1f94a42e99 --- /dev/null +++ b/test/specs/redos-spec.js @@ -0,0 +1,24 @@ +const path = require('path'); +const fs = require('fs'); + +const redosDir = path.resolve(__dirname, '../redos'); + +describe('ReDOS tests', () => { + const files = fs.readdirSync(redosDir); + files.forEach(file => { + if (!file.match(/\.js$/)) { + return; + } + + it(file, () => { + const spec = require(path.resolve(redosDir, file)); + const before = process.hrtime(); + expect(spec).toRender(spec.html); + const elapsed = process.hrtime(before); + if (elapsed[0] > 0) { + const s = (elapsed[0] + elapsed[1] * 1e-9).toFixed(3); + fail(`took too long: ${s}s`); + } + }); + }); +});