From 7ffb7943d4743e852f277c6a09586e110874b72f Mon Sep 17 00:00:00 2001 From: Emanuele Torre Date: Tue, 18 Jul 2023 20:03:18 +0200 Subject: [PATCH] Fix signed integer overflow undefined behaviour in decNumber.c Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60691 $ ./jq <<< 0E2202012202 src/decNumber/decNumber.c:598:18: runtime error: signed integer overflow: 440402440 + 1761609760 cannot be represented in type 'int' 0E+999999999 Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60683 $ ./jq <<< 5E7657765755 src/decNumber/decNumber.c:598:18: runtime error: left shift of 765776575 by 3 places cannot be represented in type 'int' src/decNumber/decNumber.c:598:18: runtime error: signed integer overflow: 1531553150 + 1831245304 cannot be represented in type 'int' 1.7976931348623157e+308 --- src/decNumber/decNumber.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/decNumber/decNumber.c b/src/decNumber/decNumber.c index 19230b89..5062634d 100644 --- a/src/decNumber/decNumber.c +++ b/src/decNumber/decNumber.c @@ -582,6 +582,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], Flag nege; // 1=negative exponent const char *firstexp; // -> first significant exponent digit status=DEC_Conversion_syntax;// assume the worst + uInt expa=0; // accumulator for exponent if (*c!='e' && *c!='E') break; /* Found 'e' or 'E' -- now process explicit exponent */ // 1998.07.11: sign no longer required @@ -595,7 +596,7 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], firstexp=c; // save exponent digit place for (; ;c++) { if (*c<'0' || *c>'9') break; // not a digit - exponent=X10(exponent)+(Int)*c-(Int)'0'; + expa=X10(expa)+(Int)*c-(Int)'0'; } // c // if not now on a '\0', *c must not be a digit if (*c!='\0') break; @@ -604,9 +605,10 @@ decNumber * decNumberFromString(decNumber *dn, const char chars[], // if it was too long the exponent may have wrapped, so check // carefully and set it to a certain overflow if wrap possible if (c>=firstexp+9+1) { - if (c>firstexp+9+1 || *firstexp>'1') exponent=DECNUMMAXE*2; + if (c>firstexp+9+1 || *firstexp>'1') expa=DECNUMMAXE*2; // [up to 1999999999 is OK, for example 1E-1000000998] } + exponent=(Int)expa; // save exponent if (nege) exponent=-exponent; // was negative status=0; // is OK } // stuff after digits