Skip to content

Commit aa7efd0

Browse files
committed
Merge master jdk-17.0.13+11 into openj9-staging
Signed-off-by: J9 Build <[email protected]>
2 parents 9f0107b + 4fbc126 commit aa7efd0

File tree

62 files changed

+2502
-433
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+2502
-433
lines changed

make/conf/version-numbers.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ DEFAULT_VERSION_CLASSFILE_MINOR=0
3939
DEFAULT_VERSION_DOCS_API_SINCE=11
4040
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="16 17"
4141
DEFAULT_JDK_SOURCE_TARGET_VERSION=17
42-
DEFAULT_PROMOTED_VERSION_PRE=ea
42+
DEFAULT_PROMOTED_VERSION_PRE=

src/java.base/share/classes/java/net/doc-files/net-properties.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,15 @@ <H2>Misc HTTP URL stream protocol handler properties</H2>
240240
</OL>
241241
<P>The channel binding tokens generated are of the type "tls-server-end-point" as defined in
242242
RFC 5929.</P>
243+
244+
<LI><P><B>{@systemProperty jdk.http.maxHeaderSize}</B> (default: 393216 or 384kB)<BR>
245+
This is the maximum header field section size that a client is prepared to accept.
246+
This is computed as the sum of the size of the uncompressed header name, plus
247+
the size of the uncompressed header value, plus an overhead of 32 bytes for
248+
each field section line. If a peer sends a field section that exceeds this
249+
size a {@link java.net.ProtocolException ProtocolException} will be raised.
250+
This applies to all versions of the HTTP protocol. A value of zero or a negative
251+
value means no limit. If left unspecified, the default value is 393216 bytes.
243252
</UL>
244253
<P>All these properties are checked only once at startup.</P>
245254
<a id="AddressCache"></a>

src/java.base/share/classes/java/text/MessageFormat.java

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import java.io.InvalidObjectException;
4242
import java.io.IOException;
4343
import java.io.ObjectInputStream;
44+
import java.io.ObjectStreamException;
4445
import java.text.DecimalFormat;
4546
import java.util.ArrayList;
4647
import java.util.Arrays;
@@ -983,6 +984,8 @@ public Object[] parse(String source, ParsePosition pos) {
983984
maximumArgumentNumber = argumentNumbers[i];
984985
}
985986
}
987+
988+
// Constructors/applyPattern ensure that resultArray.length < MAX_ARGUMENT_INDEX
986989
Object[] resultArray = new Object[maximumArgumentNumber + 1];
987990

