Skip to content
Permalink
Browse files Browse the repository at this point in the history
ICU-20246 Fixing another integer overflow in number parsing.
  • Loading branch information
sffc committed Oct 31, 2018
1 parent f71796d commit 53d8c8f
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 4 deletions.
2 changes: 1 addition & 1 deletion icu4c/source/i18n/fmtable.cpp
Expand Up @@ -734,7 +734,7 @@ CharString *Formattable::internalGetCharString(UErrorCode &status) {
// not print scientific notation for magnitudes greater than -5 and smaller than some amount (+5?).
if (fDecimalQuantity->isZero()) {
fDecimalStr->append("0", -1, status);
} else if (std::abs(fDecimalQuantity->getMagnitude()) < 5) {
} else if (fDecimalQuantity->getMagnitude() != INT32_MIN && std::abs(fDecimalQuantity->getMagnitude()) < 5) {
fDecimalStr->appendInvariantChars(fDecimalQuantity->toPlainString(), status);
} else {
fDecimalStr->appendInvariantChars(fDecimalQuantity->toScientificString(), status);
Expand Down
5 changes: 4 additions & 1 deletion icu4c/source/i18n/number_decimalquantity.cpp
Expand Up @@ -898,7 +898,10 @@ UnicodeString DecimalQuantity::toScientificString() const {
}
result.append(u'E');
int32_t _scale = upperPos + scale;
if (_scale < 0) {
if (_scale == INT32_MIN) {
result.append({u"-2147483648", -1});
return result;
} else if (_scale < 0) {
_scale *= -1;
result.append(u'-');
} else {
Expand Down
8 changes: 8 additions & 0 deletions icu4c/source/test/intltest/numfmtst.cpp
Expand Up @@ -9226,6 +9226,14 @@ void NumberFormatTest::Test20037_ScientificIntegerOverflow() {
assertEquals(u"Should not overflow and should parse only the first exponent",
u"1E-2147483647",
{sp.data(), sp.length(), US_INV});

// Test edge case overflow of exponent
result = Formattable();
nf->parse(u".0003e-2147483644", result, status);
sp = result.getDecimalNumber(status);
assertEquals(u"Should not overflow",
u"3E-2147483648",
{sp.data(), sp.length(), US_INV});
}

void NumberFormatTest::Test13840_ParseLongStringCrash() {
Expand Down
Expand Up @@ -1067,7 +1067,10 @@ public void toScientificString(StringBuilder result) {
}
result.append('E');
int _scale = upperPos + scale;
if (_scale < 0) {
if (_scale == Integer.MIN_VALUE) {
result.append("-2147483648");
return;
} else if (_scale < 0) {
_scale *= -1;
result.append('-');
} else {
Expand Down
Expand Up @@ -239,7 +239,15 @@ protected BigDecimal bcdToBigDecimal() {
tempLong = tempLong * 10 + getDigitPos(shift);
}
BigDecimal result = BigDecimal.valueOf(tempLong);
result = result.scaleByPowerOfTen(scale);
try {
result = result.scaleByPowerOfTen(scale);
} catch (ArithmeticException e) {
if (e.getMessage().contains("Underflow")) {
result = BigDecimal.ZERO;
} else {
throw e;
}
}
if (isNegative())
result = result.negate();
return result;
Expand Down
Expand Up @@ -6325,6 +6325,11 @@ public void Test20037_ScientificIntegerOverflow() throws ParseException {
result = nf.parse("1E-547483647");
assertEquals("Should *not* snap to zero",
"1E-547483647", result.toString());

// Test edge case overflow of exponent
result = nf.parse(".0003e-2147483644");
assertEquals("Should not overflow",
"0", result.toString());
}

@Test
Expand Down

0 comments on commit 53d8c8f

Please sign in to comment.