diff options
author | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2012-01-12 18:04:24 +0000 |
---|---|---|
committer | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2012-01-12 18:04:24 +0000 |
commit | 90d2f55bdd2eee86ae2e7073292749bdb1775821 (patch) | |
tree | 4a53c41b387053117a6e721f71a5aacbef223378 /java | |
parent | fd2ca0401d5cbcdee78e1dc78a4165d9f319ed6f (diff) | |
download | classpath-90d2f55bdd2eee86ae2e7073292749bdb1775821.tar.gz |
RH712013: pdftk crashes with java.lang.ArrayIndexOutOfBoundsException
2011-12-12 Andrew John Hughes <ahughes@redhat.com>
RH712013: pdftk crashes with java.lang.ArrayIndexOutOfBoundsException
* java/text/DateFormatSymbols.java:
(getStringArray(List<ResourceBundle>, String, int)):
Calls getStringArray(list,string,int,null).
(getStringArray(List<ResourceBundle>, String, int, String[])):
Populate a String array with locale data. The data
used is the first non-null non-empty element found
as we traverse the locale hierarchy. May be supplemented
by fallback data.
(DateFormatSymbols(Locale)): Get a list of all bundles up the
locale hierarchy, rather than just using the one specific locale.
Use the improved getStringArray method to populate the arrays,
supplying existing data where "sideways" inheritance takes place.
Diffstat (limited to 'java')
-rw-r--r-- | java/text/DateFormatSymbols.java | 81 |
1 files changed, 70 insertions, 11 deletions
diff --git a/java/text/DateFormatSymbols.java b/java/text/DateFormatSymbols.java index c22dd38f7..09ec1aec8 100644 --- a/java/text/DateFormatSymbols.java +++ b/java/text/DateFormatSymbols.java @@ -45,6 +45,7 @@ import java.io.IOException; import java.text.spi.DateFormatSymbolsProvider; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -125,9 +126,58 @@ public class DateFormatSymbols implements java.io.Serializable, Cloneable transient String[] dateFormats; transient String[] timeFormats; - private static String[] getStringArray(ResourceBundle res, String name) + /** + * Compiles a string array for a property using data from each of the locales in the + * hierarchy as necessary. + * + * @param bundles the locale hierarchy, starting with the most specific. + * @param name the name of the property. + * @param size the size the array should be when complete. + * @return a completed string array. + */ + private static String[] getStringArray(List<ResourceBundle> bundles, String name, int size) + { + return getStringArray(bundles, name, size, null); + } + + /** + * Compiles a string array for a property using data from each of the locales in the + * hierarchy as necessary. If non-null, the fallback array is also used for "sideways" + * inheritance (e.g. if there is no short name for a month, the long name is used rather + * than the empty string). + * + * @param bundles the locale hierarchy, starting with the most specific. + * @param name the name of the property. + * @param size the size the array should be when complete. + * @param fallback an array of long name fallback strings for data with both long and short names. + * @return a completed string array. + */ + private static String[] getStringArray(List<ResourceBundle> bundles, String name, int size, + String[] fallback) { - return res.getString(name).split("\u00ae"); + String[] data = new String[size]; + Arrays.fill(data, ""); + // Populate array with data from each locale back to the root, starting with the most specific + for (int a = 0; a < bundles.size(); ++a) + { + String localeData = bundles.get(a).getString(name); + String[] array = localeData.substring(0, localeData.length() -1).split("\u00ae", size); + for (int b = 0; b < data.length; ++b) + { + if (array.length > b && array[b] != null && data[b].isEmpty() && !array[b].isEmpty()) + data[b] = array[b]; + } + } + // Replace any remaining empty strings with data from the fallback array, if non-null + if (fallback != null && fallback.length == size) + { + for (int a = 0; a < data.length; ++a) + { + if (data[a].isEmpty() && fallback[a] != null && !fallback[a].isEmpty()) + data[a] = fallback[a]; + } + } + return data; } private String[][] getZoneStrings(ResourceBundle res, Locale locale) @@ -264,17 +314,26 @@ public class DateFormatSymbols implements java.io.Serializable, Cloneable public DateFormatSymbols (Locale locale) throws MissingResourceException { + ClassLoader ldr = ClassLoader.getSystemClassLoader(); + List<ResourceBundle> bundles = new ArrayList<ResourceBundle>(); ResourceBundle res - = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", locale, - ClassLoader.getSystemClassLoader()); - - ampms = getStringArray(res, "ampms"); - eras = getStringArray(res, "eras"); + = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", locale, ldr); + bundles.add(res); + Locale resLocale = res.getLocale(); + while (resLocale != Locale.ROOT) + { + res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", + LocaleHelper.getFallbackLocale(resLocale), ldr); + bundles.add(res); + resLocale = res.getLocale(); + } + ampms = getStringArray(bundles, "ampms", 2); + eras = getStringArray(bundles, "eras", 2); localPatternChars = res.getString("localPatternChars"); - months = getStringArray(res, "months"); - shortMonths = getStringArray(res, "shortMonths"); - shortWeekdays = getStringArray(res, "shortWeekdays"); - weekdays = getStringArray(res, "weekdays"); + months = getStringArray(bundles, "months", 13); + shortMonths = getStringArray(bundles, "shortMonths", 13, months); + weekdays = getStringArray(bundles, "weekdays", 8); + shortWeekdays = getStringArray(bundles, "shortWeekdays", 8, weekdays); dateFormats = formatsForKey(res, "DateFormat"); timeFormats = formatsForKey(res, "TimeFormat"); runtimeZoneStrings = getZoneStrings(res, locale); |