- Commit
- aad831e87c92530fe54b7dcdda593c53ccc3f0b6
- Parent
- 17e4a8203dc24ecee990ba3e8880092a1864e12e
- Author
- John MacFarlane <jgm@berkeley.edu>
- Date
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?
diff --git 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 ||