Skip to content
Permalink
Browse files Browse the repository at this point in the history
inlineCode: Fix ReDoS & improve escape semantics
Our inline code regex had overlapping parts in the case of spaces;
spaces could be parsed as part of the `\s*`s or as part of the
`[\S\s]*`, which leads to catastrophic backtracking in the case of
a string with many spaces.

The `\s*` parts were attempting to allow for escaping of backticks
within the start/end of inline code blocks, so this commit removes
the `\s*` parts of the regex, and then after parsing the code block,
checks for the case where a single space is being used to escape
a backtick, and removes that space.

Test plan:

1. Added a test for the semantics change.
2. Added a test for the exponential backtracking to match the test
   case in issue #71
  • Loading branch information
ariabuckles committed Aug 31, 2019
1 parent a52c270 commit 89797fe
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
20 changes: 20 additions & 0 deletions __tests__/simple-markdown-test.js
Expand Up @@ -550,6 +550,26 @@ describe("simple markdown", function() {
}]);
});

it("should ignore a single space at the start and end of an inline code block separating a '`'", function() {
var parsed1 = inlineParse(
"test `` ` `` escaping a code block"
);
validateParse(parsed1, [
{type: "text", content: "test "},
{type: "inlineCode", content: "`"},
{type: "text", content: " escaping a code block"},
]);

var parsed1 = inlineParse(
"test `` ` `` escaping a code block"
);
validateParse(parsed1, [
{type: "text", content: "test "},
{type: "inlineCode", content: " ` "},
{type: "text", content: " escaping a code block"},
]);
});

it("should allow you to escape special characters with \\", function() {
var parsed = inlineParse(
"\\`hi\\` \\*bye\\* \\~\\|\\<\\[\\{"
Expand Down
5 changes: 3 additions & 2 deletions simple-markdown.js
Expand Up @@ -640,6 +640,7 @@ var LIST_ITEM_R = new RegExp(
"gm"
);
var BLOCK_END_R = /\n{2,}$/;
var INLINE_CODE_ESCAPE_BACKTICKS_R = /^ ( *` *) $|^ ( *`)|(` *) $/g;
// recognize the end of a paragraph block inside a list item:
// two or more newlines at end end of the item
var LIST_BLOCK_END_R = BLOCK_END_R;
Expand Down Expand Up @@ -1581,10 +1582,10 @@ var defaultRules /* : DefaultRules */ = {
},
inlineCode: {
order: currOrder++,
match: inlineRegex(/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/),
match: inlineRegex(/^(`+)([\s\S]*?[^`])\1(?!`)/),
parse: function(capture, parse, state) {
return {
content: capture[2]
content: capture[2].replace(INLINE_CODE_ESCAPE_BACKTICKS_R, "$1")
};
},
react: function(node, output, state) {
Expand Down

0 comments on commit 89797fe

Please sign in to comment.