Fixed trigonometric and hyperbolic core dumps

This commit is contained in:
Landon Curt Noll
2018-09-30 14:08:20 -07:00
parent c8705c1198
commit 5fb3db4558
4 changed files with 137 additions and 27 deletions

22
CHANGES
View File

@@ -1,4 +1,24 @@
The following are the changes from calc version 2.12.6.6 to date:
The following are the changes from calc version 2.12.6.9 to date:
Fixed a number of core dump bugs related to the calculation of
tan(), cot(), sec(), csc(), tanh(), coth(), sech(), and csch(),
asin(), acos(), asinh(), acosh(), where when a call to an
underlying function produced an invalid value. Thanks goes to
github user wuxiuheng for reporting this problem.
A number of trigonometric and hyperbolic functions that incorrectly
returned E_LOGINF, now return a new error code that is more
specific to the trigonometric or hyperbolic function. The
following is a list of these new error codes: E_TAN3 E_TAN4
E_COT3 E_COT4 E_SEC3 E_CSC3 E_TANH3 E_TANH4 E_COTH3 E_COTH4
E_SECH3 E_CSCH3 E_ASIN3 E_ACOS3 E_ASINH3 E_ACOSH3 E_ATAN3 E_ACOT3
E_ASEC3 E_ACSC3 E_ATANH3 E_ACOTH3 E_ASECH3 E_ACSCH3.
Added regression tests 3729 thru 3732 to test E_TAN3, E_COT3,
E_SEC3 and E_CSC3 respectively.
The following are the changes from calc version 2.12.6.6 to 2.12.6.8:
For historical purposes, in lucas.cal, gen_v1(1, n) always returns 4.

View File

@@ -3227,9 +3227,9 @@ define test_error()
print '3600: Beginning test_error';
/* bump ecnt up by 148 */
ecnt += 148;
print '3601: ecnt += 148';
/* bump ecnt up by 156 */
ecnt += 156;
print '3601: ecnt += 156';
strx = "x";
print '3602: strx = "x"';
@@ -3418,11 +3418,15 @@ define test_error()
n = 8191;
print '3727: n = 8191';
/* test 3728 removed due to non-portable strerror() output */
vrfy(tan(2e9i) == error(10435), '3729: tan(2e9i) == error(10435)');
vrfy(cot(2e9i) == error(10437), '3730: cot(2e9i) == error(10437)');
vrfy(sec(2e9i) == error(10439), '3731: sec(2e9i) == error(10439)');
vrfy(csc(2e9i) == error(10440), '3732: csc(2e9i) == error(10440)');
/* errmax and errcount should be bumped up the 148 errors above */
vrfy(errcount() == ecnt, '3729: errcount() == ecnt');
vrfy(errcount() == ecnt, '3733: errcount() == ecnt');
print '3730: Ending test_error';
print '3734: Ending test_error';
}
print '054: parsed test_error()';
@@ -7932,8 +7936,8 @@ print '8901: read -once "test8900"';
read -once "test8900";
print '8902: about to run test8900(1,,8903)';
testnum = test8900(1,,8903);
print '8999: ecnt = 203;'
ecnt = 203;
print '8999: ecnt = 211;'
ecnt = 211;
/* 89xx: test calc resource functions by Christoph Zurnieden */

View File

@@ -451,6 +451,7 @@ E_FPATHOPEN1 Non-string arguments for fpathopen
E_FPATHOPEN2 Unrecognized mode for fpathopen
E_LOG1 Bad epsilon argument for log
E_LOG2 Non-numeric first argument for log
E_LOG3 Cannot calculate log for this value
E_FGETFILE1 Non-file argument for fgetfile
E_FGETFILE2 File argument for fgetfile not open for reading
E_FGETFILE3 Unable to set file position in fgetfile
@@ -471,3 +472,27 @@ E_ISSPACE Bad argument for isspace
E_ISXDIGIT Bad argument for isxdigit
E_STRTOUPPER Bad argument type for strtoupper
E_STRTOLOWER Bad argument type for strtolower
E_TAN3 Invalid value for calculating the sin numerator for tan
E_TAN4 Invalid value for calculating the cos denominator for tan
E_COT3 Invalid value for calculating the sin numerator for cot
E_COT4 Invalid value for calculating the cos denominator for cot
E_SEC3 Invalid value for calculating the cos reciprocal for sec
E_CSC3 Invalid value for calculating the sin reciprocal for csc
E_TANH3 Invalid value for calculating the sinh numerator for tanh
E_TANH4 Invalid value for calculating the cosh denominator for tanh
E_COTH3 Invalid value for calculating the sinh numerator for coth
E_COTH4 Invalid value for calculating the cosh denominator for coth
E_SECH3 Invalid value for calculating the cosh reciprocal for sech
E_CSCH3 Invalid value for calculating the sinh reciprocal for csch
E_ASIN3 Invalid value for calculating asin
E_ACOS3 Invalid value for calculating acos
E_ASINH3 Invalid value for calculating asinh
E_ACOSH3 Invalid value for calculating acosn
E_ATAN3 Invalid value for calculating atan
E_ACOT3 Invalid value for calculating acot
E_ASEC3 Invalid value for calculating asec
E_ACSC3 Invalid value for calculating acsc
E_ATANH3 Invalid value for calculating atan
E_ACOTH3 Invalid value for calculating acot
E_ASECH3 Invalid value for calculating asec
E_ACSCH3 Invalid value for calculating acsc

