From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from krisdoz.my.domain (kristaps@localhost [127.0.0.1]) by krisdoz.my.domain (8.14.5/8.14.5) with ESMTP id s9KJ4qOd002096 for ; Mon, 20 Oct 2014 15:04:52 -0400 (EDT) Received: (from kristaps@localhost) by krisdoz.my.domain (8.14.5/8.14.3/Submit) id s9KJ4jGo004331; Mon, 20 Oct 2014 15:04:45 -0400 (EDT) Date: Mon, 20 Oct 2014 15:04:45 -0400 (EDT) Message-Id: <201410201904.s9KJ4jGo004331@krisdoz.my.domain> X-Mailinglist: mdocml-source Reply-To: source@mdocml.bsd.lv MIME-Version: 1.0 From: kristaps@mdocml.bsd.lv To: source@mdocml.bsd.lv Subject: mdocml: Protect the roff parser from dividing by zero. X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Log Message: ----------- Protect the roff parser from dividing by zero. ok schwarze@ Modified Files: -------------- mdocml: mandoc.h read.c roff.c Revision Data ------------- Index: mandoc.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mandoc.h,v retrieving revision 1.163 retrieving revision 1.164 diff -Lmandoc.h -Lmandoc.h -u -p -r1.163 -r1.164 --- mandoc.h +++ mandoc.h @@ -166,6 +166,7 @@ enum mandocerr { MANDOCERR_IT_NONUM, /* skipping request without numeric argument */ MANDOCERR_ARG_SKIP, /* skipping all arguments: macro args */ MANDOCERR_ARG_EXCESS, /* skipping excess arguments: macro ... args */ + MANDOCERR_DIVZERO, /* divide by zero */ MANDOCERR_FATAL, /* ===== start of fatal errors ===== */ Index: roff.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.c,v retrieving revision 1.233 retrieving revision 1.234 diff -Lroff.c -Lroff.c -u -p -r1.233 -r1.234 --- roff.c +++ roff.c @@ -186,9 +186,12 @@ static enum rofferr roff_cond_sub(ROFF_ static enum rofferr roff_ds(ROFF_ARGS); static enum rofferr roff_eqndelim(struct roff *, char **, size_t *, int); -static int roff_evalcond(const char *, int *); -static int roff_evalnum(const char *, int *, int *, int); -static int roff_evalpar(const char *, int *, int *); +static int roff_evalcond(struct roff *r, int, + const char *, int *); +static int roff_evalnum(struct roff *, int, + const char *, int *, int *, int); +static int roff_evalpar(struct roff *, int, + const char *, int *, int *); static int roff_evalstrcond(const char *, int *); static void roff_free1(struct roff *); static void roff_freereg(struct roffreg *); @@ -622,7 +625,7 @@ roff_res(struct roff *r, char **bufp, si case 'B': npos = 0; ubuf[0] = arg_complete && - roff_evalnum(stnam, &npos, NULL, 0) && + roff_evalnum(r, ln, stnam, &npos, NULL, 0) && stnam + npos + 1 == cp ? '1' : '0'; ubuf[1] = '\0'; break; @@ -1240,7 +1243,7 @@ out: * or string condition. */ static int -roff_evalcond(const char *v, int *pos) +roff_evalcond(struct roff *r, int ln, const char *v, int *pos) { int wanttrue, number; @@ -1271,7 +1274,7 @@ roff_evalcond(const char *v, int *pos) break; } - if (roff_evalnum(v, pos, &number, 0)) + if (roff_evalnum(r, ln, v, pos, &number, 0)) return((number > 0) == wanttrue); else return(roff_evalstrcond(v, pos) == wanttrue); @@ -1300,7 +1303,7 @@ roff_cond(ROFF_ARGS) r->last->rule = ROFF_el == tok ? (r->rstackpos < 0 ? 0 : r->rstack[r->rstackpos--]) : - roff_evalcond(*bufp, &pos); + roff_evalcond(r, ln, *bufp, &pos); /* * An if-else will put the NEGATION of the current evaluated @@ -1466,14 +1469,15 @@ roff_getop(const char *v, int *pos, char * or a single signed integer number. */ static int -roff_evalpar(const char *v, int *pos, int *res) +roff_evalpar(struct roff *r, int ln, + const char *v, int *pos, int *res) { if ('(' != v[*pos]) return(roff_getnum(v, pos, res)); (*pos)++; - if ( ! roff_evalnum(v, pos, res, 1)) + if ( ! roff_evalnum(r, ln, v, pos, res, 1)) return(0); /* @@ -1495,7 +1499,8 @@ roff_evalpar(const char *v, int *pos, in * Proceed left to right, there is no concept of precedence. */ static int -roff_evalnum(const char *v, int *pos, int *res, int skipwhite) +roff_evalnum(struct roff *r, int ln, const char *v, + int *pos, int *res, int skipwhite) { int mypos, operand2; char operator; @@ -1509,7 +1514,7 @@ roff_evalnum(const char *v, int *pos, in while (isspace((unsigned char)v[*pos])) (*pos)++; - if ( ! roff_evalpar(v, pos, res)) + if ( ! roff_evalpar(r, ln, v, pos, res)) return(0); while (1) { @@ -1524,7 +1529,7 @@ roff_evalnum(const char *v, int *pos, in while (isspace((unsigned char)v[*pos])) (*pos)++; - if ( ! roff_evalpar(v, pos, &operand2)) + if ( ! roff_evalpar(r, ln, v, pos, &operand2)) return(0); if (skipwhite) @@ -1545,6 +1550,12 @@ roff_evalnum(const char *v, int *pos, in *res *= operand2; break; case '/': + if (0 == operand2) { + mandoc_msg(MANDOCERR_DIVZERO, + r->parse, ln, *pos, v); + *res = 0; + break; + } *res /= operand2; break; case '%': @@ -1719,7 +1730,7 @@ roff_nr(ROFF_ARGS) if ('+' == sign || '-' == sign) val++; - if (roff_evalnum(val, NULL, &iv, 0)) + if (roff_evalnum(r, ln, val, NULL, &iv, 0)) roff_setreg(r, key, iv, sign); return(ROFF_IGN); Index: read.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/read.c,v retrieving revision 1.91 retrieving revision 1.92 diff -Lread.c -Lread.c -u -p -r1.91 -r1.92 --- read.c +++ read.c @@ -211,6 +211,7 @@ static const char * const mandocerrs[MAN "skipping request without numeric argument", "skipping all arguments", "skipping excess arguments", + "divide by zero", "generic fatal error", -- To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv