From 9021725d5346d8cb8bda5cc5fad45959aba6f0de Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Sat, 26 May 2018 12:27:48 +0200 Subject: [PATCH] justification: limit the amount of recursion to prevent a stack overflow --- src/move.c | 4 ++-- src/proto.h | 2 +- src/text.c | 15 +++++++++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/move.c b/src/move.c index e6dfd7dc..f4264350 100644 --- a/src/move.c +++ b/src/move.c @@ -179,7 +179,7 @@ void do_para_begin(bool update_screen) if (openfile->current != openfile->fileage) openfile->current = openfile->current->prev; - while (!begpar(openfile->current)) + while (!begpar(openfile->current, 0)) openfile->current = openfile->current->prev; openfile->current_x = 0; @@ -204,7 +204,7 @@ void do_para_end(bool update_screen) while (openfile->current != openfile->filebot && inpar(openfile->current->next) && - !begpar(openfile->current->next)) { + !begpar(openfile->current->next, 0)) { openfile->current = openfile->current->next; } diff --git a/src/proto.h b/src/proto.h index 5681be22..afe6a437 100644 --- a/src/proto.h +++ b/src/proto.h @@ -551,7 +551,7 @@ size_t indent_length(const char *line); #endif #ifdef ENABLE_JUSTIFY void justify_format(filestruct *paragraph, size_t skip); -bool begpar(const filestruct *const foo); +bool begpar(const filestruct *const foo, int depth); bool inpar(const filestruct *const foo); void do_justify(bool full_justify); void do_justify_void(void); diff --git a/src/text.c b/src/text.c index fb94d69e..37bb6a86 100644 --- a/src/text.c +++ b/src/text.c @@ -1035,7 +1035,7 @@ void do_enter(void) /* If the next line is in this same paragraph, use its indentation * as the model, as it is more likely to be what the user wants. */ if (openfile->current->next && inpar(openfile->current->next) && - !begpar(openfile->current->next)) + !begpar(openfile->current->next, 0)) sampleline = openfile->current->next; extra = indent_length(sampleline->data); @@ -1983,8 +1983,11 @@ size_t quote_length(const char *line) return matches.rm_eo; } +/* The maximum depth of recursion. This must be an even number. */ +#define RECURSION_LIMIT 222 + /* Return TRUE when the given line is the beginning of a paragraph (BOP). */ -bool begpar(const filestruct *const line) +bool begpar(const filestruct *const line, int depth) { size_t quote_len, indent_len, prev_dent_len; @@ -1993,6 +1996,10 @@ bool begpar(const filestruct *const line) if (line == openfile->fileage) return TRUE; + /* If recursion is going too deep, just say it's not a BOP. */ + if (depth > RECURSION_LIMIT) + return FALSE; + quote_len = quote_length(line->data); indent_len = indent_length(line->data + quote_len); @@ -2018,7 +2025,7 @@ bool begpar(const filestruct *const line) return FALSE; /* Otherwise, this is a BOP if the preceding line is not. */ - return !begpar(line->prev); + return !begpar(line->prev, depth + 1); } /* Return TRUE when the given line is part of a paragraph. */ @@ -2149,7 +2156,7 @@ bool find_paragraph(size_t *const quote, size_t *const par) /* If the current line isn't the first line of the paragraph, move * back to the first line of the paragraph. */ - if (!begpar(openfile->current)) + if (!begpar(openfile->current, 0)) do_para_begin(FALSE); /* Now current is the first line of the paragraph. Set quote_len to