add code to do maximum recursion depth, and default it to 200

This commit is contained in:
jessica parsons
2026-06-16 01:54:15 -07:00
parent e7da52abbf
commit 2ae87732d9
7 changed files with 88 additions and 3 deletions
+6 -1
View File
@@ -31,7 +31,7 @@ OBJS=mkdio.o markdown.o dumptree.o generate.o \
github_flavoured.o setup.o tags.o html5.o \ github_flavoured.o setup.o tags.o html5.o \
pgm_options.o flags.o v2compat.o flagprocs.o \ pgm_options.o flags.o v2compat.o flagprocs.o \
@AMALLOC@ @H1TITLE@ @AMALLOC@ @H1TITLE@
TESTFRAMEWORK=rep echo cols branch pandoc_headers space2nl TESTFRAMEWORK=300 rep echo cols branch pandoc_headers space2nl
# modules that markdown, makepage, mkd2html, &tc use # modules that markdown, makepage, mkd2html, &tc use
COMMON=gethopt.o notspecial.o COMMON=gethopt.o notspecial.o
@@ -152,6 +152,11 @@ rep.o : tools/rep.c
rep: rep.o rep: rep.o
$(LINK) -o rep rep.o $(LINK) -o rep rep.o
300.o : tools/300.c
$(BUILD) -c -o 300.o tools/300.c
300: 300.o
$(LINK) -o 300 300.o
branch.o: tools/branch.c config.h branch.o: tools/branch.c config.h
$(BUILD) -c -o branch.o tools/branch.c $(BUILD) -c -o branch.o tools/branch.c
branch: branch.o branch: branch.o
+6
View File
@@ -13,6 +13,7 @@ ac_help='--enable-amalloc Enable memory allocation debugging
--container Build inside a container --container Build inside a container
--pkg-config Install pkg-config(1) glue files --pkg-config Install pkg-config(1) glue files
--cxx-binding Install header files with c++ wrappers --cxx-binding Install header files with c++ wrappers
--with-recursion=NNN how deeply things can nest before the become just text
--github-checkbox[=input] Enable github-style checkboxes in lists --github-checkbox[=input] Enable github-style checkboxes in lists
(if =input, use <input checkbox>, otherwise (if =input, use <input checkbox>, otherwise
use html ballot entities)' use html ballot entities)'
@@ -238,6 +239,11 @@ else
AC_SUB 'THEME' '#' AC_SUB 'THEME' '#'
fi fi
if [ -z "$WITH_RECURSION" ]; then
WITH_RECURSION=200
fi
AC_DEFINE 'MAX_RECURSION' $WITH_RECURSION
if [ -z "$WITH_TABSTOPS" ]; then if [ -z "$WITH_TABSTOPS" ]; then
TABSTOP=4 TABSTOP=4
elif [ "$WITH_TABSTOPS" -eq 1 ]; then elif [ "$WITH_TABSTOPS" -eq 1 ]; then
+3 -1
View File
@@ -235,6 +235,7 @@ ___mkd_reparse(char *bfr, int size, mkd_flag_t* flags, MMIOT *f, char *esc)
pushc(0, &sub); pushc(0, &sub);
S(sub.in)--; S(sub.in)--;
sub.recursion = f->recursion+1;
text(&sub); text(&sub);
___mkd_emblock(&sub); ___mkd_emblock(&sub);
@@ -1476,7 +1477,8 @@ text(MMIOT *f)
|| (f->last == 0) || (f->last == 0)
|| ((ispunct(f->last) || isspace(f->last)) || ((ispunct(f->last) || isspace(f->last))
&& f->last != ')') && f->last != ')')
|| isthisspace(f,1) ) || isthisspace(f,1)
|| f->recursion > MAX_RECURSION )
Qchar(c,f); Qchar(c,f);
else { else {
char *sup = cursor(f); char *sup = cursor(f);
+7 -1
View File
@@ -1434,9 +1434,14 @@ compile(Line *ptr, int toplevel, MMIOT *f)
ptr = consume(ptr, &para); ptr = consume(ptr, &para);
++(f->recursion);
while ( ptr ) { while ( ptr ) {
if ( iscode(ptr) ) { if ( f->recursion > MAX_RECURSION ) {
p = Pp(&d, ptr, MARKUP);
ptr = textblock(p, toplevel, &(f->flags) );
}
else if ( iscode(ptr) ) {
p = Pp(&d, ptr, CODE); p = Pp(&d, ptr, CODE);
if ( is_flag_set(&(f->flags), MKD_1_COMPAT) ) { if ( is_flag_set(&(f->flags), MKD_1_COMPAT) ) {
@@ -1530,6 +1535,7 @@ compile(Line *ptr, int toplevel, MMIOT *f)
p->align = PARA; p->align = PARA;
} }
(f->recursion)--;
return T(d); return T(d);
} }
+1
View File
@@ -196,6 +196,7 @@ typedef struct mmiot {
Qblock Q; Qblock Q;
char last; /* last text character added to out */ char last; /* last text character added to out */
int isp; int isp;
int recursion;
struct escaped *esc; struct escaped *esc;
char *ref_prefix; char *ref_prefix;
struct footnote_list *footnotes; struct footnote_list *footnotes;
+29
View File
@@ -0,0 +1,29 @@
. tests/functions.sh
title 'Recursion limits'
rc=0
limits() {
try_header "$1"
res=`./300 400 $3 $4 $5 | ./markdown | tr -dc "$2" | wc -c`
if (( $res > 0 )); then
# it worked
test $VERBOSE && ./echo " ok"
else
test "$VERBOSE" && ./echo "failed"
rc=1
fi
}
limits "superscripts" "()" "2^(" "A" ")"
limits "list items" "1" "1. " "item"
limits "blockquotes" ">" "> " "item"
summary $0
exit $rc
+36
View File
@@ -0,0 +1,36 @@
#include <stdio.h>
#include <stdlib.h>
main(argc, argv)
int argc;
char **argv;
{
int reps;
int i;
char *pattern1, *text = NULL, *pattern2 = NULL;
if ( argc < 3 ) {
fprintf(stderr, "usage: 300 reps pattern1 [text [pattern2]]\n");
exit(1);
}
reps = atoi(argv[1]);
pattern1 = argv[2];
if ( argc > 3 )
text = argv[3];
if ( argc > 4 )
pattern2 = argv[4];
for ( i=0; i < reps; i++ )
printf("%s", pattern1);
if ( text )
printf(" %s ", text);
if ( pattern2 )
for ( i=0; i < reps; i++ )
printf("%s", pattern2);
putchar('\n');
}