Skip to content

Commit c0a6fd1

Browse files
committed
Merge remote-tracking branch 'upstream/master' into upstream-sync
2 parents 1e7b978 + d2dad32 commit c0a6fd1

File tree

37 files changed

+1524
-1093
lines changed

37 files changed

+1524
-1093
lines changed

.github/actions/build-jtreg/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,4 @@ runs:
6565
with:
6666
name: bundles-jtreg-${{ steps.version.outputs.value }}
6767
path: jtreg/installed
68-
retention-days: 1
68+
retention-days: 5

.github/actions/upload-bundles/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,5 @@ runs:
7373
with:
7474
name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }}
7575
path: bundles
76-
retention-days: 1
76+
retention-days: 5
7777
if: steps.bundles.outputs.bundles-found == 'true'

src/java.base/share/classes/java/util/regex/Pattern.java

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -1090,6 +1090,10 @@ public static Pattern compile(String regex) {
10901090
*
10911091
* @throws PatternSyntaxException
10921092
* If the expression's syntax is invalid
1093+
*
1094+
* @implNote If {@link #CANON_EQ} is specified and the number of combining
1095+
* marks for any character is too large, an {@link java.lang.OutOfMemoryError}
1096+
* is thrown.
10931097
*/
10941098
public static Pattern compile(String regex, int flags) {
10951099
return new Pattern(regex, flags);
@@ -1123,6 +1127,13 @@ public String toString() {
11231127
* The character sequence to be matched
11241128
*
11251129
* @return A new matcher for this pattern
1130+
*
1131+
* @implNote When a {@link Pattern} is deserialized, compilation is deferred
1132+
* until a direct or indirect invocation of this method. Thus, if a
1133+
* deserialized pattern has {@link #CANON_EQ} among its flags and the number
1134+
* of combining marks for any character is too large, an
1135+
* {@link java.lang.OutOfMemoryError} is thrown,
1136+
* as in {@link #compile(String, int)}.
11261137
*/
11271138
public Matcher matcher(CharSequence input) {
11281139
if (!compiled) {
@@ -1596,14 +1607,30 @@ private static String[] producePermutations(String input) {
15961607
return result;
15971608
}
15981609

1599-
int length = 1;
1610+
/*
1611+
* Since
1612+
* 12! = 479_001_600 < Integer.MAX_VALUE
1613+
* 13! = 6_227_020_800 > Integer.MAX_VALUE
1614+
* the computation of n! using int arithmetic will overflow iff
1615+
* n < 0 or n > 12
1616+
*
1617+
* Here, nCodePoints! is computed in the next for-loop below.
1618+
* As nCodePoints >= 0, the computation overflows iff nCodePoints > 12.
1619+
* In that case, throw OOME to simulate length > Integer.MAX_VALUE.
1620+
*/
16001621
int nCodePoints = countCodePoints(input);
1601-
for(int x=1; x<nCodePoints; x++)
1602-
length = length * (x+1);
1622+
if (nCodePoints > 12) {
1623+
throw new OutOfMemoryError("Pattern too complex");
1624+
}
16031625

1626+
/* Compute length = nCodePoints! */
1627+
int length = 1;
1628+
for (int x = 2; x <= nCodePoints; ++x) {
1629+
length *= x;
1630+
}
16041631
String[] temp = new String[length];
16051632

1606-
int combClass[] = new int[nCodePoints];
1633+
int[] combClass = new int[nCodePoints];
16071634
for(int x=0, i=0; x<nCodePoints; x++) {
16081635
int c = Character.codePointAt(input, i);
16091636
combClass[x] = getClass(c);

src/java.desktop/share/classes/sun/font/FileFontStrike.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,6 @@ public class FileFontStrike extends PhysicalStrike {
202202
this.disposer = new FontStrikeDisposer(fileFont, desc);
203203
initGlyphCache();
204204
pScalerContext = NullFontScaler.getNullScalerContext();
205-
SunFontManager.getInstance().deRegisterBadFont(fileFont);
206205
return;
207206
}
208207
/* First, see if native code should be used to create the glyph.

src/java.desktop/share/native/libfontmanager/freetypeScaler.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,6 @@ Java_sun_font_FreetypeFontScaler_createScalerContextNative(
500500

501501
if (context == NULL) {
502502
free(context);
503-
invalidateJavaScaler(env, scaler, NULL);
504503
return (jlong) 0;
505504
}
506505
(*env)->GetDoubleArrayRegion(env, matrix, 0, 4, dmat);

src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,8 +464,8 @@ private CompletableFuture<Response> expectContinue(ExchangeImpl<T> ex) {
464464
"Unable to handle 101 while waiting for 100");
465465
return MinimalFuture.failedFuture(failed);
466466
}
467-
return exchImpl.readBodyAsync(this::ignoreBody, false, parentExecutor)
468-
.thenApply(v -> r1);
467+
exchImpl.expectContinueFailed(rcode);
468+
return MinimalFuture.completedFuture(r1);
469469
}
470470
});
471471
}

src/java.net.http/share/classes/jdk/internal/net/http/ExchangeImpl.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,4 +260,8 @@ HttpBodySubscriberWrapper<T> createResponseSubscriber(HttpResponse.BodyHandler<T
260260
// Needed to handle cancellation during the upgrade from
261261
// Http1Exchange to Stream
262262
void upgraded() { }
263+
264+
// Called when server returns non 100 response to
265+
// an Expect-Continue
266+
void expectContinueFailed(int rcode) { }
263267
}

src/java.net.http/share/classes/jdk/internal/net/http/Http1Exchange.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,4 +863,14 @@ final HttpClientImpl client() {
863863
String dbgString() {
864864
return "Http1Exchange";
865865
}
866+
867+
@Override
868+
void expectContinueFailed(int rcode) {
869+
var response = this.response;
870+
if (response != null) {
871+
// Sets a flag which closes the connection locally when
872+
// onFinished() is called
873+
response.closeWhenFinished();
874+
}
875+
}
866876
}

src/java.net.http/share/classes/jdk/internal/net/http/Http1Response.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class Http1Response<T> {
6666
private final Http1AsyncReceiver asyncReceiver;
6767
private volatile EOFException eof;
6868
private volatile BodyParser bodyParser;
69+
private volatile boolean closeWhenFinished;
6970
// max number of bytes of (fixed length) body to ignore on redirect
7071
private static final int MAX_IGNORE = 1024;
7172

@@ -404,7 +405,11 @@ public <U> CompletableFuture<U> readBody(HttpResponse.BodySubscriber<U> p,
404405

405406
private void onFinished() {
406407
asyncReceiver.clear();
407-
if (return2Cache) {
408+
if (closeWhenFinished) {
409+
if (debug.on())
410+
debug.log("Closing Connection when finished");
411+
connection.close();
412+
} else if (return2Cache) {
408413
Log.logTrace("Attempting to return connection to the pool: {0}", connection);
409414
// TODO: need to do something here?
410415
// connection.setAsyncCallbacks(null, null, null);
@@ -416,6 +421,10 @@ private void onFinished() {
416421
}
417422
}
418423

424+
void closeWhenFinished() {
425+
closeWhenFinished = true;
426+
}
427+
419428
HttpHeaders responseHeaders() {
420429
return headers;
421430
}

src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -279,23 +279,25 @@ public String toString() {
279279
}
280280
}
281281

282-
static void registerPending(PendingRequest pending) {
282+
static <T> CompletableFuture<T> registerPending(PendingRequest pending, CompletableFuture<T> res) {
283283
// shortcut if cf is already completed: no need to go through the trouble of
284284
// registering it
285-
if (pending.cf.isDone()) return;
285+
if (pending.cf.isDone()) return res;
286286

287287
var client = pending.client;
288288
var cf = pending.cf;
289289
var id = pending.id;
290290
boolean added = client.pendingRequests.add(pending);
291291
// this may immediately remove `pending` from the set is the cf is already completed
292-
pending.ref = cf.whenComplete((r,t) -> client.pendingRequests.remove(pending));
292+
var ref = res.whenComplete((r,t) -> client.pendingRequests.remove(pending));
293+
pending.ref = ref;
293294
assert added : "request %d was already added".formatted(id);
294295
// should not happen, unless the selector manager has already
295296
// exited abnormally
296297
if (client.selmgr.isClosed()) {
297298
pending.abort(client.selmgr.selectorClosedException());
298299
}
300+
return ref;
299301
}
300302

301303
static void abortPendingRequests(HttpClientImpl client, Throwable reason) {
@@ -558,8 +560,9 @@ public boolean registerSubscriber(HttpBodySubscriberWrapper<?> subscriber) {
558560
if (debug.on()) {
559561
debug.log("body subscriber registered: " + count);
560562
}
563+
return true;
561564
}
562-
return true;
565+
return false;
563566
}
564567
}
565568
}
@@ -875,8 +878,9 @@ private void debugCompleted(String tag, long startNanos, HttpRequest req) {
875878
cf = sendAsync(req, responseHandler, null, null);
876879
return cf.get();
877880
} catch (InterruptedException ie) {
878-
if (cf != null )
881+
if (cf != null) {
879882
cf.cancel(true);
883+
}
880884
throw ie;
881885
} catch (ExecutionException e) {
882886
final Throwable throwable = e.getCause();
@@ -991,19 +995,23 @@ private void debugCompleted(String tag, long startNanos, HttpRequest req) {
991995
(b,t) -> debugCompleted("ClientImpl (async)", start, userRequest));
992996
}
993997

994-
// makes sure that any dependent actions happen in the CF default
995-
// executor. This is only needed for sendAsync(...), when
996-
// exchangeExecutor is non-null.
997-
if (exchangeExecutor != null) {
998-
res = res.whenCompleteAsync((r, t) -> { /* do nothing */}, ASYNC_POOL);
999-
}
1000-
1001998
// The mexCf is the Cf we need to abort if the SelectorManager thread
1002999
// is aborted.
10031000
PendingRequest pending = new PendingRequest(id, requestImpl, mexCf, mex, this);
1004-
registerPending(pending);
1005-
return res;
1006-
} catch(Throwable t) {
1001+
res = registerPending(pending, res);
1002+
1003+
if (exchangeExecutor != null) {
1004+
// makes sure that any dependent actions happen in the CF default
1005+
// executor. This is only needed for sendAsync(...), when
1006+
// exchangeExecutor is non-null.
1007+
return res.isDone() ? res
1008+
: res.whenCompleteAsync((r, t) -> { /* do nothing */}, ASYNC_POOL);
1009+
} else {
1010+
// make a defensive copy that can be safely canceled
1011+
// by the caller
1012+
return res.isDone() ? res : res.copy();
1013+
}
1014+
} catch (Throwable t) {
10071015
requestUnreference();
10081016
debugCompleted("ClientImpl (async)", start, userRequest);
10091017
throw t;

0 commit comments

Comments
 (0)