97
func.c
View File

@@ -2122,6 +2122,9 @@ f_log(int count, VALUE **vals)
default:
return error_value(E_LOG2);
}
if (c == NULL) {
return error_value(E_LOG3);
}
result.v_type = V_COM;
result.v_com = c;
if (cisreal(c)) {
@@ -2239,8 +2242,15 @@ f_tan(int count, VALUE **vals)
case V_COM:
tmp1.v_type = V_COM;
tmp1.v_com = c_sin(vals[0]->v_com, err);
if (tmp1.v_com == NULL) {
return error_value(E_TAN3);
}
tmp2.v_type = V_COM;
tmp2.v_com = c_cos(vals[0]->v_com, err);
if (tmp2.v_com == NULL) {
comfree(tmp1.v_com);
return error_value(E_TAN4);
}
divvalue(&tmp1, &tmp2, &result);
comfree(tmp1.v_com);
comfree(tmp2.v_com);
@@ -2276,6 +2286,9 @@ f_sec(int count, VALUE **vals)
case V_COM:
tmp.v_type = V_COM;
tmp.v_com = c_cos(vals[0]->v_com, err);
if (tmp.v_com == NULL) {
return error_value(E_SEC3);
}
invertvalue(&tmp, &result);
comfree(tmp.v_com);
break;
@@ -2314,8 +2327,15 @@ f_cot(int count, VALUE **vals)
case V_COM:
tmp1.v_type = V_COM;
tmp1.v_com = c_cos(vals[0]->v_com, err);
if (tmp1.v_com == NULL) {
return error_value(E_COT3);
}
tmp2.v_type = V_COM;
tmp2.v_com = c_sin(vals[0]->v_com, err);
if (tmp2.v_com == NULL) {
comfree(tmp1.v_com);
return error_value(E_COT4);
}
divvalue(&tmp1, &tmp2, &result);
comfree(tmp1.v_com);
comfree(tmp2.v_com);
@@ -2354,6 +2374,9 @@ f_csc(int count, VALUE **vals)
case V_COM:
tmp.v_type = V_COM;
tmp.v_com = c_sin(vals[0]->v_com, err);
if (tmp.v_com == NULL) {
return error_value(E_CSC3);
}
invertvalue(&tmp, &result);
comfree(tmp.v_com);
break;
@@ -2476,8 +2499,15 @@ f_tanh(int count, VALUE **vals)
case V_COM:
tmp1.v_type = V_COM;
tmp1.v_com = c_sinh(vals[0]->v_com, err);
if (tmp1.v_com == NULL) {
return error_value(E_TANH3);
}
tmp2.v_type = V_COM;
tmp2.v_com = c_cosh(vals[0]->v_com, err);
if (tmp2.v_com == NULL) {
comfree(tmp1.v_com);
return error_value(E_TANH4);
}
divvalue(&tmp1, &tmp2, &result);
comfree(tmp1.v_com);
comfree(tmp2.v_com);
@@ -2517,8 +2547,15 @@ f_coth(int count, VALUE **vals)
case V_COM:
tmp1.v_type = V_COM;
tmp1.v_com = c_cosh(vals[0]->v_com, err);
if (tmp1.v_com == NULL) {
return error_value(E_COTH3);
}
tmp2.v_type = V_COM;
tmp2.v_com = c_sinh(vals[0]->v_com, err);
if (tmp2.v_com == NULL) {
comfree(tmp1.v_com);
return error_value(E_COTH4);
}
divvalue(&tmp1, &tmp2, &result);
comfree(tmp1.v_com);
comfree(tmp2.v_com);
@@ -2555,6 +2592,9 @@ f_sech(int count, VALUE **vals)
case V_COM:
tmp.v_type = V_COM;
tmp.v_com = c_cosh(vals[0]->v_com, err);
if (tmp.v_com == NULL) {
return error_value(E_SECH3);
}
invertvalue(&tmp, &result);
comfree(tmp.v_com);
break;
@@ -2592,6 +2632,9 @@ f_csch(int count, VALUE **vals)
case V_COM:
tmp.v_type = V_COM;
tmp.v_com = c_sinh(vals[0]->v_com, err);
if (tmp.v_com == NULL) {
return error_value(E_CSCH3);
}
invertvalue(&tmp, &result);
comfree(tmp.v_com);
break;
@@ -2626,7 +2669,7 @@ f_atan(int count, VALUE **vals)
case V_COM:
tmp = c_atan(vals[0]->v_com, err);
if (tmp == NULL)
return error_value(E_LOGINF);
return error_value(E_ATAN3);
result.v_type = V_COM;
result.v_com = tmp;
if (cisreal(tmp)) {
@@ -2666,7 +2709,7 @@ f_acot(int count, VALUE **vals)
case V_COM:
tmp = c_acot(vals[0]->v_com, err);
if (tmp == NULL)
return error_value(E_LOGINF);
return error_value(E_ACOT3);
result.v_type = V_COM;
result.v_com = tmp;
if (cisreal(tmp)) {
@@ -2718,6 +2761,9 @@ f_asin(int count, VALUE **vals)
default:
return error_value(E_ASIN2);
}
if (result.v_com == NULL) {
return error_value(E_ASIN3);
}
if (result.v_type == V_COM && cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -2764,6 +2810,9 @@ f_acos(int count, VALUE **vals)
default:
return error_value(E_ACOS2);
}
if (result.v_com == NULL) {
return error_value(E_ACOS3);
}
if (result.v_type == V_COM && cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -2794,7 +2843,7 @@ f_asec(int count, VALUE **vals)
switch (vals[0]->v_type) {
case V_NUM:
if (qiszero(vals[0]->v_num))
return error_value(E_LOGINF);
return error_value(E_ASEC3);
result.v_num = qasec(vals[0]->v_num, err);
result.v_type = V_NUM;
if (result.v_num == NULL) {
@@ -2813,9 +2862,10 @@ f_asec(int count, VALUE **vals)
default:
return error_value(E_ASEC2);
}
if (result.v_com == NULL) {
return error_value(E_ASEC3);
}
if (result.v_type == V_COM) {
if (result.v_com == NULL)
return error_value(E_LOGINF);
if (cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -2847,7 +2897,7 @@ f_acsc(int count, VALUE **vals)
switch (vals[0]->v_type) {
case V_NUM:
if (qiszero(vals[0]->v_num))
return error_value(E_LOGINF);
return error_value(E_ACSC3);
result.v_num = qacsc(vals[0]->v_num, err);
result.v_type = V_NUM;
if (result.v_num == NULL) {
@@ -2866,9 +2916,10 @@ f_acsc(int count, VALUE **vals)
default:
return error_value(E_ACSC2);
}
if (result.v_com == NULL) {
return error_value(E_ACSC3);
}
if (result.v_type == V_COM) {
if (result.v_com == NULL)
return error_value(E_LOGINF);
if (cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -2903,6 +2954,9 @@ f_asinh(int count, VALUE **vals)
break;
case V_COM:
tmp = c_asinh(vals[0]->v_com, err);
if (tmp == NULL) {
return error_value(E_ASINH3);
}
result.v_type = V_COM;
result.v_com = tmp;
if (cisreal(tmp)) {
@@ -2955,6 +3009,9 @@ f_acosh(int count, VALUE **vals)
default:
return error_value(E_ACOSH2);
}
if (result.v_com == NULL) {
return error_value(E_ACOSH3);
}
if (result.v_type == V_COM && cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -3002,9 +3059,10 @@ f_atanh(int count, VALUE **vals)
default:
return error_value(E_ATANH2);
}
if (result.v_com == NULL) {
return error_value(E_ATANH3);
}
if (result.v_type == V_COM) {
if (result.v_com == NULL)
return error_value(E_LOGINF);
if (cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -3053,9 +3111,10 @@ f_acoth(int count, VALUE **vals)
default:
return error_value(E_ACOTH2);
}
if (result.v_com == NULL) {
return error_value(E_ACOTH3);
}
if (result.v_type == V_COM) {
if (result.v_com == NULL)
return error_value(E_LOGINF);
if (cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -3087,7 +3146,7 @@ f_asech(int count, VALUE **vals)
switch (vals[0]->v_type) {
case V_NUM:
if (qiszero(vals[0]->v_num))
return error_value(E_LOGINF);
return error_value(E_ASECH3);
result.v_num = qasech(vals[0]->v_num, err);
result.v_type = V_NUM;
if (result.v_num == NULL) {
@@ -3106,9 +3165,10 @@ f_asech(int count, VALUE **vals)
default:
return error_value(E_ASECH2);
}
if (result.v_com == NULL) {
return error_value(E_ASECH3);
}
if (result.v_type == V_COM) {
if (result.v_com == NULL)
return error_value(E_LOGINF);
if (cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -3140,7 +3200,7 @@ f_acsch(int count, VALUE **vals)
switch (vals[0]->v_type) {
case V_NUM:
if (qiszero(vals[0]->v_num))
return error_value(E_LOGINF);
return error_value(E_ACSCH3);
result.v_num = qacsch(vals[0]->v_num, err);
result.v_type = V_NUM;
if (result.v_num == NULL) {
@@ -3159,9 +3219,10 @@ f_acsch(int count, VALUE **vals)
default:
return error_value(E_ACSCH2);
}
if (result.v_com == NULL) {
return error_value(E_ACSCH3);
}
if (result.v_type == V_COM) {
if (result.v_com == NULL)
return error_value(E_LOGINF);
if (cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);