mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
8331446: Improve deserialization support
Reviewed-by: rhalade, skoivu, rriggs, naoto
This commit is contained in:
parent
dadcee1b89
commit
d9f6383037
3 changed files with 243 additions and 10 deletions
|
@ -41,6 +41,7 @@ package java.text;
|
|||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectStreamException;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -1181,6 +1182,8 @@ public class MessageFormat extends Format {
|
|||
maximumArgumentNumber = argumentNumbers[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Constructors/applyPattern ensure that resultArray.length < MAX_ARGUMENT_INDEX
|
||||
Object[] resultArray = new Object[maximumArgumentNumber + 1];
|
||||
|
||||
int patternOffset = 0;
|
||||
|
@ -1459,6 +1462,9 @@ public class MessageFormat extends Format {
|
|||
* @serial
|
||||
*/
|
||||
private int[] argumentNumbers = new int[INITIAL_FORMATS];
|
||||
// Implementation limit for ArgumentIndex pattern element. Valid indices must
|
||||
// be less than this value
|
||||
private static final int MAX_ARGUMENT_INDEX = 10000;
|
||||
|
||||
/**
|
||||
* One less than the number of entries in {@code offsets}. Can also be thought of
|
||||
|
@ -1639,6 +1645,11 @@ public class MessageFormat extends Format {
|
|||
+ argumentNumber);
|
||||
}
|
||||
|
||||
if (argumentNumber >= MAX_ARGUMENT_INDEX) {
|
||||
throw new IllegalArgumentException(
|
||||
argumentNumber + " exceeds the ArgumentIndex implementation limit");
|
||||
}
|
||||
|
||||
// resize format information arrays if necessary
|
||||
if (offsetNumber >= formats.length) {
|
||||
int newLength = formats.length * 2;
|
||||
|
@ -2006,24 +2017,53 @@ public class MessageFormat extends Format {
|
|||
*/
|
||||
@java.io.Serial
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
boolean isValid = maxOffset >= -1
|
||||
&& formats.length > maxOffset
|
||||
&& offsets.length > maxOffset
|
||||
&& argumentNumbers.length > maxOffset;
|
||||
ObjectInputStream.GetField fields = in.readFields();
|
||||
if (fields.defaulted("argumentNumbers") || fields.defaulted("offsets")
|
||||
|| fields.defaulted("formats") || fields.defaulted("locale")
|
||||
|| fields.defaulted("pattern") || fields.defaulted("maxOffset")){
|
||||
throw new InvalidObjectException("Stream has missing data");
|
||||
}
|
||||
|
||||
locale = (Locale) fields.get("locale", null);
|
||||
String patt = (String) fields.get("pattern", null);
|
||||
int maxOff = fields.get("maxOffset", -2);
|
||||
int[] argNums = ((int[]) fields.get("argumentNumbers", null)).clone();
|
||||
int[] offs = ((int[]) fields.get("offsets", null)).clone();
|
||||
Format[] fmts = ((Format[]) fields.get("formats", null)).clone();
|
||||
|
||||
// Check arrays/maxOffset have correct value/length
|
||||
boolean isValid = maxOff >= -1 && argNums.length > maxOff
|
||||
&& offs.length > maxOff && fmts.length > maxOff;
|
||||
|
||||
// Check the correctness of arguments and offsets
|
||||
if (isValid) {
|
||||
int lastOffset = pattern.length() + 1;
|
||||
for (int i = maxOffset; i >= 0; --i) {
|
||||
if ((offsets[i] < 0) || (offsets[i] > lastOffset)) {
|
||||
int lastOffset = patt.length() + 1;
|
||||
for (int i = maxOff; i >= 0; --i) {
|
||||
if (argNums[i] < 0 || argNums[i] >= MAX_ARGUMENT_INDEX
|
||||
|| offs[i] < 0 || offs[i] > lastOffset) {
|
||||
isValid = false;
|
||||
break;
|
||||
} else {
|
||||
lastOffset = offsets[i];
|
||||
lastOffset = offs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isValid) {
|
||||
throw new InvalidObjectException("Could not reconstruct MessageFormat from corrupt stream.");
|
||||
throw new InvalidObjectException("Stream has invalid data");
|
||||
}
|
||||
maxOffset = maxOff;
|
||||
pattern = patt;
|
||||
offsets = offs;
|
||||
formats = fmts;
|
||||
argumentNumbers = argNums;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialization without data not supported for this class.
|
||||
*/
|
||||
@java.io.Serial
|
||||
private void readObjectNoData() throws ObjectStreamException {
|
||||
throw new InvalidObjectException("Deserialized MessageFormat objects need data");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue