Skip to content

Improve worst-case performance of inline.text regex - #1460

Merged
UziTech merged 1 commit into
markedjs:masterfrom
andersk:inline-text-quadratic
Apr 5, 2019
Merged

Improve worst-case performance of inline.text regex#1460
UziTech merged 1 commit into
markedjs:masterfrom
andersk:inline-text-quadratic

Conversation

@andersk

Copy link
Copy Markdown
Contributor

The old regex may take quadratic time to scan for potential email addresses starting at every point. Fix it to avoid scanning from points that would have been in the middle of a previous scan.

Marked version:

0.1.3 and later (problem introduced by commit 00f1f7a)

Markdown flavor: GitHub Flavored Markdown

Description

  • Fixes DoS issue reported privately.

Contributor

  • Test(s) exist to ensure functionality and minimize regression (if no tests added, list tests covering this PR); or,
  • no tests required for this PR.
  • If submitting new feature, it has been documented in the appropriate places.

Committer

In most cases, this should be a different person than the contributor.

  • Draft GitHub release notes have been updated.
  • CI is green (no forced merge required).
  • Merge PR

@UziTech

UziTech commented Apr 3, 2019

Copy link
Copy Markdown
Member

actual diff of gfm inline.text

- /^(`+|[^`])[\s\S]*?(?=[\\<!\[`*~]|\b_| {2,}\n|https?:\/\/|ftp:\/\/|www\.|[a-zA-Z0-9.!#$%&'*+\/=?^_`{\|}~-]+@|$)/+ /^(`+|[^`])(?:[\s\S]*?(?:(?=[\\<!\[`*~]|\b_| {2,}\n|https?:\/\/|ftp:\/\/|www\.|$)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))/

@UziTechUziTech left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a redos test in /test/redos/ that will fail before this change and pass after?

@andersk
anderskforce-pushed the inline-text-quadratic branch from 175fae6 to 18dbc0bCompareApril 3, 2019 23:44
@andersk

Copy link
Copy Markdown
ContributorAuthor

(Updated to address a separate quadratic slowdown in the same regex.)

@UziTech Do you want me to literally drop in a gigantic .md file consisting of aaaaaaaaaaaaa…, or should we find a way to test this more intelligently?

@UziTech

Copy link
Copy Markdown
Member

Tests that take longer than 1 second are marked as failed. maybe slim it down to a test taking 2 seconds before this fix.

@andersk
anderskforce-pushed the inline-text-quadratic branch from 18dbc0b to bd789b3CompareApril 4, 2019 00:00
@andersk

Copy link
Copy Markdown
ContributorAuthor

@UziTech Done.

@UziTechUziTech left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this 💯 🏅

Comment threadlib/marked.js Outdated
The old regex may take quadratic time to scan for potential line
breaks or email addresses starting at every point. Fix it to avoid
scanning from points that would have been in the middle of a previous
scan.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
@andersk
anderskforce-pushed the inline-text-quadratic branch from 830413b to be27472CompareApril 4, 2019 18:14
@UziTech
UziTech requested a review from davisjamApril 4, 2019 20:23
@UziTech

Copy link
Copy Markdown
Member

@davisjam do you want to look at this and make sure no redos vectors are added?

Comment threadlib/marked.js
br: /^( {2,}|\\)\n(?!\s*$)/,
del: noop,
text: /^(`+|[^`])[\s\S]*?(?=[\\<!\[`*]|\b_|{2,}\n|$)/
text: /^(`+|[^`])(?:[\s\S]*?(?:(?=[\\<!\[`*]|\b_|$)|[^ ](?= {2,}\n))|(?= {2,}\n))/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is safe

Comment threadlib/marked.js
.replace(']|', '~]|')
.replace('|$', '|https?://|ftp://|www\\.|[a-zA-Z0-9.!#$%&\'*+/=?^_`{\\|}~-]+@|$')
.getRegex()
text: /^(`+|[^`])(?:[\s\S]*?(?:(?=[\\<!\[`*~]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))|(?= {2,}\n|[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is safe

@davisjamdavisjam left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@UziTech
UziTech merged commit b1ddd3c into markedjs:masterApr 5, 2019
@UziTech

Copy link
Copy Markdown
Member

This will be released in v0.6.2 🎉 #1441

Logiclayer1111 pushed a commit to Logiclayer1111/marked that referenced this pull request Apr 20, 2026
Cannot use **(WhiteSpace)(WhiteSpace)(Return)** to break line while only one characher before it.
And if use special character, it will reset the character count
brought by [#1460](markedjs/marked#1460)
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@andersk@UziTech@davisjam