diff --git a/lib/marked.js b/lib/marked.js index ce8e033e95..196b2b9259 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -542,7 +542,7 @@ var inline = { + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. + '|^' // declaration, e.g. + '|^', // CDATA section - link: /^!?\[(label)\]\(href(?:\s+(title))?\s*\)/, + link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/, reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/, nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/, strong: /^__([^\s_])__(?!_)|^\*\*([^\s*])\*\*(?!\*)|^__([^\s][\s\S]*?[^\s])__(?!_)|^\*\*([^\s][\s\S]*?[^\s])\*\*(?!\*)/, @@ -574,8 +574,8 @@ inline.tag = edit(inline.tag) .replace('attribute', inline._attribute) .getRegex(); -inline._label = /(?:\[[^\[\]]*\]|\\[\[\]]?|`[^`]*`|`(?!`)|[^\[\]\\`])*?/; -inline._href = /\s*(<(?:\\[<>]?|[^\s<>\\])*>|[^\s\x00-\x1f]*)/; +inline._label = /(?:\[[^\[\]]*\]|\\.|`[^`]*`|[^\[\]\\`])*?/; +inline._href = /<(?:\\[<>]?|[^\s<>\\])*>|[^\s\x00-\x1f]*/; inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/; inline.link = edit(inline.link) diff --git a/test/specs/commonmark/commonmark.0.29.json b/test/specs/commonmark/commonmark.0.29.json index e4f58e8aec..1d3071112b 100644 --- a/test/specs/commonmark/commonmark.0.29.json +++ b/test/specs/commonmark/commonmark.0.29.json @@ -2775,8 +2775,7 @@ "example": 342, "start_line": 6012, "end_line": 6016, - "section": "Code spans", - "shouldFail": true + "section": "Code spans" }, { "markdown": "``\n", @@ -4266,8 +4265,7 @@ "example": 521, "start_line": 7887, "end_line": 7891, - "section": "Links", - "shouldFail": true + "section": "Links" }, { "markdown": "[foo\n", @@ -4368,8 +4366,7 @@ "example": 533, "start_line": 8041, "end_line": 8047, - "section": "Links", - "shouldFail": true + "section": "Links" }, { "markdown": "[foo\n\n[ref]: /uri\n", diff --git a/test/specs/gfm/commonmark.0.29.json b/test/specs/gfm/commonmark.0.29.json index 885da2d835..eb0b005b4b 100644 --- a/test/specs/gfm/commonmark.0.29.json +++ b/test/specs/gfm/commonmark.0.29.json @@ -2775,8 +2775,7 @@ "example": 342, "start_line": 6012, "end_line": 6016, - "section": "Code spans", - "shouldFail": true + "section": "Code spans" }, { "markdown": "``\n", @@ -4266,8 +4265,7 @@ "example": 521, "start_line": 7887, "end_line": 7891, - "section": "Links", - "shouldFail": true + "section": "Links" }, { "markdown": "[foo\n", @@ -4368,8 +4366,7 @@ "example": 533, "start_line": 8041, "end_line": 8047, - "section": "Links", - "shouldFail": true + "section": "Links" }, { "markdown": "[foo\n\n[ref]: /uri\n", diff --git a/test/specs/new/nested_square_link.md b/test/specs/new/nested_square_link.md index 0f311e9516..9354ec400a 100644 --- a/test/specs/new/nested_square_link.md +++ b/test/specs/new/nested_square_link.md @@ -1,3 +1,3 @@ [the `]` character](/url) -[the ` character](/url) +[the \` character](/url) diff --git a/test/specs/redos/link_code.html b/test/specs/redos/link_code.html new file mode 100644 index 0000000000..f936665d20 --- /dev/null +++ b/test/specs/redos/link_code.html @@ -0,0 +1 @@ +

INDEX(string, pattern[, start): searches for the first occurrence of pattern in string, starting from start:INDEX("123123", "23", 3)==5INSERT(new, old[, start][, length][, pad]): inserts the new string into the old string after the specified position (default is 0), new string is truncated or padded (default is " ") to the specified length, if start is beyond the end of old old will be paddedLASTPOS(pattern, string[, start]): searches backwards for the last occurrence of pattern in string, starting from start:LASTPOS("123123", "23", 4)==2LINES(file): returns the number of lines typed ahead at the interactive stream:push("a line"); push("second line"); lines(STDIN); /* == 2 */MAX(number, number[, number,...]): obviousMIN(number, number[, number,...]): obviousOPEN(filehandle, filename[, "APPEND"|"READ"|"WRITE"]): opens file, returns boolean for success:OPEN("MyCon", "CON:160/50/320/100/MyCon/CDS")==1OVERLAY(new, old[, start][, length][, pad]): overlays new string onto old one at start for length chars padding with pad if necessary:OVERLAY("4", "123", 5, 5)=="123-4----"POS(pattern, string[, start])` : same as index

diff --git a/test/specs/redos/link_code.md b/test/specs/redos/link_code.md new file mode 100644 index 0000000000..4e9298a5f8 --- /dev/null +++ b/test/specs/redos/link_code.md @@ -0,0 +1,9 @@ +INDEX(string, pattern[, start)` : searches for the first occurrence of pattern in string, starting from start: `INDEX("123123", "23", 3)` == `5` +`INSERT(new, old[, start][, length][, pad])` : inserts the new string into the old string after the specified position (default is 0), new string is truncated or padded (default is " ") to the specified length, if start is beyond the end of old old will be padded +`LASTPOS(pattern, string[, start])` : searches backwards for the last occurrence of pattern in string, starting from start: `LASTPOS("123123", "23", 4)` == `2` +`LINES(file)` : returns the number of lines typed ahead at the interactive stream: `push("a line"); push("second line"); lines(STDIN); /* == 2 */` +`MAX(number, number[, number,...])` : obvious +`MIN(number, number[, number,...])` : obvious +`OPEN(filehandle, filename[, "APPEND"|"READ"|"WRITE"])` : opens file, returns boolean for success: `OPEN("MyCon", "CON:160/50/320/100/MyCon/CDS")` == `1` +`OVERLAY(new, old[, start][, length][, pad])` : overlays new string onto old one at start for length chars padding with pad if necessary: `OVERLAY("4", "123", 5, 5)` == `"123-4----"` +`POS(pattern, string[, start])` : same as index