This commit is contained in:
Jesper Wilhelmsson 2023-01-18 23:29:12 +00:00
commit fc9f8baf56
27 changed files with 446 additions and 231 deletions
src
hotspot/share/jfr
java.base/share
java.desktop
share/classes
com/sun
imageio/plugins/bmp
media/sound
javax/swing/text/html
windows/native
jdk.compiler/share/classes/com/sun/tools/javac/comp
test
jdk/java/foreign
langtools/tools/javac/patterns

@ -132,7 +132,9 @@ bool JfrCheckpointManager::initialize() {
#ifdef ASSERT
static void assert_lease(ConstBufferPtr buffer) {
assert(buffer != NULL, "invariant");
if (buffer == nullptr) {
return;
}
assert(buffer->acquired_by_self(), "invariant");
assert(buffer->lease(), "invariant");
}
@ -293,8 +295,9 @@ BufferPtr JfrCheckpointManager::flush(BufferPtr old, size_t used, size_t request
return NULL;
}
BufferPtr new_buffer = renew(old, thread, used + requested, kind(old));
assert(new_buffer != NULL, "invariant");
migrate_outstanding_writes(old, new_buffer, used, requested);
if (new_buffer != nullptr) {
migrate_outstanding_writes(old, new_buffer, used, requested);
}
retire(old);
return new_buffer;
}

