Skip to content

Commit

Permalink
Merge master jdk-17.0.13+11 into openj9-staging
Browse files Browse the repository at this point in the history
Signed-off-by: J9 Build <j9build@ca.ibm.com>
  • Loading branch information
j9build committed Oct 15, 2024
2 parents 9f0107b + 4fbc126 commit aa7efd0
Show file tree
Hide file tree
Showing 62 changed files with 2,502 additions and 433 deletions.
2 changes: 1 addition & 1 deletion make/conf/version-numbers.conf
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ DEFAULT_VERSION_CLASSFILE_MINOR=0
DEFAULT_VERSION_DOCS_API_SINCE=11
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="16 17"
DEFAULT_JDK_SOURCE_TARGET_VERSION=17
DEFAULT_PROMOTED_VERSION_PRE=ea
DEFAULT_PROMOTED_VERSION_PRE=
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,15 @@ <H2>Misc HTTP URL stream protocol handler properties</H2>
</OL>
<P>The channel binding tokens generated are of the type "tls-server-end-point" as defined in
RFC 5929.</P>

<LI><P><B>{@systemProperty jdk.http.maxHeaderSize}</B> (default: 393216 or 384kB)<BR>
This is the maximum header field section size that a client is prepared to accept.
This is computed as the sum of the size of the uncompressed header name, plus
the size of the uncompressed header value, plus an overhead of 32 bytes for
each field section line. If a peer sends a field section that exceeds this
size a {@link java.net.ProtocolException ProtocolException} will be raised.
This applies to all versions of the HTTP protocol. A value of zero or a negative
value means no limit. If left unspecified, the default value is 393216 bytes.
</UL>
<P>All these properties are checked only once at startup.</P>
<a id="AddressCache"></a>
Expand Down
60 changes: 50 additions & 10 deletions src/java.base/share/classes/java/text/MessageFormat.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import java.io.InvalidObjectException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -983,6 +984,8 @@ public Object[] parse(String source, ParsePosition pos) {
maximumArgumentNumber = argumentNumbers[i];
}
}

// Constructors/applyPattern ensure that resultArray.length < MAX_ARGUMENT_INDEX
Object[] resultArray = new Object[maximumArgumentNumber + 1];

