From 5af9f2717274efe5e2aebfe6a8154d700ec7e471 Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Thu, 19 Feb 2015 22:55:02 -0800 Subject: Fixed use-after-free error. Closes #9, confirmed with ASAN. Avoid using `parser->current` in the loop that creates new blocks, since `finalize` in `add_child` may have removed the current parser (if it contains only reference definitions). This isn't a great solution; in the long run we need to rewrite to make the logic clearer and to make it harder to make mistakes like this one. --- src/blocks.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/blocks.c b/src/blocks.c index 6e2f97a..b5b1e3e 100644 --- a/src/blocks.c +++ b/src/blocks.c @@ -527,6 +527,7 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, size_t bytes) int first_nonspace; int indent; cmark_chunk input; + bool maybe_lazy; utf8proc_detab(parser->curline, buffer, bytes); @@ -646,7 +647,8 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, size_t bytes) break_out_of_lists(parser, &container); } - // unless last matched container is code cmark_node, try new container starts: + maybe_lazy = parser->current->type == NODE_PARAGRAPH; + // try new container starts: while (container->type != NODE_CODE_BLOCK && container->type != NODE_HTML) { @@ -658,7 +660,7 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, size_t bytes) blank = peek_at(&input, first_nonspace) == '\n'; if (indent >= CODE_INDENT) { - if (parser->current->type != NODE_PARAGRAPH && !blank) { + if (!maybe_lazy && !blank) { offset += CODE_INDENT; container = add_child(parser, container, NODE_CODE_BLOCK, offset + 1); container->as.code.fenced = false; @@ -773,6 +775,7 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, size_t bytes) // if it's a line container, it can't contain other containers break; } + maybe_lazy = false; } // what remains at offset is a text line. add the text to the -- cgit v1.2.3