Skip to content

Commit

Permalink
Limit the recursion in autolink extension. (#125)
Browse files Browse the repository at this point in the history
This is not really a bug, but it's possible to send an input markdown
consisting of lots of @ signs, and the recursion will cause memory
explosion. The limit depends on the running environment, but there is no
reason to accept arbitrarily long sequence of @, so let's just cut off
at 1000.
  • Loading branch information
Xadeck authored and Ashe Connor committed Oct 17, 2018
1 parent b863aca commit 829f27c
Showing 1 changed file with 10 additions and 6 deletions.
16 changes: 10 additions & 6 deletions extensions/autolink.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,11 @@ static cmark_node *match(cmark_syntax_extension *ext, cmark_parser *parser,
// inline was finished in inlines.c.
}

static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset) {
static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset, int depth) {
// postprocess_text can recurse very deeply if there is a very long line of
// '@' only. Stop at a reasonable depth to ensure it cannot crash.
if (depth > 1000) return;

size_t link_end;
uint8_t *data = text->as.literal.data,
*at;
Expand Down Expand Up @@ -307,7 +311,7 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset)
}

if (rewind == 0 || ns > 0) {
postprocess_text(parser, text, max_rewind + 1 + offset);
postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1);
return;
}

Expand All @@ -327,14 +331,14 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset)

if (link_end < 2 || nb != 1 || np == 0 ||
(!cmark_isalpha(data[link_end - 1]) && data[link_end - 1] != '.')) {
postprocess_text(parser, text, max_rewind + 1 + offset);
postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1);
return;
}

link_end = autolink_delim(data, link_end);

if (link_end == 0) {
postprocess_text(parser, text, max_rewind + 1 + offset);
postprocess_text(parser, text, max_rewind + 1 + offset, depth + 1);
return;
}

Expand Down Expand Up @@ -369,7 +373,7 @@ static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset)
text->as.literal.len = offset + max_rewind - rewind;
text->as.literal.data[text->as.literal.len] = 0;

postprocess_text(parser, post, 0);
postprocess_text(parser, post, 0, depth + 1);
}

static cmark_node *postprocess(cmark_syntax_extension *ext, cmark_parser *parser, cmark_node *root) {
Expand All @@ -396,7 +400,7 @@ static cmark_node *postprocess(cmark_syntax_extension *ext, cmark_parser *parser
}

if (ev == CMARK_EVENT_ENTER && node->type == CMARK_NODE_TEXT) {
postprocess_text(parser, node, 0);
postprocess_text(parser, node, 0, /*depth*/0);
}
}

Expand Down

0 comments on commit 829f27c

Please sign in to comment.