diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2014-12-24 09:58:35 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2014-12-24 09:58:35 +0000 |
commit | b90b724e08fcba984d8b57dd4b4bf1be91691628 (patch) | |
tree | 5fde85230f507da92dd2056c9445f8820b995b1f /man_term.c | |
parent | 4ad53635f5202474c55af90f70bba0ade18962cb (diff) | |
download | mandoc-b90b724e08fcba984d8b57dd4b4bf1be91691628.tar.gz |
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.c | 27 |
1 files changed, 18 insertions, 9 deletions
@@ -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) |