aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/man_term.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2014-12-24 09:58:35 +0000
committerIngo Schwarze <schwarze@openbsd.org>2014-12-24 09:58:35 +0000
commitfb95344148cb8c3ffd77776cedee32c2661cffa1 (patch)
tree8b623c201368f1b9046f9019e7f8b8804796667d /man_term.c
parente98af5414161553ffd7b765ad3a2451626334232 (diff)
downloadmandoc-fb95344148cb8c3ffd77776cedee32c2661cffa1.tar.gz
mandoc-fb95344148cb8c3ffd77776cedee32c2661cffa1.tar.zst
mandoc-fb95344148cb8c3ffd77776cedee32c2661cffa1.zip
When a man(7) document contains unreasonably large numbers for
indentations or paragraph distances, large output may be generated, which is practically the same as an endless loop; found by jsg@ with afl. Reject such unreasonably large numbers beyond arbitrary limits similar to those used by groff (max. 65 blank lines between paragraphs and max. SHRT_MAX characters per output line) and fall back to defaults when exceeded. Having the limits behave in exactly the same way is not relevant.
Diffstat (limited to 'man_term.c')
-rw-r--r--man_term.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/man_term.c b/man_term.c
index a710a1e6..94be32ba 100644
--- a/man_term.c
+++ b/man_term.c
@@ -1,4 +1,4 @@
-/* $Id: man_term.c,v 1.163 2014/12/23 13:48:57 schwarze Exp $ */
+/* $Id: man_term.c,v 1.164 2014/12/24 09:58:35 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -21,6 +21,7 @@
#include <assert.h>
#include <ctype.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -432,6 +433,8 @@ pre_in(DECL_ARGS)
p->offset += v;
else
p->offset = v;
+ if (p->offset > SHRT_MAX)
+ p->offset = term_len(p, p->defindent);
return(0);
}
@@ -508,16 +511,16 @@ pre_HP(DECL_ARGS)
if ((nn = n->parent->head->child) != NULL &&
a2roffsu(nn->string, &su, SCALE_EN)) {
len = term_hspan(p, &su);
+ if (len < 0 && (size_t)(-len) > mt->offset)
+ len = -mt->offset;
+ else if (len > SHRT_MAX)
+ len = term_len(p, p->defindent);
mt->lmargin[mt->lmargincur] = len;
} else
len = mt->lmargin[mt->lmargincur];
p->offset = mt->offset;
- if (len > 0 || (size_t)(-len) < mt->offset)
- p->rmargin = mt->offset + len;
- else
- p->rmargin = 0;
-
+ p->rmargin = mt->offset + len;
return(1);
}
@@ -582,9 +585,11 @@ pre_IP(DECL_ARGS)
(nn = nn->next) != NULL &&
a2roffsu(nn->string, &su, SCALE_EN)) {
len = term_hspan(p, &su);
- mt->lmargin[mt->lmargincur] = len;
if (len < 0 && (size_t)(-len) > mt->offset)
len = -mt->offset;
+ else if (len > SHRT_MAX)
+ len = term_len(p, p->defindent);
+ mt->lmargin[mt->lmargincur] = len;
} else
len = mt->lmargin[mt->lmargincur];
@@ -662,9 +667,11 @@ pre_TP(DECL_ARGS)
nn->string != NULL && ! (MAN_LINE & nn->flags) &&
a2roffsu(nn->string, &su, SCALE_EN)) {
len = term_hspan(p, &su);
- mt->lmargin[mt->lmargincur] = len;
if (len < 0 && (size_t)(-len) > mt->offset)
len = -mt->offset;
+ else if (len > SHRT_MAX)
+ len = term_len(p, p->defindent);
+ mt->lmargin[mt->lmargincur] = len;
} else
len = mt->lmargin[mt->lmargincur];
@@ -845,10 +852,11 @@ pre_RS(DECL_ARGS)
break;
}
+ len = SHRT_MAX + 1;
if ((n = n->parent->head->child) != NULL &&
a2roffsu(n->string, &su, SCALE_EN))
len = term_hspan(p, &su);
- else
+ if (len > SHRT_MAX)
len = term_len(p, p->defindent);
if (len > 0 || (size_t)(-len) < mt->offset)
@@ -881,10 +889,11 @@ post_RS(DECL_ARGS)
break;
}
+ len = SHRT_MAX + 1;
if ((n = n->parent->head->child) != NULL &&
a2roffsu(n->string, &su, SCALE_EN))
len = term_hspan(p, &su);
- else
+ if (len > SHRT_MAX)
len = term_len(p, p->defindent);
if (len < 0 || (size_t)len < mt->offset)