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.
This commit is contained in:
Todd C. Miller 2020-06-12 05:16:12 -06:00 committed by GitHub
parent 754cf93645
commit b2de1c4ee7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 16 additions and 5 deletions

21
run.c
View File

@ -25,6 +25,7 @@ THIS SOFTWARE.
#define DEBUG
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <wchar.h>
#include <wctype.h>
#include <fcntl.h>
@ -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: