From: Shane Date: Thu, 20 Sep 2018 21:47:25 +0000 (-0700) Subject: ICU-20073 Do not parse stray percent sign in strict mode. (#145) X-Git-Tag: release-63-rc~29 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e5bca0c9f77670ca869b103e9cc7ea44415fb90e;p=icu ICU-20073 Do not parse stray percent sign in strict mode. (#145) --- diff --git a/icu4c/source/i18n/numparse_impl.cpp b/icu4c/source/i18n/numparse_impl.cpp index 5fa52f63351..3192a395938 100644 --- a/icu4c/source/i18n/numparse_impl.cpp +++ b/icu4c/source/i18n/numparse_impl.cpp @@ -159,10 +159,10 @@ NumberParserImpl::createParserFromProperties(const number::impl::DecimalFormatPr // ICU-TC meeting, April 11, 2018: accept percent/permille only if it is in the pattern, // and to maintain regressive behavior, divide by 100 even if no percent sign is present. - if (affixProvider->containsSymbolType(AffixPatternType::TYPE_PERCENT, status)) { + if (!isStrict && affixProvider->containsSymbolType(AffixPatternType::TYPE_PERCENT, status)) { parser->addMatcher(parser->fLocalMatchers.percent = {symbols}); } - if (affixProvider->containsSymbolType(AffixPatternType::TYPE_PERMILLE, status)) { + if (!isStrict && affixProvider->containsSymbolType(AffixPatternType::TYPE_PERMILLE, status)) { parser->addMatcher(parser->fLocalMatchers.permille = {symbols}); } diff --git a/icu4c/source/test/intltest/numfmtst.cpp b/icu4c/source/test/intltest/numfmtst.cpp index ecd6f95380d..2a4d91b84c0 100644 --- a/icu4c/source/test/intltest/numfmtst.cpp +++ b/icu4c/source/test/intltest/numfmtst.cpp @@ -202,6 +202,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n TESTCASE_AUTO(Test11645_ApplyPatternEquality); TESTCASE_AUTO(Test12567); TESTCASE_AUTO(Test11626_CustomizeCurrencyPluralInfo); + TESTCASE_AUTO(Test20073_StrictPercentParseErrorIndex); TESTCASE_AUTO(Test13056_GroupingSize); TESTCASE_AUTO(Test11025_CurrencyPadding); TESTCASE_AUTO(Test11648_ExpDecFormatMalPattern); @@ -8942,6 +8943,17 @@ void NumberFormatTest::Test11626_CustomizeCurrencyPluralInfo() { assertEquals("Plural other", u"99 америчких долара", df.format(99, result.remove(), errorCode)); } +void NumberFormatTest::Test20073_StrictPercentParseErrorIndex() { + IcuTestErrorCode status(*this, "Test20073_StrictPercentParseErrorIndex"); + ParsePosition parsePosition(0); + DecimalFormat df(u"0%", {"en-us", status}, status); + df.setLenient(FALSE); + Formattable result; + df.parse(u"%2%", result, parsePosition); + assertEquals("", 0, parsePosition.getIndex()); + assertEquals("", 0, parsePosition.getErrorIndex()); +} + void NumberFormatTest::Test13056_GroupingSize() { UErrorCode status = U_ZERO_ERROR; DecimalFormat df(u"#,##0", status); diff --git a/icu4c/source/test/intltest/numfmtst.h b/icu4c/source/test/intltest/numfmtst.h index 65e0ffe8f33..9d255383243 100644 --- a/icu4c/source/test/intltest/numfmtst.h +++ b/icu4c/source/test/intltest/numfmtst.h @@ -266,6 +266,7 @@ class NumberFormatTest: public CalendarTimeZoneTest { void Test11645_ApplyPatternEquality(); void Test12567(); void Test11626_CustomizeCurrencyPluralInfo(); + void Test20073_StrictPercentParseErrorIndex(); void Test13056_GroupingSize(); void Test11025_CurrencyPadding(); void Test11648_ExpDecFormatMalPattern(); diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java index fb717496f52..f90775c7fcc 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java @@ -209,10 +209,10 @@ public class NumberParserImpl { // ICU-TC meeting, April 11, 2018: accept percent/permille only if it is in the pattern, // and to maintain regressive behavior, divide by 100 even if no percent sign is present. - if (affixProvider.containsSymbolType(AffixUtils.TYPE_PERCENT)) { + if (!isStrict && affixProvider.containsSymbolType(AffixUtils.TYPE_PERCENT)) { parser.addMatcher(PercentMatcher.getInstance(symbols)); } - if (affixProvider.containsSymbolType(AffixUtils.TYPE_PERMILLE)) { + if (!isStrict && affixProvider.containsSymbolType(AffixUtils.TYPE_PERMILLE)) { parser.addMatcher(PermilleMatcher.getInstance(symbols)); } @@ -274,7 +274,7 @@ public class NumberParserImpl { * The parser settings defined in the PARSE_FLAG_* fields. */ public NumberParserImpl(int parseFlags) { - matchers = new ArrayList(); + matchers = new ArrayList<>(); this.parseFlags = parseFlags; frozen = false; } diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java index d276f1fc0b2..d656b601832 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java @@ -5990,6 +5990,17 @@ public class NumberFormatTest extends TestFmwk { } } + @Test + public void Test20073_StrictPercentParseErrorIndex() { + ParsePosition parsePosition = new ParsePosition(0); + DecimalFormat df = new DecimalFormat("0%", DecimalFormatSymbols.getInstance(Locale.US)); + df.setParseStrict(true); + Number number = df.parse("%2%", parsePosition); + assertNull("", number); + assertEquals("", 0, parsePosition.getIndex()); + assertEquals("", 0, parsePosition.getErrorIndex()); + } + @Test public void Test11626_CustomizeCurrencyPluralInfo() throws ParseException { // Use locale sr because it has interesting plural rules.