8335668: NumberFormat integer only parsing should throw exception for edge case
Reviewed-by: naoto
This commit is contained in:
parent
58c98420b6
commit
5100303c6c
src/java.base/share/classes/java/text
test/jdk/java/text/Format/NumberFormat
@ -2379,8 +2379,8 @@ public class DecimalFormat extends NumberFormat {
|
||||
NumericPosition pos = subparseNumber(text, position, digits, true, isExponent, status);
|
||||
position = pos.fullPos;
|
||||
|
||||
// First character after the prefix was un-parseable, should
|
||||
// fail regardless if lenient or strict.
|
||||
// First character after the prefix was un-parseable or parsing integer
|
||||
// only with no integer portion. Should fail regardless if lenient or strict.
|
||||
if (position == -1) {
|
||||
parsePosition.index = oldStart;
|
||||
parsePosition.errorIndex = oldStart;
|
||||
@ -2421,8 +2421,8 @@ public class DecimalFormat extends NumberFormat {
|
||||
}
|
||||
|
||||
// When parsing integer only, index should be int pos
|
||||
// If intPos is 0, the entire value was integer
|
||||
if (isParseIntegerOnly() && pos.intPos > 0) {
|
||||
// If intPos is -1, the entire value was integer and index should be full pos
|
||||
if (isParseIntegerOnly() && pos.intPos != -1) {
|
||||
parsePosition.index = pos.intPos;
|
||||
} else {
|
||||
// increment the index by the suffix
|
||||
@ -2474,7 +2474,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
boolean isExponent, boolean[] status) {
|
||||
// process digits or Inf, find decimal position
|
||||
status[STATUS_INFINITE] = false;
|
||||
int intIndex = 0;
|
||||
int intIndex = -1;
|
||||
if (!isExponent && text.regionMatches(position, symbols.getInfinity(), 0,
|
||||
symbols.getInfinity().length())) {
|
||||
position += symbols.getInfinity().length();
|
||||
@ -2570,6 +2570,10 @@ public class DecimalFormat extends NumberFormat {
|
||||
// Cancel out backup setting (see grouping handler below)
|
||||
backup = -1;
|
||||
} else if (!isExponent && ch == decimal) {
|
||||
if (isParseIntegerOnly() && startPos == position) {
|
||||
// Parsing int only with no integer portion, fail
|
||||
return new NumericPosition(-1, intIndex);
|
||||
}
|
||||
// Check grouping size on decimal separator
|
||||
if (parseStrict && isGroupingViolation(position, prevSeparatorIndex)) {
|
||||
return new NumericPosition(
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8327640 8331485 8333456
|
||||
* @bug 8327640 8331485 8333456 8335668
|
||||
* @summary Test suite for NumberFormat parsing when lenient.
|
||||
* @run junit/othervm -Duser.language=en -Duser.country=US LenientParseTest
|
||||
* @run junit/othervm -Duser.language=ja -Duser.country=JP LenientParseTest
|
||||
@ -128,6 +128,28 @@ public class LenientParseTest {
|
||||
dFmt.setParseIntegerOnly(false);
|
||||
}
|
||||
|
||||
// 8335668: Parsing with integer only against String with no integer portion
|
||||
// should fail, not return 0. Expected error index should be 0
|
||||
@Test
|
||||
public void integerParseOnlyFractionOnlyTest() {
|
||||
var fmt = NumberFormat.getIntegerInstance();
|
||||
failParse(fmt, localizeText("."), 0);
|
||||
failParse(fmt, localizeText(".0"), 0);
|
||||
failParse(fmt, localizeText(".55"), 0);
|
||||
}
|
||||
|
||||
// 8335668: Parsing with integer only against String with no integer portion
|
||||
// should fail, not return 0. Expected error index should be 0
|
||||
@Test // Non-localized, run once
|
||||
@EnabledIfSystemProperty(named = "user.language", matches = "en")
|
||||
public void compactIntegerParseOnlyFractionOnlyTest() {
|
||||
var fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
|
||||
fmt.setParseIntegerOnly(true);
|
||||
failParse(fmt, ".K", 0);
|
||||
failParse(fmt, ".0K", 0);
|
||||
failParse(fmt, ".55K", 0);
|
||||
}
|
||||
|
||||
@Test // Non-localized, only run once
|
||||
@EnabledIfSystemProperty(named = "user.language", matches = "en")
|
||||
public void badExponentParseNumberFormatTest() {
|
||||
@ -313,7 +335,11 @@ public class LenientParseTest {
|
||||
Arguments.of("10000", 10000d),
|
||||
Arguments.of("100,000", 100000d),
|
||||
Arguments.of("1,000,000", 1000000d),
|
||||
Arguments.of("10,000,000", 10000000d))
|
||||
Arguments.of("10,000,000", 10000000d),
|
||||
// Smaller value cases (w/ decimal)
|
||||
Arguments.of(".1", .1d),
|
||||
Arguments.of("1.1", 1.1d),
|
||||
Arguments.of("11.1", 11.1d))
|
||||
.map(args -> Arguments.of(
|
||||
localizeText(String.valueOf(args.get()[0])), args.get()[1]));
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8327640 8331485 8333755
|
||||
* @bug 8327640 8331485 8333755 8335668
|
||||
* @summary Test suite for NumberFormat parsing with strict leniency
|
||||
* @run junit/othervm -Duser.language=en -Duser.country=US StrictParseTest
|
||||
* @run junit/othervm -Duser.language=ja -Duser.country=JP StrictParseTest
|
||||
@ -203,6 +203,28 @@ public class StrictParseTest {
|
||||
}
|
||||
}
|
||||
|
||||
// 8335668: Parsing with integer only against String with no integer portion
|
||||
// should fail, not return 0. Expected error index should be 0
|
||||
@Test
|
||||
public void integerParseOnlyFractionOnlyTest() {
|
||||
var fmt = NumberFormat.getIntegerInstance();
|
||||
failParse(fmt, localizeText("."), 0);
|
||||
failParse(fmt, localizeText(".0"), 0);
|
||||
failParse(fmt, localizeText(".55"), 0);
|
||||
}
|
||||
|
||||
// 8335668: Parsing with integer only against String with no integer portion
|
||||
// should fail, not return 0. Expected error index should be 0
|
||||
@Test // Non-localized, run once
|
||||
@EnabledIfSystemProperty(named = "user.language", matches = "en")
|
||||
public void compactIntegerParseOnlyFractionOnlyTest() {
|
||||
var fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
|
||||
fmt.setParseIntegerOnly(true);
|
||||
failParse(fmt, ".K", 0);
|
||||
failParse(fmt, ".0K", 0);
|
||||
failParse(fmt, ".55K", 0);
|
||||
}
|
||||
|
||||
// 8333755: Parsing behavior should follow normal strict behavior
|
||||
// when it comes to failures.
|
||||
@ParameterizedTest
|
||||
@ -426,8 +448,8 @@ public class StrictParseTest {
|
||||
Arguments.of("1,234a", 5),
|
||||
Arguments.of("1,.a", 2),
|
||||
Arguments.of("1.a", 2),
|
||||
Arguments.of(".22a", 3),
|
||||
Arguments.of(".1a1", 2),
|
||||
Arguments.of("1.22a", 4),
|
||||
Arguments.of("1.1a1", 3),
|
||||
Arguments.of("1,234,a", 5),
|
||||
// Double decimal
|
||||
Arguments.of("1,234..5", 5))
|
||||
@ -453,7 +475,11 @@ public class StrictParseTest {
|
||||
Arguments.of("10000", 10000d),
|
||||
Arguments.of("100,000", 100000d),
|
||||
Arguments.of("1,000,000", 1000000d),
|
||||
Arguments.of("10,000,000", 10000000d))
|
||||
Arguments.of("10,000,000", 10000000d),
|
||||
// Smaller value cases (w/ decimal)
|
||||
Arguments.of(".1", .1d),
|
||||
Arguments.of("1.1", 1.1d),
|
||||
Arguments.of("11.1", 11.1d))
|
||||
.map(args -> Arguments.of(
|
||||
localizeText(String.valueOf(args.get()[0])), args.get()[1]));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user