ICU-20246 Fixing another integer overflow in number parsing.

This commit is contained in:
Shane Carr 2018-10-29 23:52:44 -07:00 committed by Shane F. Carr
parent f71796d5e5
commit 53d8c8f3d1
6 changed files with 31 additions and 4 deletions

View file

@ -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);

View file

@ -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 {

View file

@ -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() {

View file

@ -1067,7 +1067,10 @@ public abstract class DecimalQuantity_AbstractBCD implements DecimalQuantity {
}
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 {

View file

@ -239,7 +239,15 @@ public final class DecimalQuantity_DualStorageBCD extends DecimalQuantity_Abstra
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;

View file

@ -6325,6 +6325,11 @@ public class NumberFormatTest extends TestFmwk {
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