]> git.cameronkatri.com Git - mandoc.git/commitdiff
When a man(7) document contains unreasonably large numbers for
authorIngo Schwarze <schwarze@openbsd.org>
Wed, 24 Dec 2014 09:58:35 +0000 (09:58 +0000)
committerIngo Schwarze <schwarze@openbsd.org>
Wed, 24 Dec 2014 09:58:35 +0000 (09:58 +0000)
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.

man_term.c
term.c

index a710a1e61ef16236cc3a883f2ca0d13745e8f290..94be32ba9a6c4d2fc1c08d74828823136a5be750 100644 (file)
@@ -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)
diff --git a/term.c b/term.c
index d884ba70648a7eb816a61fdcd952a9127342824c..0f39525b269b5814de754cc1492f72956523c331 100644 (file)
--- a/term.c
+++ b/term.c
@@ -1,4 +1,4 @@
-/*     $Id: term.c,v 1.240 2014/12/23 13:48:57 schwarze Exp $ */
+/*     $Id: term.c,v 1.241 2014/12/24 09:58:35 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -773,6 +773,7 @@ int
 term_vspan(const struct termp *p, const struct roffsu *su)
 {
        double           r;
+       int              ri;
 
        switch (su->unit) {
        case SCALE_BU:
@@ -808,7 +809,8 @@ term_vspan(const struct termp *p, const struct roffsu *su)
                abort();
                /* NOTREACHED */
        }
-       return(r > 0.0 ? r + 0.4995 : r - 0.4995);
+       ri = r > 0.0 ? r + 0.4995 : r - 0.4995;
+       return(ri < 66 ? ri : 1);
 }
 
 int