cmark

My personal build of CMark ✏️

Commit
c3f9a7caecbf5239f29b6fd1a7edf47df4fc6d21
Parent
15422f68253bd5d877f0b308b1bf6caec6e0eb79
Author
John MacFarlane <jgm@berkeley.edu>
Date

Add EMPHASIS_STACK_LIMIT.

If we get more than 1000 deep in potential emphasis/strong emphasis openers, we refuse to add more to the stack. This prevents the sort of stack overflow we previously got with

python -c 'print "*a **a " * 100000; print " a** a*" * 100000' | ./cmark

Partially addresses #166.

Diffstat

2 files changed, 7 insertions, 1 deletion

Status File Name N° Changes Insertions Deletions
Modified src/cmark.h 1 1 0
Modified src/inlines.c 7 6 1
diff --git a/src/cmark.h b/src/cmark.h
@@ -9,6 +9,7 @@
 
 #define VERSION "0.1"
 #define CODE_INDENT 4
+#define EMPHASIS_STACK_LIMIT 1000
 
 struct node_inl {
 	enum {
diff --git a/src/inlines.c b/src/inlines.c
@@ -23,6 +23,7 @@ typedef struct Subject {
 	int label_nestlevel;
 	reference_map *refmap;
 	inline_stack *emphasis_openers;
+	int number_of_emphasis_openers;
 } subject;
 
 static node_inl *parse_chunk_inlines(chunk *chunk, reference_map *refmap);
@@ -177,6 +178,7 @@ static void subject_from_buf(subject *e, strbuf *buffer, reference_map *refmap)
 	e->label_nestlevel = 0;
 	e->refmap = refmap;
 	e->emphasis_openers = NULL;
+	e->number_of_emphasis_openers = 0;
 
 	chunk_rtrim(&e->input);
 }
@@ -190,6 +192,7 @@ static void subject_from_chunk(subject *e, chunk *chunk, reference_map *refmap)
 	e->label_nestlevel = 0;
 	e->refmap = refmap;
 	e->emphasis_openers = NULL;
+	e->number_of_emphasis_openers = 0;
 
 	chunk_rtrim(&e->input);
 }
@@ -309,6 +312,7 @@ static void free_openers(subject* subj, inline_stack* istack)
     while (subj->emphasis_openers != istack) {
 	tempstack = subj->emphasis_openers;
 	subj->emphasis_openers = subj->emphasis_openers->previous;
+	subj->number_of_emphasis_openers--;
 	free(tempstack);
     }
 }
@@ -389,7 +393,7 @@ static node_inl* handle_strong_emph(subject* subj, unsigned char c, node_inl **l
 cannotClose:
 	inl_text = make_str(chunk_dup(&subj->input, subj->pos - numdelims, numdelims));
 
-	if (can_open)
+	if (can_open && subj->number_of_emphasis_openers < EMPHASIS_STACK_LIMIT)
 	{
 		istack = (inline_stack*)malloc(sizeof(inline_stack));
                 if (istack == NULL) {
@@ -400,6 +404,7 @@ cannotClose:
 		istack->first_inline = inl_text;
 		istack->previous = subj->emphasis_openers;
 		subj->emphasis_openers = istack;
+		subj->number_of_emphasis_openers++;
 	}
 
 	return inl_text;