int patternOffset = 0;
Expand Down Expand Up @@ -1235,6 +1238,9 @@ protected Object readResolve() throws InvalidObjectException {
* @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
Expand Down Expand Up @@ -1459,6 +1465,11 @@ private void makeFormat(int position, int offsetNumber,
+ 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;
Expand Down Expand Up @@ -1606,24 +1617,53 @@ private static final void copyAndFixQuotes(String source, int start, int end,
*/
@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");
}
}
55 changes: 55 additions & 0 deletions src/java.base/share/classes/sun/net/www/MessageHeader.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
package sun.net.www;

import java.io.*;
import java.lang.reflect.Array;
import java.net.ProtocolException;
import java.util.Collections;
import java.util.*;

Expand All @@ -46,11 +48,32 @@ class MessageHeader {
private String values[];
private int nkeys;

// max number of bytes for headers, <=0 means unlimited;
// this corresponds to the length of the names, plus the length
// of the values, plus an overhead of 32 bytes per name: value
// pair.
// Note: we use the same definition as HTTP/2 SETTINGS_MAX_HEADER_LIST_SIZE
// see RFC 9113, section 6.5.2.
// https://www.rfc-editor.org/rfc/rfc9113.html#SETTINGS_MAX_HEADER_LIST_SIZE
private final int maxHeaderSize;

// Aggregate size of the field lines (name + value + 32) x N
// that have been parsed and accepted so far.
// This is defined as a long to force promotion to long
// and avoid overflows; see checkNewSize;
private long size;

public MessageHeader () {
this(0);
}

public MessageHeader (int maxHeaderSize) {
this.maxHeaderSize = maxHeaderSize;
grow();
}

public MessageHeader (InputStream is) throws java.io.IOException {
maxHeaderSize = 0;
parseHeader(is);
}

Expand Down Expand Up @@ -477,10 +500,28 @@ public static String canonicalID(String id) {
public void parseHeader(InputStream is) throws java.io.IOException {
synchronized (this) {
nkeys = 0;
size = 0;
}
mergeHeader(is);
}

private void checkMaxHeaderSize(int sz) throws ProtocolException {
if (maxHeaderSize > 0) checkNewSize(size, sz, 0);
}

private long checkNewSize(long size, int name, int value) throws ProtocolException {
// See SETTINGS_MAX_HEADER_LIST_SIZE, RFC 9113, section 6.5.2.
long newSize = size + name + value + 32;
if (maxHeaderSize > 0 && newSize > maxHeaderSize) {
Arrays.fill(keys, 0, nkeys, null);
Arrays.fill(values,0, nkeys, null);
nkeys = 0;
throw new ProtocolException(String.format("Header size too big: %s > %s",
newSize, maxHeaderSize));
}
return newSize;
}

/** Parse and merge a MIME header from an input stream. */
@SuppressWarnings("fallthrough")
public void mergeHeader(InputStream is) throws java.io.IOException {
Expand All @@ -494,7 +535,15 @@ public void mergeHeader(InputStream is) throws java.io.IOException {
int c;
boolean inKey = firstc > ' ';
s[len++] = (char) firstc;
checkMaxHeaderSize(len);
parseloop:{
// We start parsing for a new name value pair here.
// The max header size includes an overhead of 32 bytes per
// name value pair.
// See SETTINGS_MAX_HEADER_LIST_SIZE, RFC 9113, section 6.5.2.
long maxRemaining = maxHeaderSize > 0
? maxHeaderSize - size - 32
: Long.MAX_VALUE;
while ((c = is.read()) >= 0) {
switch (c) {
case ':':
Expand Down Expand Up @@ -528,6 +577,9 @@ public void mergeHeader(InputStream is) throws java.io.IOException {
s = ns;
}
s[len++] = (char) c;
if (maxHeaderSize > 0 && len > maxRemaining) {
checkMaxHeaderSize(len);
}
}
firstc = -1;
}
Expand All @@ -549,6 +601,9 @@ public void mergeHeader(InputStream is) throws java.io.IOException {
v = new String();
else
v = String.copyValueOf(s, keyend, len - keyend);
int klen = k == null ? 0 : k.length();

size = checkNewSize(size, klen, v.length());
add(k, v);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
*/
private static int bufSize4ES = 0;

private static final int maxHeaderSize;

/*
* Restrict setting of request headers through the public api
* consistent with JavaScript XMLHttpRequest2 with a few
Expand Down Expand Up @@ -285,6 +287,19 @@ private static Set<String> schemesListToSet(String list) {
} else {
restrictedHeaderSet = null;
}

int defMaxHeaderSize = 384 * 1024;
String maxHeaderSizeStr = getNetProperty("jdk.http.maxHeaderSize");
int maxHeaderSizeVal = defMaxHeaderSize;
if (maxHeaderSizeStr != null) {
try {
maxHeaderSizeVal = Integer.parseInt(maxHeaderSizeStr);
} catch (NumberFormatException n) {
maxHeaderSizeVal = defMaxHeaderSize;
}
}
if (maxHeaderSizeVal < 0) maxHeaderSizeVal = 0;
maxHeaderSize = maxHeaderSizeVal;
}

static final String httpVersion = "HTTP/1.1";
Expand Down Expand Up @@ -759,7 +774,7 @@ private void writeRequests() throws IOException {
}
ps = (PrintStream) http.getOutputStream();
connected=true;
responses = new MessageHeader();
responses = new MessageHeader(maxHeaderSize);
setRequests=false;
writeRequests();
}
Expand Down Expand Up @@ -917,7 +932,7 @@ protected HttpURLConnection(URL u, Proxy p, Handler handler)
throws IOException {
super(checkURL(u));
requests = new MessageHeader();
responses = new MessageHeader();
responses = new MessageHeader(maxHeaderSize);
userHeaders = new MessageHeader();
this.handler = handler;
instProxy = p;
Expand Down Expand Up @@ -2872,7 +2887,7 @@ private boolean followRedirect0(String loc, int stat, URL locUrl)
}

// clear out old response headers!!!!
responses = new MessageHeader();
responses = new MessageHeader(maxHeaderSize);
if (stat == HTTP_USE_PROXY) {
/* This means we must re-request the resource through the
* proxy denoted in the "Location:" field of the response.
Expand Down Expand Up @@ -3062,7 +3077,7 @@ private void reset() throws IOException {
} catch (IOException e) { }
}
responseCode = -1;
responses = new MessageHeader();
responses = new MessageHeader(maxHeaderSize);
connected = false;
}

Expand Down
5 changes: 3 additions & 2 deletions src/java.base/share/classes/sun/security/ssl/ClientHello.java
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,6 @@ byte[] getHelloCookieBytes() {
// ignore cookie
hos.putBytes16(getEncodedCipherSuites());
hos.putBytes8(compressionMethod);
extensions.send(hos); // In TLS 1.3, use of certain
// extensions is mandatory.
} catch (IOException ioe) {
// unlikely
}
Expand Down Expand Up @@ -1427,6 +1425,9 @@ public void consume(ConnectionContext context,
shc.handshakeProducers.put(SSLHandshake.SERVER_HELLO.id,
SSLHandshake.SERVER_HELLO);

// Reset the ClientHello non-zero offset fragment allowance
shc.acceptCliHelloFragments = false;

//
// produce
//
Expand Down
Loading

0 comments on commit aa7efd0

Please sign in to comment.