diff options
author | John MacFarlane <jgm@berkeley.edu> | 2015-02-19 22:55:02 -0800 |
---|---|---|
committer | John MacFarlane <jgm@berkeley.edu> | 2015-02-19 22:55:02 -0800 |
commit | 5af9f2717274efe5e2aebfe6a8154d700ec7e471 (patch) | |
tree | df460ee82d454c76ba815da123308e8d0dfb8778 | |
parent | 0fdb06f275aeb67331fd0984d89227ecadeeb26e (diff) |
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.
-rw-r--r-- | src/blocks.c | 7 |
1 files changed, 5 insertions, 2 deletions
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 |