988991
int patternOffset = 0;
@@ -1235,6 +1238,9 @@ protected Object readResolve() throws InvalidObjectException {
12351238
* @serial
12361239
*/
12371240
private int[] argumentNumbers = new int[INITIAL_FORMATS];
1241+
// Implementation limit for ArgumentIndex pattern element. Valid indices must
1242+
// be less than this value
1243+
private static final int MAX_ARGUMENT_INDEX = 10000;
12381244

12391245
/**
12401246
* One less than the number of entries in {@code offsets}. Can also be thought of
@@ -1459,6 +1465,11 @@ private void makeFormat(int position, int offsetNumber,
14591465
+ argumentNumber);
14601466
}
14611467

1468+
if (argumentNumber >= MAX_ARGUMENT_INDEX) {
1469+
throw new IllegalArgumentException(
1470+
argumentNumber + " exceeds the ArgumentIndex implementation limit");
1471+
}
1472+
14621473
// resize format information arrays if necessary
14631474
if (offsetNumber >= formats.length) {
14641475
int newLength = formats.length * 2;
@@ -1606,24 +1617,53 @@ private static final void copyAndFixQuotes(String source, int start, int end,
16061617
*/
16071618
@java.io.Serial
16081619
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
1609-
in.defaultReadObject();
1610-
boolean isValid = maxOffset >= -1
1611-
&& formats.length > maxOffset
1612-
&& offsets.length > maxOffset
1613-
&& argumentNumbers.length > maxOffset;
1620+
ObjectInputStream.GetField fields = in.readFields();
1621+
if (fields.defaulted("argumentNumbers") || fields.defaulted("offsets")
1622+
|| fields.defaulted("formats") || fields.defaulted("locale")
1623+
|| fields.defaulted("pattern") || fields.defaulted("maxOffset")){
1624+
throw new InvalidObjectException("Stream has missing data");
1625+
}
1626+
1627+
locale = (Locale) fields.get("locale", null);
1628+
String patt = (String) fields.get("pattern", null);
1629+
int maxOff = fields.get("maxOffset", -2);
1630+
int[] argNums = ((int[]) fields.get("argumentNumbers", null)).clone();
1631+
int[] offs = ((int[]) fields.get("offsets", null)).clone();
1632+
Format[] fmts = ((Format[]) fields.get("formats", null)).clone();
1633+
1634+
// Check arrays/maxOffset have correct value/length
1635+
boolean isValid = maxOff >= -1 && argNums.length > maxOff
1636+
&& offs.length > maxOff && fmts.length > maxOff;
1637+
1638+
// Check the correctness of arguments and offsets
16141639
if (isValid) {
1615-
int lastOffset = pattern.length() + 1;
1616-
for (int i = maxOffset; i >= 0; --i) {
1617-
if ((offsets[i] < 0) || (offsets[i] > lastOffset)) {
1640+
int lastOffset = patt.length() + 1;
1641+
for (int i = maxOff; i >= 0; --i) {
1642+
if (argNums[i] < 0 || argNums[i] >= MAX_ARGUMENT_INDEX
1643+
|| offs[i] < 0 || offs[i] > lastOffset) {
16181644
isValid = false;
16191645
break;
16201646
} else {
1621-
lastOffset = offsets[i];
1647+
lastOffset = offs[i];
16221648
}
16231649
}
16241650
}
1651+
16251652
if (!isValid) {
1626-
throw new InvalidObjectException("Could not reconstruct MessageFormat from corrupt stream.");
1653+
throw new InvalidObjectException("Stream has invalid data");
16271654
}
1655+
maxOffset = maxOff;
1656+
pattern = patt;
1657+
offsets = offs;
1658+
formats = fmts;
1659+
argumentNumbers = argNums;
1660+
}
1661+
1662+
/**
1663+
* Serialization without data not supported for this class.
1664+
*/
1665+
@java.io.Serial
1666+
private void readObjectNoData() throws ObjectStreamException {
1667+
throw new InvalidObjectException("Deserialized MessageFormat objects need data");
16281668
}
16291669
}

src/java.base/share/classes/sun/net/www/MessageHeader.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
package sun.net.www;
3131

3232
import java.io.*;
33+
import java.lang.reflect.Array;
34+
import java.net.ProtocolException;
3335
import java.util.Collections;
3436
import java.util.*;
3537

@@ -46,11 +48,32 @@ class MessageHeader {
4648
private String values[];
4749
private int nkeys;
4850

51+
// max number of bytes for headers, <=0 means unlimited;
52+
// this corresponds to the length of the names, plus the length
53+
// of the values, plus an overhead of 32 bytes per name: value
54+
// pair.
55+
// Note: we use the same definition as HTTP/2 SETTINGS_MAX_HEADER_LIST_SIZE
56+
// see RFC 9113, section 6.5.2.
57+
// https://www.rfc-editor.org/rfc/rfc9113.html#SETTINGS_MAX_HEADER_LIST_SIZE
58+
private final int maxHeaderSize;
59+
60+
// Aggregate size of the field lines (name + value + 32) x N
61+
// that have been parsed and accepted so far.
62+
// This is defined as a long to force promotion to long
63+
// and avoid overflows; see checkNewSize;
64+
private long size;
65+
4966
public MessageHeader () {
67+
this(0);
68+
}
69+
70+
public MessageHeader (int maxHeaderSize) {
71+
this.maxHeaderSize = maxHeaderSize;
5072
grow();
5173
}
5274

5375
public MessageHeader (InputStream is) throws java.io.IOException {
76+
maxHeaderSize = 0;
5477
parseHeader(is);
5578
}
5679

@@ -477,10 +500,28 @@ public static String canonicalID(String id) {
477500
public void parseHeader(InputStream is) throws java.io.IOException {
478501
synchronized (this) {
479502
nkeys = 0;
503+
size = 0;
480504
}
481505
mergeHeader(is);
482506
}
483507

508+
private void checkMaxHeaderSize(int sz) throws ProtocolException {
509+
if (maxHeaderSize > 0) checkNewSize(size, sz, 0);
510+
}
511+
512+
private long checkNewSize(long size, int name, int value) throws ProtocolException {
513+
// See SETTINGS_MAX_HEADER_LIST_SIZE, RFC 9113, section 6.5.2.
514+
long newSize = size + name + value + 32;
515+
if (maxHeaderSize > 0 && newSize > maxHeaderSize) {
516+
Arrays.fill(keys, 0, nkeys, null);
517+
Arrays.fill(values,0, nkeys, null);
518+
nkeys = 0;
519+
throw new ProtocolException(String.format("Header size too big: %s > %s",
520+
newSize, maxHeaderSize));
521+
}
522+
return newSize;
523+
}
524+
484525
/** Parse and merge a MIME header from an input stream. */
485526
@SuppressWarnings("fallthrough")
486527
public void mergeHeader(InputStream is) throws java.io.IOException {
@@ -494,7 +535,15 @@ public void mergeHeader(InputStream is) throws java.io.IOException {
494535
int c;
495536
boolean inKey = firstc > ' ';
496537
s[len++] = (char) firstc;
538+
checkMaxHeaderSize(len);
497539
parseloop:{
540+
// We start parsing for a new name value pair here.
541+
// The max header size includes an overhead of 32 bytes per
542+
// name value pair.
543+
// See SETTINGS_MAX_HEADER_LIST_SIZE, RFC 9113, section 6.5.2.
544+
long maxRemaining = maxHeaderSize > 0
545+
? maxHeaderSize - size - 32
546+
: Long.MAX_VALUE;
498547
while ((c = is.read()) >= 0) {
499548
switch (c) {
500549
case ':':
@@ -528,6 +577,9 @@ public void mergeHeader(InputStream is) throws java.io.IOException {
528577
s = ns;
529578
}
530579
s[len++] = (char) c;
580+
if (maxHeaderSize > 0 && len > maxRemaining) {
581+
checkMaxHeaderSize(len);
582+
}
531583
}
532584
firstc = -1;
533585
}
@@ -549,6 +601,9 @@ public void mergeHeader(InputStream is) throws java.io.IOException {
549601
v = new String();
550602
else
551603
v = String.copyValueOf(s, keyend, len - keyend);
604+
int klen = k == null ? 0 : k.length();
605+
606+
size = checkNewSize(size, klen, v.length());
552607
add(k, v);
553608
}
554609
}

src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
171171
*/
172172
private static int bufSize4ES = 0;
173173

174+
private static final int maxHeaderSize;
175+
174176
/*
175177
* Restrict setting of request headers through the public api
176178
* consistent with JavaScript XMLHttpRequest2 with a few
@@ -285,6 +287,19 @@ private static Set<String> schemesListToSet(String list) {
285287
} else {
286288
restrictedHeaderSet = null;
287289
}
290+
291+
int defMaxHeaderSize = 384 * 1024;
292+
String maxHeaderSizeStr = getNetProperty("jdk.http.maxHeaderSize");
293+
int maxHeaderSizeVal = defMaxHeaderSize;
294+
if (maxHeaderSizeStr != null) {
295+
try {
296+
maxHeaderSizeVal = Integer.parseInt(maxHeaderSizeStr);
297+
} catch (NumberFormatException n) {
298+
maxHeaderSizeVal = defMaxHeaderSize;
299+
}
300+
}
301+
if (maxHeaderSizeVal < 0) maxHeaderSizeVal = 0;
302+
maxHeaderSize = maxHeaderSizeVal;
288303
}
289304

290305
static final String httpVersion = "HTTP/1.1";
@@ -759,7 +774,7 @@ private void writeRequests() throws IOException {
759774
}
760775
ps = (PrintStream) http.getOutputStream();
761776
connected=true;
762-
responses = new MessageHeader();
777+
responses = new MessageHeader(maxHeaderSize);
763778
setRequests=false;
764779
writeRequests();
765780
}
@@ -917,7 +932,7 @@ protected HttpURLConnection(URL u, Proxy p, Handler handler)
917932
throws IOException {
918933
super(checkURL(u));
919934
requests = new MessageHeader();
920-
responses = new MessageHeader();
935+
responses = new MessageHeader(maxHeaderSize);
921936
userHeaders = new MessageHeader();
922937
this.handler = handler;
923938
instProxy = p;
@@ -2872,7 +2887,7 @@ private boolean followRedirect0(String loc, int stat, URL locUrl)
28722887
}
28732888

28742889
// clear out old response headers!!!!
2875-
responses = new MessageHeader();
2890+
responses = new MessageHeader(maxHeaderSize);
28762891
if (stat == HTTP_USE_PROXY) {
28772892
/* This means we must re-request the resource through the
28782893
* proxy denoted in the "Location:" field of the response.
@@ -3062,7 +3077,7 @@ private void reset() throws IOException {
30623077
} catch (IOException e) { }
30633078
}
30643079
responseCode = -1;
3065-
responses = new MessageHeader();
3080+
responses = new MessageHeader(maxHeaderSize);
30663081
connected = false;
30673082
}
30683083

src/java.base/share/classes/sun/security/ssl/ClientHello.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,6 @@ byte[] getHelloCookieBytes() {
217217
// ignore cookie
218218
hos.putBytes16(getEncodedCipherSuites());
219219
hos.putBytes8(compressionMethod);
220-
extensions.send(hos); // In TLS 1.3, use of certain
221-
// extensions is mandatory.
222220
} catch (IOException ioe) {
223221
// unlikely
224222
}
@@ -1427,6 +1425,9 @@ public void consume(ConnectionContext context,
14271425
shc.handshakeProducers.put(SSLHandshake.SERVER_HELLO.id,
14281426
SSLHandshake.SERVER_HELLO);
14291427

1428+
// Reset the ClientHello non-zero offset fragment allowance
1429+
shc.acceptCliHelloFragments = false;
1430+
14301431
//
14311432
// produce
14321433
//

0 commit comments

Comments
 (0)