ICU-9641 Add customizable max parse digit to DecimalFormat

X-SVN-Rev: 32993
This commit is contained in:
Michael Ow 2012-12-19 01:23:53 +00:00
parent fc3787c545
commit 49d85a9d59
2 changed files with 55 additions and 5 deletions

View file

@ -2152,9 +2152,9 @@ public class DecimalFormat extends NumberFormat {
// When parsing a number with big exponential value, it requires to transform the
// value into a string representation to construct BigInteger instance. We want to
// set the maximum size because it can easily trigger OutOfMemoryException.
// PARSE_MAX_EXPONENT is currently set to 1000, which is much bigger than MAX_VALUE of
// Double ( See the problem reported by ticket#5698
private static final int PARSE_MAX_EXPONENT = 1000;
// PARSE_MAX_EXPONENT is currently set to 1000 (See getParseMaxDigits()),
// which is much bigger than MAX_VALUE of Double ( See the problem reported by ticket#5698
private int PARSE_MAX_EXPONENT = 1000;
/**
* Parses the given text into a number. The text is parsed beginning at parsePosition,
@ -2499,9 +2499,9 @@ public class DecimalFormat extends NumberFormat {
// Adjust for exponent, if any
exponent += digits.decimalAt;
if (exponent < -PARSE_MAX_EXPONENT) {
if (exponent < -getParseMaxDigits()) {
status[STATUS_UNDERFLOW] = true;
} else if (exponent > PARSE_MAX_EXPONENT) {
} else if (exponent > getParseMaxDigits()) {
status[STATUS_INFINITE] = true;
} else {
digits.decimalAt = (int) exponent;
@ -5057,6 +5057,29 @@ public class DecimalFormat extends NumberFormat {
public boolean isParseBigDecimal() {
return parseBigDecimal;
}
/**
* Set the maximum number of exponent digits when parsing a number.
* If the limit is set too high, an OutOfMemoryException may be triggered.
* The default value is 1000.
* @param newValue the new limit
* @draft ICU 51
*/
public void setParseMaxDigits(int newValue) {
if (newValue > 0) {
PARSE_MAX_EXPONENT = newValue;
}
}
/**
* Get the current maximum number of exponent digits when parsing a
* number.
*
* @draft ICU 51
*/
public int getParseMaxDigits() {
return PARSE_MAX_EXPONENT;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
// Ticket#6449 Format.Field instances are not serializable. When

View file

@ -3039,6 +3039,33 @@ public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
}
}
}
public void TestParseMaxDigits() {
DecimalFormat fmt = new DecimalFormat();
String number = "100000000000";
int newParseMax = number.length() - 1;
fmt.setParseMaxDigits(-1);
/* Default value is 1000 */
if (fmt.getParseMaxDigits() != 1000) {
errln("Fail valid value checking in setParseMaxDigits.");
}
try {
if (fmt.parse(number).doubleValue() == Float.POSITIVE_INFINITY) {
errln("Got Infinity but should NOT when parsing number: " + number);
}
fmt.setParseMaxDigits(newParseMax);
if (fmt.parse(number).doubleValue() != Float.POSITIVE_INFINITY) {
errln("Did not get Infinity but should when parsing number: " + number);
}
} catch (ParseException ex) {
}
}
private static class FormatCharItrTestThread implements Runnable {
private final NumberFormat fmt;