Commit 0ac9f35d06650eb805d326c460d59ab638641f72

Martin Mitas 2024-01-16T09:53:41

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.

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++;
     }
 }