From b2de1c4ee74c1283bae52cd6a94a56308430f79e Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Fri, 12 Jun 2020 05:16:12 -0600 Subject: [PATCH] Clear errno before using errcheck() to avoid spurious errors. (#80) The errcheck() function treats an errno of ERANGE or EDOM as something to report, so make sure errno is set to zero before invoking a function to check so that a previous such errno value won't result in a false positive. This could happen simply due to input line fields that looked enough like floating-point input to trigger ERANGE. Reported by Jordan Geoghegan, fix from Philip Guenther. --- run.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/run.c b/run.c index 26e8c4f..41f1bbe 100644 --- a/run.c +++ b/run.c @@ -25,6 +25,7 @@ THIS SOFTWARE. #define DEBUG #include #include +#include #include #include #include @@ -1072,8 +1073,10 @@ Cell *arith(Node **a, int n) /* a[0] + a[1], etc. also -a[0] */ case POWER: if (j >= 0 && modf(j, &v) == 0.0) /* pos integer exponent */ i = ipow(i, (int) j); - else + else { + errno = 0; i = errcheck(pow(i, j), "pow"); + } break; default: /* can't happen */ FATAL("illegal arithmetic operator %d", n); @@ -1166,8 +1169,10 @@ Cell *assign(Node **a, int n) /* a[0] = a[1], a[0] += a[1], etc. */ case POWEQ: if (yf >= 0 && modf(yf, &v) == 0.0) /* pos integer exponent */ xf = ipow(xf, (int) yf); - else + else { + errno = 0; xf = errcheck(pow(xf, yf), "pow"); + } break; default: FATAL("illegal assignment operator %d", n); @@ -1589,13 +1594,19 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis u = strlen(getsval(x)); break; case FLOG: - u = errcheck(log(getfval(x)), "log"); break; + errno = 0; + u = errcheck(log(getfval(x)), "log"); + break; case FINT: modf(getfval(x), &u); break; case FEXP: - u = errcheck(exp(getfval(x)), "exp"); break; + errno = 0; + u = errcheck(exp(getfval(x)), "exp"); + break; case FSQRT: - u = errcheck(sqrt(getfval(x)), "sqrt"); break; + errno = 0; + u = errcheck(sqrt(getfval(x)), "sqrt"); + break; case FSIN: u = sin(getfval(x)); break; case FCOS: