From 92c8a53689ae3aed2756704c0497352e686c3ae2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 23 Jan 2020 12:55:41 +0000 Subject: Better error-handling in some libtommath calls. --- generic/tclBasic.c | 2 +- generic/tclObj.c | 9 ++++++++- generic/tclStrToD.c | 4 ++-- generic/tclTestObj.c | 30 +++++++++++++++--------------- generic/tclTomMathInterface.c | 19 +++++++------------ 5 files changed, 33 insertions(+), 31 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index a03f131..68f32c2 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -7547,7 +7547,7 @@ ExprAbsFunc( if (mp_cmp_d((const mp_int *) ptr, 0) == MP_LT) { Tcl_GetBignumFromObj(NULL, objv[1], &big); tooLarge: - mp_neg(&big, &big); + (void)mp_neg(&big, &big); Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big)); } else { unChanged: diff --git a/generic/tclObj.c b/generic/tclObj.c index eca456f..b5d6d84 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -3392,7 +3392,14 @@ GetBignumFromObj( mp_int temp; UNPACK_BIGNUM(objPtr, temp); - mp_init_copy(bignumValue, &temp); + if (mp_init_copy(bignumValue, &temp) != MP_OKAY) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "insufficient memory to unpack bignum", -1)); + Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); + } + return TCL_ERROR; + } } else { UNPACK_BIGNUM(objPtr, *bignumValue); objPtr->internalRep.twoPtrValue.ptr1 = NULL; diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c index 16eca19..523e0cb 100644 --- a/generic/tclStrToD.c +++ b/generic/tclStrToD.c @@ -1283,7 +1283,7 @@ TclParseNumber( } if (octalSignificandOverflow) { if (signum) { - mp_neg(&octalSignificandBig, &octalSignificandBig); + (void)mp_neg(&octalSignificandBig, &octalSignificandBig); } TclSetBignumIntRep(objPtr, &octalSignificandBig); } @@ -1330,7 +1330,7 @@ TclParseNumber( } if (significandOverflow) { if (signum) { - mp_neg(&significandBig, &significandBig); + (void)mp_neg(&significandBig, &significandBig); } TclSetBignumIntRep(objPtr, &significandBig); } diff --git a/generic/tclTestObj.c b/generic/tclTestObj.c index f741714..ba1dda6 100644 --- a/generic/tclTestObj.c +++ b/generic/tclTestObj.c @@ -160,7 +160,7 @@ TestbignumobjCmd( }; int index, varIndex; const char *string; - mp_int bignumValue, newValue; + mp_int bignumValue; Tcl_Obj **varPtr; if (objc < 3) { @@ -233,19 +233,16 @@ TestbignumobjCmd( &bignumValue) != TCL_OK) { return TCL_ERROR; } - if (mp_init(&newValue) != MP_OKAY - || (mp_mul_d(&bignumValue, 10, &newValue) != MP_OKAY)) { + if (mp_mul_d(&bignumValue, 10, &bignumValue) != MP_OKAY) { mp_clear(&bignumValue); - mp_clear(&newValue); Tcl_SetObjResult(interp, Tcl_NewStringObj("error in mp_mul_d", -1)); return TCL_ERROR; } - mp_clear(&bignumValue); if (!Tcl_IsShared(varPtr[varIndex])) { - Tcl_SetBignumObj(varPtr[varIndex], &newValue); + Tcl_SetBignumObj(varPtr[varIndex], &bignumValue); } else { - SetVarToObj(varPtr, varIndex, Tcl_NewBignumObj(&newValue)); + SetVarToObj(varPtr, varIndex, Tcl_NewBignumObj(&bignumValue)); } break; @@ -261,19 +258,16 @@ TestbignumobjCmd( &bignumValue) != TCL_OK) { return TCL_ERROR; } - if (mp_init(&newValue) != MP_OKAY - || (mp_div_d(&bignumValue, 10, &newValue, NULL) != MP_OKAY)) { + if (mp_div_d(&bignumValue, 10, &bignumValue, NULL) != MP_OKAY) { mp_clear(&bignumValue); - mp_clear(&newValue); Tcl_SetObjResult(interp, Tcl_NewStringObj("error in mp_div_d", -1)); return TCL_ERROR; } - mp_clear(&bignumValue); if (!Tcl_IsShared(varPtr[varIndex])) { - Tcl_SetBignumObj(varPtr[varIndex], &newValue); + Tcl_SetBignumObj(varPtr[varIndex], &bignumValue); } else { - SetVarToObj(varPtr, varIndex, Tcl_NewBignumObj(&newValue)); + SetVarToObj(varPtr, varIndex, Tcl_NewBignumObj(&bignumValue)); } break; @@ -289,10 +283,16 @@ TestbignumobjCmd( &bignumValue) != TCL_OK) { return TCL_ERROR; } + if (mp_mod_2d(&bignumValue, 1, &bignumValue) != MP_OKAY) { + mp_clear(&bignumValue); + Tcl_SetObjResult(interp, + Tcl_NewStringObj("error in mp_mod_2d", -1)); + return TCL_ERROR; + } if (!Tcl_IsShared(varPtr[varIndex])) { - Tcl_SetIntObj(varPtr[varIndex], !mp_isodd(&bignumValue)); + Tcl_SetIntObj(varPtr[varIndex], mp_iszero(&bignumValue)); } else { - SetVarToObj(varPtr, varIndex, Tcl_NewIntObj(!mp_isodd(&bignumValue))); + SetVarToObj(varPtr, varIndex, Tcl_NewIntObj(mp_iszero(&bignumValue))); } mp_clear(&bignumValue); break; diff --git a/generic/tclTomMathInterface.c b/generic/tclTomMathInterface.c index 2dc8c2d..21fd238 100644 --- a/generic/tclTomMathInterface.c +++ b/generic/tclTomMathInterface.c @@ -111,7 +111,6 @@ TclBNInitBignumFromLong( mp_int *a, long initVal) { - int status; unsigned long v; mp_digit *p; @@ -119,8 +118,7 @@ TclBNInitBignumFromLong( * Allocate enough memory to hold the largest possible long */ - status = mp_init(a); - if (status != MP_OKAY) { + if (mp_init(a) != MP_OKAY) { Tcl_Panic("initialization failure in TclBNInitBignumFromLong"); } @@ -130,7 +128,7 @@ TclBNInitBignumFromLong( if (initVal < 0) { a->sign = MP_NEG; - v = -initVal; + v = -(unsigned long)initVal; } else { a->sign = MP_ZPOS; v = initVal; @@ -170,12 +168,11 @@ TclBNInitBignumFromWideInt( mp_int *a, /* Bignum to initialize */ Tcl_WideInt v) /* Initial value */ { - if (v < (Tcl_WideInt)0) { - TclBNInitBignumFromWideUInt(a, (Tcl_WideUInt)(-v)); - mp_neg(a, a); - } else { - TclBNInitBignumFromWideUInt(a, (Tcl_WideUInt)v); + if (v < 0) { + (void)TclBNInitBignumFromWideUInt(a, -(Tcl_WideUInt)v); + return mp_neg(a, a); } + (void)TclBNInitBignumFromWideUInt(a, (Tcl_WideUInt)v); return MP_OKAY; } @@ -200,15 +197,13 @@ TclBNInitBignumFromWideUInt( mp_int *a, /* Bignum to initialize */ Tcl_WideUInt v) /* Initial value */ { - int status; mp_digit *p; /* * Allocate enough memory to hold the largest possible Tcl_WideUInt. */ - status = mp_init(a); - if (status != MP_OKAY) { + if (mp_init(a) != MP_OKAY) { Tcl_Panic("initialization failure in TclBNInitBignumFromWideUInt"); } -- cgit v0.12