mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-24 17:20:06 +00:00
7200341: DateFormatSymbols.hashCode() throws ArrayIndexOutOfBoundsException in some circumstances
Reviewed-by: okutsu
This commit is contained in:
parent
2a3853c1b9
commit
04816adee5
@ -45,6 +45,7 @@ import java.lang.ref.SoftReference;
|
||||
import java.text.spi.DateFormatSymbolsProvider;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -366,6 +367,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
|
||||
*/
|
||||
public void setEras(String[] newEras) {
|
||||
eras = Arrays.copyOf(newEras, newEras.length);
|
||||
cachedHashCode = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -393,6 +395,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
|
||||
*/
|
||||
public void setMonths(String[] newMonths) {
|
||||
months = Arrays.copyOf(newMonths, newMonths.length);
|
||||
cachedHashCode = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -420,6 +423,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
|
||||
*/
|
||||
public void setShortMonths(String[] newShortMonths) {
|
||||
shortMonths = Arrays.copyOf(newShortMonths, newShortMonths.length);
|
||||
cachedHashCode = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -439,6 +443,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
|
||||
*/
|
||||
public void setWeekdays(String[] newWeekdays) {
|
||||
weekdays = Arrays.copyOf(newWeekdays, newWeekdays.length);
|
||||
cachedHashCode = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -458,6 +463,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
|
||||
*/
|
||||
public void setShortWeekdays(String[] newShortWeekdays) {
|
||||
shortWeekdays = Arrays.copyOf(newShortWeekdays, newShortWeekdays.length);
|
||||
cachedHashCode = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -474,6 +480,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
|
||||
*/
|
||||
public void setAmPmStrings(String[] newAmpms) {
|
||||
ampms = Arrays.copyOf(newAmpms, newAmpms.length);
|
||||
cachedHashCode = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -558,6 +565,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
|
||||
}
|
||||
zoneStrings = aCopy;
|
||||
isZoneStringsSet = true;
|
||||
cachedHashCode = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -576,6 +584,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
|
||||
public void setLocalPatternChars(String newLocalPatternChars) {
|
||||
// Call toString() to throw an NPE in case the argument is null
|
||||
localPatternChars = newLocalPatternChars.toString();
|
||||
cachedHashCode = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -597,12 +606,23 @@ public class DateFormatSymbols implements Serializable, Cloneable {
|
||||
* Override hashCode.
|
||||
* Generates a hash code for the DateFormatSymbols object.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashcode = 0;
|
||||
String[][] zoneStrings = getZoneStringsWrapper();
|
||||
for (int index = 0; index < zoneStrings[0].length; ++index)
|
||||
hashcode ^= zoneStrings[0][index].hashCode();
|
||||
return hashcode;
|
||||
int hashCode = cachedHashCode;
|
||||
if (hashCode == 0) {
|
||||
hashCode = 5;
|
||||
hashCode = 11 * hashCode + Arrays.hashCode(eras);
|
||||
hashCode = 11 * hashCode + Arrays.hashCode(months);
|
||||
hashCode = 11 * hashCode + Arrays.hashCode(shortMonths);
|
||||
hashCode = 11 * hashCode + Arrays.hashCode(weekdays);
|
||||
hashCode = 11 * hashCode + Arrays.hashCode(shortWeekdays);
|
||||
hashCode = 11 * hashCode + Arrays.hashCode(ampms);
|
||||
hashCode = 11 * hashCode + Arrays.deepHashCode(getZoneStringsWrapper());
|
||||
hashCode = 11 * hashCode + Objects.hashCode(localPatternChars);
|
||||
cachedHashCode = hashCode;
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -641,6 +661,11 @@ public class DateFormatSymbols implements Serializable, Cloneable {
|
||||
|
||||
private transient int lastZoneIndex = 0;
|
||||
|
||||
/**
|
||||
* Cached hash code
|
||||
*/
|
||||
transient volatile int cachedHashCode = 0;
|
||||
|
||||
private void initializeData(Locale desiredLocale) {
|
||||
locale = desiredLocale;
|
||||
|
||||
@ -782,6 +807,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
|
||||
dst.zoneStrings = null;
|
||||
}
|
||||
dst.localPatternChars = src.localPatternChars;
|
||||
dst.cachedHashCode = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -44,6 +44,7 @@ public class DateFormatSymbolsProviderTest extends ProviderTest {
|
||||
DateFormatSymbolsProviderTest() {
|
||||
availableLocalesTest();
|
||||
objectValidityTest();
|
||||
hashCodeTest();
|
||||
}
|
||||
|
||||
void availableLocalesTest() {
|
||||
@ -124,4 +125,17 @@ public class DateFormatSymbolsProviderTest extends ProviderTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bug 7200341.
|
||||
void hashCodeTest() {
|
||||
for (Locale target: availloc) {
|
||||
// look for provider's object
|
||||
DateFormatSymbols dfs = DateFormatSymbols.getInstance(target);
|
||||
if (dfs.getClass().getSimpleName().equals("FooDateFormatSymbols")) {
|
||||
// call its hashCode(). success if no ArrayIndexOutOfBoundsException is thrown.
|
||||
dfs.hashCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# @test
|
||||
# @bug 4052440
|
||||
# @bug 4052440 7200341
|
||||
# @summary DateFormatSymbolsProvider tests
|
||||
# @run shell ExecTest.sh foo DateFormatSymbolsProviderTest true
|
||||
|
||||
Binary file not shown.
@ -221,5 +221,10 @@ public class DateFormatSymbolsProviderImpl extends DateFormatSymbolsProvider {
|
||||
public void setAmPmStrings(String[] newAmpms) {
|
||||
ampms = newAmpms;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[][] getZoneStrings() {
|
||||
return new String[0][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user