From aad831e87c92530fe54b7dcdda593c53ccc3f0b6 Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Thu, 19 Feb 2015 09:16:49 -0800 Subject: Fixed use-after-free bug. This arose when a paragraph containing only reference links and blank space was finalized. Finalization would remove the node. `finalize` returns the parent node, but the problem arose because we had both `cur` and `parser->current`, and only one was being updated. Solution: remove `cur`, which is a holdover from before we had `parser->current`. I believe this will close #9 -- @JordanMilne can you test and confirm? --- src/blocks.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/blocks.c b/src/blocks.c index c6a468f..6e2f97a 100644 --- a/src/blocks.c +++ b/src/blocks.c @@ -523,7 +523,6 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, size_t bytes) cmark_list *data = NULL; bool all_matched = true; cmark_node* container; - cmark_node* cur = parser->current; bool blank = false; int first_nonspace; int indent; @@ -659,7 +658,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 (cur->type != NODE_PARAGRAPH && !blank) { + if (parser->current->type != NODE_PARAGRAPH && !blank) { offset += CODE_INDENT; container = add_child(parser, container, NODE_CODE_BLOCK, offset + 1); container->as.code.fenced = false; @@ -809,20 +808,20 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, size_t bytes) cont = cont->parent; } - if (cur != last_matched_container && + if (parser->current != last_matched_container && container == last_matched_container && !blank && - cur->type == NODE_PARAGRAPH && - cmark_strbuf_len(&cur->string_content) > 0) { + parser->current->type == NODE_PARAGRAPH && + cmark_strbuf_len(&parser->current->string_content) > 0) { - add_line(cur, &input, offset); + add_line(parser->current, &input, offset); } else { // not a lazy continuation // finalize any blocks that were not matched and set cur to container: - while (cur != last_matched_container) { - cur = finalize(parser, cur); - assert(cur != NULL); + while (parser->current != last_matched_container) { + parser->current = finalize(parser, parser->current); + assert(parser->current != NULL); } if (container->type == NODE_CODE_BLOCK || -- cgit v1.2.3