@ -35,13 +35,15 @@ JfrBuffer::JfrBuffer() : _next(NULL),
_size(0),
_header_size(0),
_flags(0),
_context(0) {}
_context(0)
LP64_ONLY(COMMA _pad(0)) {}
void JfrBuffer::initialize(size_t header_size, size_t size) {
assert(_next == NULL, "invariant");
assert(_identity == NULL, "invariant");
_header_size = (u2)header_size;
_size = (u4)(size / BytesPerWord);
assert(header_size <= max_jushort, "invariant");
_header_size = static_cast<u2>(header_size);
_size = size;
set_pos(start());
set_top(start());
assert(free_size() == size, "invariant");

@ -70,10 +70,11 @@ class JfrBuffer {
const void* _identity;
u1* _pos;
mutable const u1* _top;
u4 _size;
size_t _size;
u2 _header_size;
u1 _flags;
u1 _context;
LP64_ONLY(const u4 _pad;)
const u1* stable_top() const;
@ -125,7 +126,7 @@ class JfrBuffer {
void release_critical_section_top(const u1* new_top);
size_t size() const {
return _size * BytesPerWord;
return _size;
}
size_t total_size() const {

@ -202,16 +202,24 @@ inline bool JfrMemorySpace< Client, RetrievalPolicy, FreeListType, FullListType,
// allocations are even multiples of the mspace min size
static inline size_t align_allocation_size(size_t requested_size, size_t min_element_size) {
if (requested_size > static_cast<size_t>(min_intx)) {
assert(false, "requested size: " SIZE_FORMAT " is too large", requested_size);
return 0;
}
u8 alloc_size_bytes = min_element_size;
while (requested_size > alloc_size_bytes) {
alloc_size_bytes <<= 1;
}
return (size_t)alloc_size_bytes;
assert(alloc_size_bytes <= static_cast<size_t>(min_intx), "invariant");
return static_cast<size_t>(alloc_size_bytes);
}
template <typename Client, template <typename> class RetrievalPolicy, typename FreeListType, typename FullListType, bool epoch_aware>
inline typename FreeListType::NodePtr JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::allocate(size_t size) {
const size_t aligned_size_bytes = align_allocation_size(size, _min_element_size);
if (aligned_size_bytes == 0) {
return NULL;
}
void* const allocation = JfrCHeapObj::new_array<u1>(aligned_size_bytes + sizeof(Node));
if (allocation == NULL) {
return NULL;

@ -73,6 +73,7 @@ template <typename T>
inline void WriterHost<BE, IE, WriterPolicyImpl>::write(const T* value, size_t len) {
assert(value != NULL, "invariant");
assert(len > 0, "invariant");
assert(len <= max_jint, "invariant");
// Might need T + 1 size
u1* const pos = ensure_size(sizeof(T) * len + len);
if (pos) {
@ -125,8 +126,9 @@ template <typename T>
inline void WriterHost<BE, IE, WriterPolicyImpl>::be_write(const T* value, size_t len) {
assert(value != NULL, "invariant");
assert(len > 0, "invariant");
// Might need T + 1 size
u1* const pos = ensure_size(sizeof(T) * len + len);
assert(len <= max_jint, "invariant");
// Big endian writes map one-to-one for length, so no extra space is needed.
u1* const pos = ensure_size(sizeof(T) * len);
if (pos) {
this->set_current_pos(BE::be_write(value, len, pos));
}

@ -34,6 +34,7 @@ import javax.crypto.spec.DHGenParameterSpec;
import sun.security.provider.ParameterCache;
import static sun.security.util.SecurityProviderConstants.DEF_DH_KEY_SIZE;
import static sun.security.util.SecurityProviderConstants.getDefDHPrivateExpSize;
/**
* This class represents the key pair generator for Diffie-Hellman key pairs.
@ -60,9 +61,6 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
// The size in bits of the prime modulus
private int pSize;
// The size in bits of the random exponent (private value)
private int lSize;
// The source of randomness
private SecureRandom random;
@ -71,7 +69,8 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
initialize(DEF_DH_KEY_SIZE, null);
}
private static void checkKeySize(int keysize)
// pkg private; used by DHParameterGenerator class as well
static void checkKeySize(int keysize, int expSize)
throws InvalidParameterException {
if ((keysize < 512) || (keysize > 8192) || ((keysize & 0x3F) != 0)) {
@ -80,6 +79,13 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
"from 512 to 8192 (inclusive). " +
"The specific key size " + keysize + " is not supported");
}
// optional, could be 0 if not specified
if ((expSize < 0) || (expSize > keysize)) {
throw new InvalidParameterException
("Exponent size must be positive and no larger than" +
" modulus size");
}
}
/**
@ -91,21 +97,17 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
* @param random the source of randomness
*/
public void initialize(int keysize, SecureRandom random) {
checkKeySize(keysize);
checkKeySize(keysize, 0);
// Use the built-in parameters (ranging from 512 to 8192)
// when available.
this.params = ParameterCache.getCachedDHParameterSpec(keysize);
// Due to performance issue, only support DH parameters generation
// up to 1024 bits.
if ((this.params == null) && (keysize > 1024)) {
throw new InvalidParameterException(
"Unsupported " + keysize + "-bit DH parameter generation");
try {
// Use the built-in parameters (ranging from 512 to 8192)
// when available.
this.params = ParameterCache.getDHParameterSpec(keysize, random);
} catch (GeneralSecurityException e) {
throw new InvalidParameterException(e.getMessage());
}
this.pSize = keysize;
this.lSize = 0;
this.random = random;
}
@ -130,22 +132,13 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
("Inappropriate parameter type");
}
params = (DHParameterSpec)algParams;
params = (DHParameterSpec) algParams;
pSize = params.getP().bitLength();
try {
checkKeySize(pSize);
checkKeySize(pSize, params.getL());
} catch (InvalidParameterException ipe) {
throw new InvalidAlgorithmParameterException(ipe.getMessage());
}
// exponent size is optional, could be 0
lSize = params.getL();
// Require exponentSize < primeSize
if ((lSize != 0) && (lSize > pSize)) {
throw new InvalidAlgorithmParameterException
("Exponent size must not be larger than modulus size");
}
this.random = random;
}
@ -159,24 +152,12 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
random = SunJCE.getRandom();
}
if (params == null) {
try {
params = ParameterCache.getDHParameterSpec(pSize, random);
} catch (GeneralSecurityException e) {
// should never happen
throw new ProviderException(e);
}
}
BigInteger p = params.getP();
BigInteger g = params.getG();
if (lSize <= 0) {
lSize = pSize >> 1;
// use an exponent size of (pSize / 2) but at least 384 bits
if (lSize < 384) {
lSize = 384;
}
int lSize = params.getL();
if (lSize == 0) { // not specified; use our own default
lSize = getDefDHPrivateExpSize(params);
}
BigInteger x;

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -59,7 +59,7 @@ public final class DHParameterGenerator extends AlgorithmParameterGeneratorSpi {
// The source of randomness
private SecureRandom random = null;
private static void checkKeySize(int keysize)
private static void checkSupport(int keysize, int exponentSize)
throws InvalidParameterException {
boolean supported = ((keysize == 2048) || (keysize == 3072) ||
@ -67,9 +67,13 @@ public final class DHParameterGenerator extends AlgorithmParameterGeneratorSpi {
if (!supported) {
throw new InvalidParameterException(
"DH key size must be multiple of 64 and range " +
"Supported DH key size must be multiple of 64 and range " +
"from 512 to 1024 (inclusive), or 2048, 3072. " +
"The specific key size " + keysize + " is not supported");
"The specified key size " + keysize + " is not supported");
}
if (exponentSize != 0) {
DHKeyPairGenerator.checkKeySize(keysize, exponentSize);
}
}
@ -83,7 +87,8 @@ public final class DHParameterGenerator extends AlgorithmParameterGeneratorSpi {
*/
@Override
protected void engineInit(int keysize, SecureRandom random) {
checkKeySize(keysize);
checkSupport(keysize, 0);
this.primeSize = keysize;
this.random = random;
}
@ -108,21 +113,17 @@ public final class DHParameterGenerator extends AlgorithmParameterGeneratorSpi {
("Inappropriate parameter type");
}
DHGenParameterSpec dhParamSpec = (DHGenParameterSpec)genParamSpec;
primeSize = dhParamSpec.getPrimeSize();
exponentSize = dhParamSpec.getExponentSize();
if ((exponentSize <= 0) || (exponentSize >= primeSize)) {
throw new InvalidAlgorithmParameterException(
"Exponent size (" + exponentSize +
") must be positive and less than modulus size (" +
primeSize + ")");
}
DHGenParameterSpec dhParamSpec = (DHGenParameterSpec) genParamSpec;
int primeSize = dhParamSpec.getPrimeSize();
int exponentSize = dhParamSpec.getExponentSize();
try {
checkKeySize(primeSize);
checkSupport(primeSize, exponentSize);
} catch (InvalidParameterException ipe) {
throw new InvalidAlgorithmParameterException(ipe.getMessage());
}
this.primeSize = primeSize;
this.exponentSize = exponentSize;
this.random = random;
}

@ -1508,6 +1508,10 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In
InetAddress[] ret = new InetAddress[1];
if(addr != null) {
if (addr.length == Inet4Address.INADDRSZ) {
if (numericZone != -1 || ifname != null) {
// IPv4-mapped address must not contain zone-id
throw new UnknownHostException(host + ": invalid IPv4-mapped address");
}
ret[0] = new Inet4Address(null, addr);
} else {
if (ifname != null) {
@ -1552,22 +1556,23 @@ public sealed class InetAddress implements Serializable permits Inet4Address, In
int percent = s.indexOf ('%');
int slen = s.length();
int digit, zone=0;
int multmax = Integer.MAX_VALUE / 10; // for int overflow detection
if (percent == -1) {
return -1;
}
for (int i=percent+1; i<slen; i++) {
char c = s.charAt(i);
if (c == ']') {
if (i == percent+1) {
/* empty per-cent field */
return -1;
}
break;
if ((digit = IPAddressUtil.parseAsciiDigit(c, 10)) < 0) {
return -1;
}
if ((digit = Character.digit (c, 10)) < 0) {
if (zone > multmax) {
return -1;
}
zone = (zone * 10) + digit;
if (zone < 0) {
return -1;
}
}
return zone;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -183,7 +183,7 @@ public abstract sealed class MemorySessionImpl
@Override
public final boolean isAccessibleBy(Thread thread) {
Objects.requireNonNull(thread);
return owner == thread;
return owner == null || owner == thread;
}
/**

@ -829,7 +829,7 @@ public class IPAddressUtil {
}
// Parse ASCII digit in given radix
private static int parseAsciiDigit(char c, int radix) {
public static int parseAsciiDigit(char c, int radix) {
assert radix == OCTAL || radix == DECIMAL || radix == HEXADECIMAL;
if (radix == HEXADECIMAL) {
return parseAsciiHexDigit(c);

@ -34,6 +34,7 @@ import java.security.SecureRandom;
import java.security.spec.*;
import javax.crypto.spec.DHParameterSpec;
import sun.security.util.SafeDHParameterSpec;
/**
* Cache for DSA and DH parameter specs. Used by the KeyPairGenerators
@ -55,6 +56,26 @@ public final class ParameterCache {
// cache of DH parameters
private static final Map<Integer,DHParameterSpec> dhCache;
// convert DHParameterSpec to SafeDHParameterSpec if its parameters are
// safe primes; validation takes time but should be worthwhile for the
// parameter cache since the parameters may be reused many times.
private static DHParameterSpec makeSafe(DHParameterSpec spec) {
if (spec instanceof SafeDHParameterSpec) {
return spec;
}
BigInteger p = spec.getP();
BigInteger g = spec.getG();
boolean isSafe = (g.equals(BigInteger.TWO) && p.testBit(0) &&
p.shiftRight(1).isProbablePrime(100));
if (isSafe) {
return new SafeDHParameterSpec(p, g, spec.getL());
} else {
return spec;
}
}
/**
* Return cached DSA parameters for the given length combination of
* prime and subprime, or null if none are available in the cache.
@ -74,7 +95,7 @@ public final class ParameterCache {
* are available in the cache.
*/
public static DHParameterSpec getCachedDHParameterSpec(int keyLength) {
return dhCache.get(Integer.valueOf(keyLength));
return dhCache.get(keyLength);
}
/**
@ -132,7 +153,7 @@ public final class ParameterCache {
gen.init(keyLength, random);
AlgorithmParameters params = gen.generateParameters();
spec = params.getParameterSpec(DHParameterSpec.class);
dhCache.put(Integer.valueOf(keyLength), spec);
dhCache.put(keyLength, makeSafe(spec));
return spec;
}
@ -393,6 +414,12 @@ public final class ParameterCache {
// the common generator
BigInteger dhG = BigInteger.TWO;
// Self generated following the approach from RFC 2412 Appendix E but
// using random source instead of binary expansion of pi
BigInteger dhP512 = new BigInteger(
"FFFFFFFFFFFFFFFF8B479B3A6E8DE86C294188F0BF2CD86C" +
"DB950ADB36D0F61FD51E46F69C99ED95ABE5A7BBB230A6ED" +
"1D0B4506B5317284FFFFFFFFFFFFFFFF", 16);
//
// From RFC 7296
@ -561,16 +588,18 @@ public final class ParameterCache {
"9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" +
"60C980DD98EDD3DFFFFFFFFFFFFFFFFF", 16);
// use DSA parameters for DH for sizes not defined in RFC 7296, 3526
dhCache.put(Integer.valueOf(512), new DHParameterSpec(p512, g512));
// self-generated safe prime
dhCache.put(512, new SafeDHParameterSpec(dhP512, dhG));
dhCache.put(Integer.valueOf(768), new DHParameterSpec(dhP768, dhG));
dhCache.put(Integer.valueOf(1024), new DHParameterSpec(dhP1024, dhG));
dhCache.put(Integer.valueOf(1536), new DHParameterSpec(dhP1536, dhG));
dhCache.put(Integer.valueOf(2048), new DHParameterSpec(dhP2048, dhG));
dhCache.put(Integer.valueOf(3072), new DHParameterSpec(dhP3072, dhG));
dhCache.put(Integer.valueOf(4096), new DHParameterSpec(dhP4096, dhG));
dhCache.put(Integer.valueOf(6144), new DHParameterSpec(dhP6144, dhG));
dhCache.put(Integer.valueOf(8192), new DHParameterSpec(dhP8192, dhG));
// from RFC 7296
dhCache.put(768, new SafeDHParameterSpec(dhP768, dhG));
dhCache.put(1024, new SafeDHParameterSpec(dhP1024, dhG));
// from RFC 3526
dhCache.put(1536, new SafeDHParameterSpec(dhP1536, dhG));
dhCache.put(2048, new SafeDHParameterSpec(dhP2048, dhG));
dhCache.put(3072, new SafeDHParameterSpec(dhP3072, dhG));
dhCache.put(4096, new SafeDHParameterSpec(dhP4096, dhG));
dhCache.put(6144, new SafeDHParameterSpec(dhP6144, dhG));
dhCache.put(8192, new SafeDHParameterSpec(dhP8192, dhG));
}
}

@ -1378,25 +1378,30 @@ final class ClientHello {
shc.resumingSession = resumingSession ? previous : null;
}
HelloCookieManager hcm =
shc.sslContext.getHelloCookieManager(ProtocolVersion.DTLS10);
if (!shc.isResumption &&
!hcm.isCookieValid(shc, clientHello, clientHello.cookie)) {
//
// Perform cookie exchange for DTLS handshaking if no cookie
// or the cookie is invalid in the ClientHello message.
//
// update the responders
shc.handshakeProducers.put(
SSLHandshake.HELLO_VERIFY_REQUEST.id,
SSLHandshake.HELLO_VERIFY_REQUEST);
//
// produce response handshake message
//
SSLHandshake.HELLO_VERIFY_REQUEST.produce(context, clientHello);
// We will by default exchange DTLS cookies for all handshakes
// (new and resumed) unless jdk.tls.enableDtlsResumeCookie=false.
// The property only affects the cookie exchange for resumption.
if (!shc.isResumption || SSLConfiguration.enableDtlsResumeCookie) {
HelloCookieManager hcm =
shc.sslContext.getHelloCookieManager(ProtocolVersion.DTLS10);
if (!hcm.isCookieValid(shc, clientHello, clientHello.cookie)) {
//
// Perform cookie exchange for DTLS handshaking if no cookie
// or the cookie is invalid in the ClientHello message.
//
// update the responders
shc.handshakeProducers.put(
SSLHandshake.HELLO_VERIFY_REQUEST.id,
SSLHandshake.HELLO_VERIFY_REQUEST);
return;
//
// produce response handshake message
//
SSLHandshake.HELLO_VERIFY_REQUEST.produce(context, clientHello);
return;
}
}
// cache the client random number for further using

@ -33,6 +33,7 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.crypto.spec.DHParameterSpec;
import sun.security.util.SafeDHParameterSpec;
/**
* Predefined default DH ephemeral parameters.
@ -280,8 +281,8 @@ final class PredefinedDHParameterSpecs {
String baseGenerator = paramsFinder.group(2);
BigInteger g = new BigInteger(baseGenerator, 16);
DHParameterSpec spec = new DHParameterSpec(p, g);
int primeLen = p.bitLength();
DHParameterSpec spec = new DHParameterSpec(p, g);
defaultParams.put(primeLen, spec);
}
} else if (SSLLogger.isOn && SSLLogger.isOn("sslctx")) {
@ -293,7 +294,7 @@ final class PredefinedDHParameterSpecs {
Map<Integer,DHParameterSpec> tempFFDHEs = new HashMap<>();
for (BigInteger p : ffdhePrimes) {
int primeLen = p.bitLength();
DHParameterSpec dhps = new DHParameterSpec(p, BigInteger.TWO);
DHParameterSpec dhps = new SafeDHParameterSpec(p, BigInteger.TWO);
tempFFDHEs.put(primeLen, dhps);
defaultParams.putIfAbsent(primeLen, dhps);
}
@ -301,8 +302,8 @@ final class PredefinedDHParameterSpecs {
for (BigInteger p : supportedPrimes) {
int primeLen = p.bitLength();
if (defaultParams.get(primeLen) == null) {
defaultParams.put(primeLen,
new DHParameterSpec(p, BigInteger.TWO));
defaultParams.put(primeLen, new SafeDHParameterSpec(p,
BigInteger.TWO));
}
}

@ -116,6 +116,9 @@ final class SSLConfiguration implements Cloneable {
static final boolean enableFFDHE =
Utilities.getBooleanProperty("jsse.enableFFDHE", true);
static final boolean enableDtlsResumeCookie = Utilities.getBooleanProperty(
"jdk.tls.enableDtlsResumeCookie", true);
// Is the extended_master_secret extension supported?
static {
boolean supportExtendedMasterSecret = Utilities.getBooleanProperty(

@ -0,0 +1,45 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.util;
import java.math.BigInteger;
import javax.crypto.spec.DHParameterSpec;
/**
* Internal marker class for well-known safe DH parameters. It should
* only be used with trusted callers since it does not have all the needed
* values for validation.
*/
public final class SafeDHParameterSpec extends DHParameterSpec {
public SafeDHParameterSpec(BigInteger p, BigInteger g) {
super(p, g);
}
public SafeDHParameterSpec(BigInteger p, BigInteger g, int l) {
super(p, g, l);
}
}

@ -33,6 +33,7 @@ import java.security.InvalidParameterException;
import java.security.ProviderException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.spec.DHParameterSpec;
import sun.security.action.GetPropertyAction;
/**
@ -102,6 +103,42 @@ public final class SecurityProviderConstants {
}
}
public static final int getDefDHPrivateExpSize(DHParameterSpec spec) {
int dhGroupSize = spec.getP().bitLength();
if (spec instanceof SafeDHParameterSpec) {
// Known safe primes
// use 2*security strength as default private exponent size
// as in table 2 of NIST SP 800-57 part 1 rev 5, sec 5.6.1.1
// and table 25 of NIST SP 800-56A rev 3, appendix D.
if (dhGroupSize >= 15360) {
return 512;
} else if (dhGroupSize >= 8192) {
return 400;
} else if (dhGroupSize >= 7680) {
return 384;
} else if (dhGroupSize >= 6144) {
return 352;
} else if (dhGroupSize >= 4096) {
return 304;
} else if (dhGroupSize >= 3072) {
return 256;
} else if (dhGroupSize >= 2048) {
return 224;
} else {
// min value for legacy key sizes
return 160;
}
} else {
// assume the worst and use groupSize/2 as private exp length
// up to 1024-bit and use the same minimum 384 as before
return Math.max((dhGroupSize >= 2048 ? 1024 : dhGroupSize >> 1),
384);
}
}
public static final int getDefAESKeySize() {
int currVal = DEF_AES_KEY_SIZE.get();
if (currVal == -1) {

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -869,6 +869,13 @@ getStringUTF8(JNIEnv *env, jstring jstr)
}
}
// Check `jint` overflow
if (rlen < 0) {
(*env)->ReleasePrimitiveArrayCritical(env, value, str, 0);
JNU_ThrowOutOfMemoryError(env, "requested array size exceeds VM limit");
return NULL;
}
result = MALLOC_MIN4(rlen);
if (result == NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, value, str, 0);

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -607,25 +607,20 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
iis.mark();
iis.skipBytes(profileData - size);
byte[] profile = new byte[profileSize];
iis.readFully(profile, 0, profileSize);
byte[] profile = ReaderUtil.
staggeredReadByteStream(iis, profileSize);
iis.reset();
try {
if (metadata.colorSpace == PROFILE_LINKED &&
isLinkedProfileAllowed() &&
!isUncOrDevicePath(profile))
{
String path = new String(profile, "windows-1252");
if (metadata.colorSpace == PROFILE_LINKED &&
isLinkedProfileAllowed())
{
String path = new String(profile, "windows-1252");
colorSpace =
new ICC_ColorSpace(ICC_Profile.getInstance(path));
} else {
colorSpace =
new ICC_ColorSpace(ICC_Profile.getInstance(profile));
}
} catch (Exception e) {
colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
colorSpace =
new ICC_ColorSpace(ICC_Profile.getInstance(path));
} else if (metadata.colorSpace == PROFILE_EMBEDDED) {
colorSpace =
new ICC_ColorSpace(ICC_Profile.getInstance(profile));
}
}
@ -2040,73 +2035,20 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
public void readAborted(ImageReader src) {}
}
private static Boolean isLinkedProfileDisabled = null;
private static Boolean isLinkedProfileAllowed = null;
@SuppressWarnings("removal")
private static boolean isLinkedProfileAllowed() {
if (isLinkedProfileDisabled == null) {
if (isLinkedProfileAllowed == null) {
PrivilegedAction<Boolean> a = new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return Boolean.getBoolean("sun.imageio.plugins.bmp.disableLinkedProfiles");
return Boolean.
getBoolean("sun.imageio.bmp.enableLinkedProfiles");
}
};
isLinkedProfileDisabled = AccessController.doPrivileged(a);
}
return !isLinkedProfileDisabled;
}
private static Boolean isWindowsPlatform = null;
/**
* Verifies whether the byte array contains a unc path.
* Non-UNC path examples:
* c:\path\to\file - simple notation
* \\?\c:\path\to\file - long notation
*
* UNC path examples:
* \\server\share - a UNC path in simple notation
* \\?\UNC\server\share - a UNC path in long notation
* \\.\some\device - a path to device.
*/
@SuppressWarnings("removal")
private static boolean isUncOrDevicePath(byte[] p) {
if (isWindowsPlatform == null) {
PrivilegedAction<Boolean> a = new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
String osname = System.getProperty("os.name");
return (osname != null &&
osname.toLowerCase().startsWith("win"));
}
};
isWindowsPlatform = AccessController.doPrivileged(a);
}
if (!isWindowsPlatform) {
/* no need for the check on platforms except windows */
return false;
}
/* normalize prefix of the path */
if (p[0] == '/') p[0] = '\\';
if (p[1] == '/') p[1] = '\\';
if (p[3] == '/') p[3] = '\\';
if ((p[0] == '\\') && (p[1] == '\\')) {
if ((p[2] == '?') && (p[3] == '\\')) {
// long path: whether unc or local
return ((p[4] == 'U' || p[4] == 'u') &&
(p[5] == 'N' || p[5] == 'n') &&
(p[6] == 'C' || p[6] == 'c'));
} else {
// device path or short unc notation
return true;
}
} else {
return false;
isLinkedProfileAllowed = AccessController.doPrivileged(a);
}
return isLinkedProfileAllowed;
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -48,6 +48,13 @@ import sun.reflect.misc.ReflectUtil;
*/
public final class JARSoundbankReader extends SoundbankReader {
/*
* Name of the system property that enables the Jar soundbank loading
* true if jar sound bank is allowed to be loaded
* default is false
*/
private final static String JAR_SOUNDBANK_ENABLED = "jdk.sound.jarsoundbank";
private static boolean isZIP(URL url) {
boolean ok = false;
try {
@ -70,8 +77,10 @@ public final class JARSoundbankReader extends SoundbankReader {
@SuppressWarnings("deprecation")
public Soundbank getSoundbank(URL url)
throws InvalidMidiDataException, IOException {
if (!isZIP(url))
Objects.requireNonNull(url);
if (!Boolean.getBoolean(JAR_SOUNDBANK_ENABLED) || !isZIP(url))
return null;
ArrayList<Soundbank> soundbanks = new ArrayList<>();
URLClassLoader ucl = URLClassLoader.newInstance(new URL[]{url});
InputStream stream = ucl.getResourceAsStream(
@ -116,6 +125,7 @@ public final class JARSoundbankReader extends SoundbankReader {
@Override
public Soundbank getSoundbank(File file)
throws InvalidMidiDataException, IOException {
Objects.requireNonNull(file);
return getSoundbank(file.toURI().toURL());
}
}

@ -91,13 +91,15 @@ public class ObjectView extends ComponentView {
String classname = (String) attr.getAttribute(HTML.Attribute.CLASSID);
try {
ReflectUtil.checkPackageAccess(classname);
Class<?> c = Class.forName(classname, true,Thread.currentThread().
Class<?> c = Class.forName(classname, false,Thread.currentThread().
getContextClassLoader());
Object o = c.newInstance();
if (o instanceof Component) {
Component comp = (Component) o;
setParameters(comp, attr);
return comp;
if (Component.class.isAssignableFrom(c)) {
Object o = c.newInstance();
if (o instanceof Component) {
Component comp = (Component) o;
setParameters(comp, attr);
return comp;
}
}
} catch (Throwable e) {
// couldn't create a component... fall through to the

@ -25,6 +25,7 @@
#include "awt.h"
#include <math.h>
#include <strsafe.h>
#include "jlong.h"
#include "awt_Font.h"
#include "awt_Toolkit.h"
@ -287,7 +288,6 @@ AwtFont* AwtFont::Create(JNIEnv *env, jobject font, jint angle, jfloat awScale)
return NULL;
}
LPCWSTR textComponentFontName = JNU_GetStringPlatformChars(env, jTextComponentFontName, NULL);
awtFont->m_textInput = -1;
for (int i = 0; i < cfnum; i++) {
// nativeName is a pair of platform fontname and its charset
@ -463,7 +463,7 @@ static HFONT CreateHFont_sub(LPCWSTR name, int style, int height,
// Set font name
WCHAR tmpname[80];
wcscpy(tmpname, name);
StringCchCopy(tmpname, 80, name);
WCHAR* delimit = wcschr(tmpname, L',');
if (delimit != NULL)
*delimit = L'\0'; // terminate the string after the font name.
@ -471,7 +471,7 @@ static HFONT CreateHFont_sub(LPCWSTR name, int style, int height,
strip_tail(tmpname,L""); //strip possible trailing whitespace
strip_tail(tmpname,L"Italic");
strip_tail(tmpname,L"Bold");
wcscpy(&(logFont.lfFaceName[0]), tmpname);
StringCchCopy(&(logFont.lfFaceName[0]), LF_FACESIZE, tmpname);
HFONT hFont = ::CreateFontIndirect(&logFont);
DASSERT(hFont != NULL);
// get a expanded or condensed version if its specified.
@ -502,7 +502,7 @@ HFONT AwtFont::CreateHFont(LPCWSTR name, int style, int height,
// 80 > (max face name(=30) + strlen("CHINESEBIG5_CHARSET"))
// longName doesn't have to be printable. So, it is OK not to convert.
wsprintf(longName, L"%ls-%d-%d", name, style, height);
StringCchPrintf(longName, 80, L"%ls-%d-%d", name, style, height);
HFONT hFont = NULL;
@ -1750,12 +1750,12 @@ LPSTR CCombinedSegTable::GetCodePageSubkey()
lpszCP++; // cf lpszCP = "932"
char szSubKey[KEYLEN];
strcpy(szSubKey, "EUDC\\");
StringCchCopyA(szSubKey, KEYLEN, "EUDC\\");
if ((strlen(szSubKey) + strlen(lpszCP)) >= KEYLEN) {
return NULL;
}
strcpy(&(szSubKey[strlen(szSubKey)]), lpszCP);
strcpy(m_szCodePageSubkey, szSubKey);
StringCchCatA(szSubKey, KEYLEN, lpszCP);
StringCchCopyA(m_szCodePageSubkey, KEYLEN, szSubKey);
return m_szCodePageSubkey;
}
@ -1780,7 +1780,7 @@ void CCombinedSegTable::GetEUDCFileName(LPWSTR lpszFileName, int cchFileName)
// get EUDC font file name
WCHAR szFamilyName[80];
wcscpy(szFamilyName, GetFontName());
StringCchCopy(szFamilyName, 80, GetFontName());
WCHAR* delimit = wcschr(szFamilyName, L',');
if (delimit != NULL)
*delimit = L'\0';
@ -1799,7 +1799,7 @@ void CCombinedSegTable::GetEUDCFileName(LPWSTR lpszFileName, int cchFileName)
if (m_fTTEUDCFileExist == FALSE)
return;
if (wcslen(m_szDefaultEUDCFile) > 0) {
wcscpy(lpszFileName, m_szDefaultEUDCFile);
StringCchCopy(lpszFileName, cchFileName, m_szDefaultEUDCFile);
return;
}
char szDefault[] = "SystemDefaultEUDCFont";
@ -1825,7 +1825,7 @@ void CCombinedSegTable::GetEUDCFileName(LPWSTR lpszFileName, int cchFileName)
VERIFY(::MultiByteToWideChar(CP_ACP, 0,
(LPCSTR)szFileName, -1, lpszFileName, cchFileName) != 0);
if (fUseDefault)
wcscpy(m_szDefaultEUDCFile, lpszFileName);
StringCchCopy(m_szDefaultEUDCFile, _MAX_PATH, lpszFileName);
}
void CCombinedSegTable::Create(LPCWSTR name)

@ -24,6 +24,7 @@
*/
#include "awt.h"
#include <strsafe.h>
#include <math.h>
#include <windef.h>
#include <wtypes.h>
@ -2408,7 +2409,7 @@ static jboolean jFontToWFontW(JNIEnv *env, HDC printDC, jstring fontName,
size_t nameLen = wcslen(fontNameW);
if (nameLen < (sizeof(lf.lfFaceName) / sizeof(lf.lfFaceName[0]))) {
wcscpy(lf.lfFaceName, fontNameW);
StringCchCopyW(lf.lfFaceName, LF_FACESIZE, fontNameW);
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfPitchAndFamily = 0;

@ -24,6 +24,7 @@
*/
#include <windows.h>
#include <strsafe.h>
#include <stdio.h>
#include <jni.h>
@ -63,20 +64,20 @@ JNIEXPORT jstring JNICALL Java_sun_awt_Win32FontManager_getFontPath(JNIEnv *env,
end = strrchr(sysdir,'\\');
if (end && (stricmp(end,"\\System") || stricmp(end,"\\System32"))) {
*end = 0;
strcat(sysdir, "\\Fonts");
StringCchCatA(sysdir, BSIZE, "\\Fonts");
}
GetWindowsDirectory(windir, BSIZE);
if (strlen(windir) > BSIZE-7) {
*windir = 0;
} else {
strcat(windir, "\\Fonts");
StringCchCatA(windir, BSIZE, "\\Fonts");
}
strcpy(fontpath,sysdir);
StringCchCopyA(fontpath, BSIZE*2, sysdir);
if (stricmp(sysdir,windir)) {
strcat(fontpath,";");
strcat(fontpath,windir);
StringCchCatA(fontpath, BSIZE*2, ";");
StringCchCatA(fontpath, BSIZE*2, windir);
}
return JNU_NewStringPlatform(env, fontpath);
@ -152,7 +153,7 @@ static int DifferentFamily(wchar_t *family, wchar_t* fullName) {
info.isDifferent = 0;
memset(&lfw, 0, sizeof(lfw));
wcscpy(lfw.lfFaceName, fullName);
StringCchCopyW(lfw.lfFaceName, LF_FACESIZE, fullName);
lfw.lfCharSet = DEFAULT_CHARSET;
EnumFontFamiliesExW(screenDC, &lfw,
(FONTENUMPROCW)CheckFontFamilyProcW,
@ -349,7 +350,7 @@ static int CALLBACK EnumFamilyNamesW(
}
memset(&lfw, 0, sizeof(lfw));
wcscpy(lfw.lfFaceName, lpelfe->elfLogFont.lfFaceName);
StringCchCopyW(lfw.lfFaceName, LF_FACESIZE, lpelfe->elfLogFont.lfFaceName);
lfw.lfCharSet = lpelfe->elfLogFont.lfCharSet;
EnumFontFamiliesExW(screenDC, &lfw,
(FONTENUMPROCW)EnumFontFacesInFamilyProcW,
@ -653,7 +654,7 @@ Java_sun_awt_Win32FontManager_populateFontFileNameMap0
/* Enumerate fonts via GDI to build maps of fonts and families */
memset(&lfw, 0, sizeof(lfw));
lfw.lfCharSet = DEFAULT_CHARSET; /* all charsets */
wcscpy(lfw.lfFaceName, L""); /* one face per family (CHECK) */
StringCchCopyW(lfw.lfFaceName, LF_FACESIZE, L""); /* one face per family (CHECK) */
EnumFontFamiliesExW(screenDC, &lfw,
(FONTENUMPROCW)EnumFamilyNamesW,
(LPARAM)(&fmi), 0L);

@ -48,6 +48,7 @@
#include <stdio.h>
#include <malloc.h>
#include <math.h>
#include <strsafe.h>
#include <windows.h>
#include <winuser.h>
@ -236,7 +237,7 @@ Java_sun_font_FileFontStrike__1getGlyphImageFromWindows
name[nameLen] = '\0';
if (nameLen < (sizeof(lf.lfFaceName) / sizeof(lf.lfFaceName[0]))) {
wcscpy(lf.lfFaceName, name);
StringCchCopyW(lf.lfFaceName, LF_FACESIZE, name);
} else {
FREE_AND_RETURN;
}

@ -590,14 +590,10 @@ public class TransPatterns extends TreeTranslator {
}
}
c.labels = translatedLabels.toList();
if (c.caseKind == CaseTree.CaseKind.STATEMENT) {
previousCompletesNormally = c.completesNormally;
} else {
previousCompletesNormally = false;
JCBreak brk = make.at(TreeInfo.endPos(c.stats.last())).Break(null);
brk.target = tree;
c.stats = c.stats.append(brk);
}
previousCompletesNormally =
c.caseKind == CaseTree.CaseKind.STATEMENT &&
c.completesNormally;
appendBreakIfNeeded(tree, c);
}
if (tree.hasTag(Tag.SWITCH)) {
@ -642,6 +638,14 @@ public class TransPatterns extends TreeTranslator {
}.scan(c.stats);
}
private void appendBreakIfNeeded(JCTree switchTree, JCCase c) {
if (c.caseKind == CaseTree.CaseKind.RULE) {
JCBreak brk = make.at(TreeInfo.endPos(c.stats.last())).Break(null);
brk.target = switchTree;
c.stats = c.stats.append(brk);
}
}
JCMethodInvocation makeApply(JCExpression selector, Name name, List<JCExpression> args) {
MethodSymbol method = rs.resolveInternalMethod(
currentClassTree.pos(), env,
@ -740,6 +744,7 @@ public class TransPatterns extends TreeTranslator {
} else {
newLabel = List.of(make.PatternCaseLabel(binding, newGuard));
}
appendBreakIfNeeded(currentSwitch, accummulated);
nestedCases.add(make.Case(CaseKind.STATEMENT, newLabel, accummulated.stats, null));
}
if (!hasUnconditional) {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -191,6 +191,25 @@ public class TestSegments {
assertFalse(segment.isReadOnly());
}
@DataProvider(name = "scopes")
public Object[][] scopes() {
return new Object[][] {
{ SegmentScope.auto(), false },
{ SegmentScope.global(), false },
{ Arena.openConfined().scope(), true },
{ Arena.openShared().scope(), false }
};
}
@Test(dataProvider = "scopes")
public void testIsAccessibleBy(SegmentScope scope, boolean isConfined) {
assertTrue(scope.isAccessibleBy(Thread.currentThread()));
assertTrue(scope.isAccessibleBy(new Thread()) != isConfined);
MemorySegment segment = MemorySegment.ofAddress(0, 0, scope);
assertTrue(segment.scope().isAccessibleBy(Thread.currentThread()));
assertTrue(segment.scope().isAccessibleBy(new Thread()) != isConfined);
}
@DataProvider(name = "segmentFactories")
public Object[][] segmentFactories() {
List<Supplier<MemorySegment>> l = List.of(
@ -264,11 +283,9 @@ public class TestSegments {
thread.start();
thread.join();
if (segment.scope().isAccessibleBy(Thread.currentThread())) {
if (!segment.scope().isAccessibleBy(Thread.currentThread())) {
RuntimeException e = exception.get();
if (!(e instanceof IllegalStateException)) {
throw e;
}
throw e;
} else {
assertNull(exception.get());
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,8 +23,9 @@
/**
* @test
* @bug 8291769
* @bug 8291769 8300195
* @summary Verify the compiled code does not have unwanted constructs.
* @enablePreview
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@ -34,11 +35,17 @@
* @run main PatternDesugaring
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import toolbox.TestRunner;
@ -198,4 +205,103 @@ public class PatternDesugaring extends TestRunner {
validate.accept(decompiled);
}
@Test
public void testRuleCases(Path base) throws Exception {
doTestRun(base,
new String[0],
"""
package test;
public class Test {
public static void main(String... args) {
System.out.println(test(new R("a")));
System.out.println(test(new R(3)));
System.out.println(test(new R(new R("a"))));
System.out.println(test(new R(new R(3))));
}
public static int test(Object obj) {
int res;
switch (obj) {
case R(String s) -> res = s.length();
case R(Integer i) -> res = i;
case R(R(String s)) -> res = 10 + s.length();
case R(R(Integer i)) -> res = 10 + i;
default -> res = -1;
}
return res;
}
record R(Object o) {}
}
""",
output -> {
String expectedOutput = """
1
3
11
13
""";
if (!Objects.equals(output, expectedOutput)) {
throw new AssertionError("Unexpected output," +
" expected: " + expectedOutput +
" actual: " + output);
}
});
}
private void doTestRun(Path base, String[] libraryCode, String testCode, Consumer<String> validate) throws Exception {
Path current = base.resolve(".");
Path libClasses = current.resolve("libClasses");
Files.createDirectories(libClasses);
if (libraryCode.length != 0) {
Path libSrc = current.resolve("lib-src");
for (String code : libraryCode) {
tb.writeJavaFiles(libSrc, code);
}
new JavacTask(tb)
.options("--enable-preview",
"-source", JAVA_VERSION)
.outdir(libClasses)
.files(tb.findJavaFiles(libSrc))
.run();
}
Path src = current.resolve("src");
tb.writeJavaFiles(src, testCode);
Path classes = current.resolve("libClasses");
Files.createDirectories(libClasses);
var log =
new JavacTask(tb)
.options("--enable-preview",
"-source", JAVA_VERSION,
"-XDrawDiagnostics",
"-Xlint:-preview",
"--class-path", libClasses.toString(),
"-XDshould-stop.at=FLOW")
.outdir(classes)
.files(tb.findJavaFiles(src))
.run(Task.Expect.SUCCESS)
.writeAll();
ClassLoader cl = new URLClassLoader(new URL[] {classes.toUri().toURL()});
Class<?> testClass = cl.loadClass("test.Test");
Method main = testClass.getMethod("main", String[].class);
PrintStream prevOut = System.out;
var data = new ByteArrayOutputStream();
try (var outStream = new PrintStream(data, true, StandardCharsets.UTF_8)) {
System.setOut(outStream);
main.invoke(null, (Object) new String[0]);
} finally {
System.setOut(prevOut);
}
String output = new String(data.toByteArray(), StandardCharsets.UTF_8);
output = output.replaceAll("\\R", "\n");
validate.accept(output);
}
}