Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix undefined behavior in libdecnumber #81

Merged
merged 1 commit into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions decnumber-sys/decnumber/decBasic.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
for (;;) { // inner loop -- calculate quotient unit
// strip leading zero units from acc (either there initially or
// from subtraction below); this may strip all if exactly 0
for (; *msua==0 && msua>=lsua;) msua--;
for (; msua>=lsua && *msua==0;) msua--;
accunits=(Int)(msua-lsua+1); // [maybe 0]
// subtraction is only necessary and possible if there are as
// least as many units remaining in acc for this iteration as
Expand Down Expand Up @@ -505,7 +505,7 @@ static decFloat * decDivide(decFloat *result, const decFloat *dfl,
// (must also continue to original lsu for correct quotient length)
if (lsua>acc+DIVACCLEN-DIVOPLEN) continue;
for (; msua>lsua && *msua==0;) msua--;
if (*msua==0 && msua==lsua) break;
if (msua==lsua && *msua==0) break;
} // outer loop

// all of the original operand in acc has been covered at this point
Expand Down Expand Up @@ -1533,8 +1533,8 @@ decFloat * decFloatAdd(decFloat *result,
umsd=acc+COFF+DECPMAX-1; // so far, so zero
if (ulsd>umsd) { // more to check
umsd++; // to align after checked area
for (; UBTOUI(umsd)==0 && umsd+3<ulsd;) umsd+=4;
for (; *umsd==0 && umsd<ulsd;) umsd++;
for (; umsd+3<ulsd && UBTOUI(umsd)==0;) umsd+=4;
for (; umsd<ulsd && *umsd==0;) umsd++;
}
if (*umsd==0) { // must be true zero (and diffsign)
num.sign=0; // assume +
Expand Down Expand Up @@ -2077,10 +2077,10 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl,
// remove leading zeros on both operands; this will save time later
// and make testing for zero trivial (tests are safe because acc
// and coe are rounded up to uInts)
for (; UBTOUI(hi->msd)==0 && hi->msd+3<hi->lsd;) hi->msd+=4;
for (; *hi->msd==0 && hi->msd<hi->lsd;) hi->msd++;
for (; UBTOUI(lo->msd)==0 && lo->msd+3<lo->lsd;) lo->msd+=4;
for (; *lo->msd==0 && lo->msd<lo->lsd;) lo->msd++;
for (; hi->msd+3<hi->lsd && UBTOUI(hi->msd)==0;) hi->msd+=4;
for (; hi->msd<hi->lsd && *hi->msd==0;) hi->msd++;
for (; lo->msd+3<lo->lsd && UBTOUI(lo->msd)==0;) lo->msd+=4;
for (; lo->msd<lo->lsd && *lo->msd==0;) lo->msd++;

// if hi is zero then result will be lo (which has the smaller
// exponent), which also may need to be tested for zero for the
Expand Down Expand Up @@ -2242,8 +2242,8 @@ decFloat * decFloatFMA(decFloat *result, const decFloat *dfl,
// all done except for the special IEEE 754 exact-zero-result
// rule (see above); while testing for zero, strip leading
// zeros (which will save decFinalize doing it)
for (; UBTOUI(lo->msd)==0 && lo->msd+3<lo->lsd;) lo->msd+=4;
for (; *lo->msd==0 && lo->msd<lo->lsd;) lo->msd++;
for (; lo->msd+3<lo->lsd && UBTOUI(lo->msd)==0;) lo->msd+=4;
for (; lo->msd<lo->lsd && *lo->msd==0;) lo->msd++;
if (*lo->msd==0) { // must be true zero (and diffsign)
lo->sign=0; // assume +
if (set->round==DEC_ROUND_FLOOR) lo->sign=DECFLOAT_Sign;
Expand Down
4 changes: 2 additions & 2 deletions decnumber-sys/decnumber/decCommon.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
// [this is quite expensive]
if (*umsd==0) {
for (; umsd+3<ulsd && UBTOUI(umsd)==0;) umsd+=4;
for (; *umsd==0 && umsd<ulsd;) umsd++;
for (; umsd<ulsd && *umsd==0;) umsd++;
length=ulsd-umsd+1; // recalculate
}
drop=MAXI(length-DECPMAX, DECQTINY-num->exponent);
Expand Down Expand Up @@ -416,7 +416,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
// if exponent is >=emax may have to clamp, overflow, or fold-down
if (num->exponent>DECEMAX-(DECPMAX-1)) { // is edge case
// printf("overflow checks...\n");
if (*ulsd==0 && ulsd==umsd) { // have zero
if (ulsd==umsd && *ulsd==0) { // have zero
num->exponent=DECEMAX-(DECPMAX-1); // clamp to max
}
else if ((num->exponent+length-1)>DECEMAX) { // > Nmax
Expand Down
5 changes: 3 additions & 2 deletions decnumber-sys/decnumber/decNumber.c
Original file line number Diff line number Diff line change
Expand Up @@ -3467,7 +3467,8 @@ uByte * decNumberGetBCD(const decNumber *dn, uByte *bcd) {
cut--;
if (cut>0) continue; // more in this unit
up++;
u=*up;
if (ub > bcd)
u=*up;
cut=DECDPUN;
}
#endif
Expand Down Expand Up @@ -4508,7 +4509,7 @@ static decNumber * decDivideOp(decNumber *res,
for (;;) { // inner forever loop
// strip leading zero units [from either pre-adjust or from
// subtract last time around]. Leave at least one unit.
for (; *msu1==0 && msu1>var1; msu1--) var1units--;
for (; msu1>var1 && *msu1==0; msu1--) var1units--;

if (var1units<var2ulen) break; // var1 too low for subtract
if (var1units==var2ulen) { // unit-by-unit compare needed
Expand Down