When a numerical condition errors out after consuming at least one
authorschwarze <schwarze@openbsd.org>
Tue, 16 Dec 2014 01:21:37 +0000 (01:21 +0000)
committerschwarze <schwarze@openbsd.org>
Tue, 16 Dec 2014 01:21:37 +0000 (01:21 +0000)
character of input, treat it as false, do not retry it as a string
comparison condition.  This also fixes a read buffer overrun that
happened when the numerical condition advanced to the end of the
input line before erroring out, found by jsg@ with afl.

regress/usr.bin/mandoc/roff/cond/numeric.in
regress/usr.bin/mandoc/roff/cond/numeric.out_ascii
usr.bin/mandoc/roff.c

index ab154d6..d28fcb9 100644 (file)
@@ -1,4 +1,4 @@
-.TH COND-NUMERIC 1 "April 7, 2014" OpenBSD
+.TH COND-NUMERIC 1 "December 16, 2014" OpenBSD
 .SH NAME
 cond-numeric \- roff conditions involving numbers
 .SH DESCRIPTION
@@ -126,3 +126,19 @@ operator ":":
 11
 .ie 1:1 (t)
 .el (f)
+.PP
+unmatched parenthesis:
+.ie (
+(t)
+.el (f)
+one
+.ie (1 (t)
+.el (f)
+.PP
+negated unmatched parenthesis:
+.ie !(
+(t)
+.el (f)
+zero
+.ie !(0 (t)
+.el (f)
index 9947c53..b8155ca 100644 (file)
@@ -30,6 +30,10 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
 
        operator ":": 00 (f) 01 (t) 10 (t) 11 (t)
 
+       unmatched parenthesis: (f) one (t)
 
+       negated unmatched parenthesis: (f) zero (t)
 
-OpenBSD                          April 7, 2014                 COND-NUMERIC(1)
+
+
+OpenBSD                        December 16, 2014               COND-NUMERIC(1)
index d4d923c..e7d9795 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: roff.c,v 1.112 2014/12/15 23:42:31 schwarze Exp $ */
+/*     $OpenBSD: roff.c,v 1.113 2014/12/16 01:21:37 schwarze Exp $ */
 /*
  * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -1247,7 +1247,7 @@ out:
 static int
 roff_evalcond(struct roff *r, int ln, const char *v, int *pos)
 {
-       int      wanttrue, number;
+       int      number, savepos, wanttrue;
 
        if ('!' == v[*pos]) {
                wanttrue = 0;
@@ -1280,10 +1280,13 @@ roff_evalcond(struct roff *r, int ln, const char *v, int *pos)
                break;
        }
 
+       savepos = *pos;
        if (roff_evalnum(r, ln, v, pos, &number, 0))
                return((number > 0) == wanttrue);
-       else
+       else if (*pos == savepos)
                return(roff_evalstrcond(v, pos) == wanttrue);
+       else
+               return (0);
 }
 
 static enum rofferr