ICU-13445 Pattern space handling in localized GMT format parser. Applied a fix to ICU4J equivalent to the ICU4C fix done by #13374. Also made a small fix in the previous ICU4C change to prevent buffer overrun with unexpected input.

X-SVN-Rev: 40642
This commit is contained in:
Yoshito Umaoka 2017-10-25 23:41:57 +00:00
parent 42a7565808
commit f6e3124e74
3 changed files with 24 additions and 8 deletions

View file

@ -1869,8 +1869,8 @@ TimeZoneFormat::parseOffsetFieldsWithPattern(const UnicodeString& text, int32_t
// leading space characters might be truncated. If the first pattern text
// starts with such character (e.g. Bidi control), then we need to
// skip the leading space charcters.
if (!PatternProps::isWhiteSpace(text.char32At(idx))) {
for (;;) {
if (idx < text.length() && !PatternProps::isWhiteSpace(text.char32At(idx))) {
while (len > 0) {
UChar32 ch;
int32_t chLen;
U16_GET(patStr, 0, 0, len, ch)

View file

@ -32,6 +32,7 @@ import java.util.Set;
import com.ibm.icu.impl.ICUData;
import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.impl.PatternProps;
import com.ibm.icu.impl.SoftCache;
import com.ibm.icu.impl.TZDBTimeZoneNames;
import com.ibm.icu.impl.TextTrieMap;
@ -2397,7 +2398,26 @@ public class TimeZoneFormat extends UFormat implements Freezable<TimeZoneFormat>
if (patternItems[i] instanceof String) {
String patStr = (String)patternItems[i];
int len = patStr.length();
if (!text.regionMatches(true, idx, patStr, 0, len)) {
int patIdx = 0;
if (i == 0) {
// When TimeZoneFormat parse() is called from SimpleDateFormat,
// leading space characters might be truncated. If the first pattern text
// starts with such character (e.g. Bidi control), then we need to
// skip the leading space characters.
if (idx < text.length() && !PatternProps.isWhiteSpace(text.codePointAt(idx))) {
while (len > 0) {
int cp = patStr.codePointAt(patIdx);
if (PatternProps.isWhiteSpace(cp)) {
int cpLen = Character.charCount(cp);
len -= cpLen;
patIdx += cpLen;
} else {
break;
}
}
}
}
if (!text.regionMatches(true, idx, patStr, patIdx, len)) {
failed = true;
break;
}

View file

@ -360,7 +360,7 @@ public class TimeZoneFormatTest extends TestFmwk {
new ULocale("ko_KR"), new ULocale("nb_NO"), new ULocale("nl_NL"), new ULocale("nn_NO"), new ULocale("pl_PL"),
new ULocale("pt"), new ULocale("pt_BR"), new ULocale("pt_PT"), new ULocale("ru_RU"), new ULocale("sv_SE"),
new ULocale("th_TH"), new ULocale("tr_TR"), new ULocale("zh"), new ULocale("zh_Hans"), new ULocale("zh_Hans_CN"),
new ULocale("zh_Hant"), new ULocale("zh_Hant_HK"), new ULocale("zh_Hant_TW")
new ULocale("zh_Hant"), new ULocale("zh_Hant_HK"), new ULocale("zh_Hant_TW"), new ULocale("ccp"), new ULocale("fa")
};
} else {
LOCALES = new ULocale[] {
@ -377,10 +377,6 @@ public class TimeZoneFormatTest extends TestFmwk {
int testLen = 0;
for (int locidx = 0; locidx < LOCALES.length; locidx++) {
logln("Locale: " + LOCALES[locidx].toString());
if (LOCALES[locidx].getLanguage().equals("fa")
&& logKnownIssue("13445", "Bidi control in localized GMT pattern")) {
continue;
}
for (int patidx = 0; patidx < PATTERNS.length; patidx++) {
logln(" pattern: " + PATTERNS[patidx]);
String pattern = BASEPATTERN + " " + PATTERNS[patidx];