md_analyze_marks: Skip analyzing marks if... they fall into range of previously analyzed mark. That can happen if the previous mark has been expanded. That typically happens for permissive auto-links. This fixes one case of pathologic input leading to quadratic behavior.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
diff --git a/src/md4c.c b/src/md4c.c
index bdabef9..79b91f5 100644
--- a/src/md4c.c
+++ b/src/md4c.c
@@ -4016,6 +4016,8 @@ md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines,
int mark_beg, int mark_end, const CHAR* mark_chars)
{
int i = mark_beg;
+ OFF last_end = lines[0].beg;
+
MD_UNUSED(lines);
MD_UNUSED(n_lines);
@@ -4039,6 +4041,12 @@ md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines,
continue;
}
+ /* The resolving in previous step could have expanded a mark. */
+ if(mark->beg < last_end) {
+ i++;
+ continue;
+ }
+
/* Analyze the mark. */
switch(mark->ch) {
case '[': /* Pass through. */
@@ -4055,6 +4063,13 @@ md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines,
case '@': md_analyze_permissive_email_autolink(ctx, i); break;
}
+ if(mark->flags & MD_MARK_RESOLVED) {
+ if(mark->flags & MD_MARK_OPENER)
+ last_end = ctx->marks[mark->next].end;
+ else
+ last_end = mark->end;
+ }
+
i++;
}
}