aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2014-12-24 18:04:10 +0000
committerIngo Schwarze <schwarze@openbsd.org>2014-12-24 18:04:10 +0000
commit4779d1b30e29ee1f848dbfdced4e200abc5f99a8 (patch)
treea0b812d0eaf3f15f0c65771ab2b0c07c95b9b11e
parent09a8bdf0f2fa584f57aa5d897c98eae1f48ae719 (diff)
downloadmandoc-4779d1b30e29ee1f848dbfdced4e200abc5f99a8.tar.gz
mandoc-4779d1b30e29ee1f848dbfdced4e200abc5f99a8.tar.zst
mandoc-4779d1b30e29ee1f848dbfdced4e200abc5f99a8.zip
For .RS, we need to save the information how much we actually indented
because negative indents can get truncated, in which case we no longer know how to restore the original indent at the end of the block. This also solves another case of effectively infinite output found by jsg@ with afl, triggered by very large negative indents.
-rw-r--r--man.h3
-rw-r--r--man_term.c42
2 files changed, 16 insertions, 29 deletions
diff --git a/man.h b/man.h
index 08bfcc8e..f4589fe3 100644
--- a/man.h
+++ b/man.h
@@ -1,4 +1,4 @@
-/* $Id: man.h,v 1.67 2014/12/01 04:05:32 schwarze Exp $ */
+/* $Id: man.h,v 1.68 2014/12/24 18:04:10 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -99,6 +99,7 @@ struct man_node {
struct man_node *body; /* BLOCK node BODY ptr */
const struct tbl_span *span; /* TBL */
const struct eqn *eqn; /* EQN */
+ int aux; /* decoded node data, type-dependent */
};
/* Names of macros. Index is enum mant. */
diff --git a/man_term.c b/man_term.c
index 94be32ba..1c4f7e06 100644
--- a/man_term.c
+++ b/man_term.c
@@ -1,4 +1,4 @@
-/* $Id: man_term.c,v 1.164 2014/12/24 09:58:35 schwarze Exp $ */
+/* $Id: man_term.c,v 1.165 2014/12/24 18:04:10 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -47,7 +47,7 @@ struct mtermp {
#define DECL_ARGS struct termp *p, \
struct mtermp *mt, \
- const struct man_node *n, \
+ struct man_node *n, \
const struct man_meta *meta
struct termact {
@@ -280,7 +280,7 @@ static int
pre_alternate(DECL_ARGS)
{
enum termfont font[2];
- const struct man_node *nn;
+ struct man_node *nn;
int savelit, i;
switch (n->tok) {
@@ -643,7 +643,7 @@ static int
pre_TP(DECL_ARGS)
{
struct roffsu su;
- const struct man_node *nn;
+ struct man_node *nn;
int len, savelit;
switch (n->type) {
@@ -840,7 +840,6 @@ static int
pre_RS(DECL_ARGS)
{
struct roffsu su;
- int len;
switch (n->type) {
case MAN_BLOCK:
@@ -852,17 +851,16 @@ 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);
- if (len > SHRT_MAX)
- len = term_len(p, p->defindent);
+ n = n->parent->head;
+ n->aux = SHRT_MAX + 1;
+ if (n->child != NULL && a2roffsu(n->child->string, &su, SCALE_EN))
+ n->aux = term_hspan(p, &su);
+ if (n->aux < 0 && (size_t)(-n->aux) > mt->offset)
+ n->aux = -mt->offset;
+ else if (n->aux > SHRT_MAX)
+ n->aux = term_len(p, p->defindent);
- if (len > 0 || (size_t)(-len) < mt->offset)
- mt->offset += len;
- else
- mt->offset = 0;
+ mt->offset += n->aux;
p->offset = mt->offset;
p->rmargin = p->maxrmargin;
@@ -876,8 +874,6 @@ pre_RS(DECL_ARGS)
static void
post_RS(DECL_ARGS)
{
- struct roffsu su;
- int len;
switch (n->type) {
case MAN_BLOCK:
@@ -889,17 +885,7 @@ 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);
- if (len > SHRT_MAX)
- len = term_len(p, p->defindent);
-
- if (len < 0 || (size_t)len < mt->offset)
- mt->offset -= len;
- else
- mt->offset = 0;
+ mt->offset -= n->parent->head->aux;
p->offset = mt->offset;
if (--mt->lmarginsz < MAXMARGINS)