commit 035dea495b814709eea8cfbea7cc4589d0a3c0f8
parent 578dea5b81474bb16ac66cf79cf876c5e8be77bf
Author: Martin Mitas <mity@morous.org>
Date: Sun, 4 Dec 2016 20:48:06 +0100
Fix crash caused by bad management of opener chains.
1. We need to reset (potentially used) chains after each mark analysis
phase. This ensures that md_rollback() does not try to play with
chains used in previous phases.
2. md_rollback() must never play with PTR_CHAIN.
Diffstat:
| M | md4c/md4c.c | | | 39 | ++++++++++++++++++++++++++------------- |
1 file changed, 26 insertions(+), 13 deletions(-)
diff --git a/md4c/md4c.c b/md4c/md4c.c
@@ -2074,8 +2074,9 @@ md_rollback(MD_CTX* ctx, int opener_index, int closer_index, int how)
int i;
int mark_index;
- /* Cut all unresolved openers at the mark index. */
- for(i = 0; i < SIZEOF_ARRAY(ctx->mark_chains); i++) {
+ /* Cut all unresolved openers at the mark index.
+ * (start at 1 to not touch PTR_CHAIN.) */
+ for(i = 1; i < SIZEOF_ARRAY(ctx->mark_chains); i++) {
MD_MARKCHAIN* chain = &ctx->mark_chains[i];
while(chain->tail >= opener_index)
@@ -3151,7 +3152,6 @@ md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF en
static int
md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
{
- int i;
int ret;
OFF beg = lines[0].beg;
OFF end = lines[n_lines-1].end;
@@ -3159,14 +3159,6 @@ md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
/* Reset the previously collected stack of marks. */
ctx->n_marks = 0;
- /* Reset all unresolved opener mark chains. */
- for(i = 0; i < SIZEOF_ARRAY(ctx->mark_chains); i++) {
- ctx->mark_chains[i].head = -1;
- ctx->mark_chains[i].tail = -1;
- }
- ctx->unresolved_link_head = -1;
- ctx->unresolved_link_tail = -1;
-
/* Collect all marks. */
if(md_collect_marks(ctx, lines, n_lines) != 0)
return -1;
@@ -3174,11 +3166,23 @@ md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
/* We analyze marks in few groups to handle their precedence. */
/* (1) Entities; code spans; autolinks; raw HTML. */
md_analyze_marks(ctx, lines, n_lines, beg, end, _T("&`<>"));
+ BACKTICK_OPENERS.head = -1;
+ BACKTICK_OPENERS.tail = -1;
+ LOWERTHEN_OPENERS.head = -1;
+ LOWERTHEN_OPENERS.tail = -1;
/* (2) Links. */
md_analyze_marks(ctx, lines, n_lines, beg, end, _T("[]!"));
MD_CHECK(md_resolve_links(ctx, lines, n_lines));
+ BRACKET_OPENERS.head = -1;
+ BRACKET_OPENERS.tail = -1;
+ ctx->unresolved_link_head = -1;
+ ctx->unresolved_link_tail = -1;
/* (3) Emphasis and strong emphasis; permissive autolinks. */
md_analyze_marks(ctx, lines, n_lines, beg, end, _T("*_@:"));
+ ASTERISK_OPENERS.head = -1;
+ ASTERISK_OPENERS.tail = -1;
+ UNDERSCORE_OPENERS.head = -1;
+ UNDERSCORE_OPENERS.tail = -1;
abort:
return ret;
@@ -3188,8 +3192,6 @@ static void
md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF end)
{
md_analyze_marks(ctx, lines, n_lines, beg, end, _T("*_@:"));
-
- /* Reset the chains we could use. */
ASTERISK_OPENERS.head = -1;
ASTERISK_OPENERS.tail = -1;
UNDERSCORE_OPENERS.head = -1;
@@ -3703,6 +3705,8 @@ abort:
/* Free any temporary memory blocks stored within some dummy marks. */
for(i = PTR_CHAIN.head; i >= 0; i = ctx->marks[i].next)
free(md_mark_get_ptr(ctx, i));
+ PTR_CHAIN.head = -1;
+ PTR_CHAIN.tail = -1;
return ret;
}
@@ -5216,6 +5220,7 @@ int
md_parse(const MD_CHAR* text, MD_SIZE size, const MD_RENDERER* renderer, void* userdata)
{
MD_CTX ctx;
+ int i;
int ret;
/* Setup context structure. */
@@ -5227,6 +5232,14 @@ md_parse(const MD_CHAR* text, MD_SIZE size, const MD_RENDERER* renderer, void* u
ctx.code_indent_offset = (ctx.r.flags & MD_FLAG_NOINDENTEDCODEBLOCKS) ? (OFF)(-1) : 4;
md_build_mark_char_map(&ctx);
+ /* Reset all unresolved opener mark chains. */
+ for(i = 0; i < SIZEOF_ARRAY(ctx.mark_chains); i++) {
+ ctx.mark_chains[i].head = -1;
+ ctx.mark_chains[i].tail = -1;
+ }
+ ctx.unresolved_link_head = -1;
+ ctx.unresolved_link_tail = -1;
+
/* All the work. */
ret = md_process_doc(&ctx);