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
This commit is contained in:
Emanuele Torre authored and Nico Williams committed 2023-07-18 14:03:40 -05:00
1 parent 15fd31de78
commit 7ffb7943d4
1 file changed
+4 -2
+4 -2
View File
@@ -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