Reviewed-by: kcr, prr, smarks
This commit is contained in:
Brent Christian 2026-01-21 01:28:38 +00:00
commit e25a5a4821
37 changed files with 1115 additions and 298 deletions

View File

@ -35,6 +35,13 @@
package java.util.concurrent;
import jdk.internal.misc.Unsafe;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
import java.io.Serial;
import java.io.StreamCorruptedException;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Iterator;
@ -445,4 +452,38 @@ public class CopyOnWriteArraySet<E> extends AbstractSet<E>
return Spliterators.spliterator
(al.getArray(), Spliterator.IMMUTABLE | Spliterator.DISTINCT);
}
/**
* De-serialization without data not supported for this class.
*/
@Serial
private void readObjectNoData() throws ObjectStreamException {
throw new StreamCorruptedException("Deserialized CopyOnWriteArraySet requires data");
}
/**
* Reconstitutes the {@code CopyOnWriteArraySet} instance from a stream
* (that is, deserializes it).
* @throws StreamCorruptedException if the object read from the stream is invalid.
*/
@Serial
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
CopyOnWriteArrayList<E> newAl; // Set during the duplicate check
@SuppressWarnings("unchecked")
CopyOnWriteArrayList<E> inAl = (CopyOnWriteArrayList<E>) in.readFields().get("al", null);
if (inAl == null
|| inAl.getClass() != CopyOnWriteArrayList.class
|| (newAl = new CopyOnWriteArrayList<>()).addAllAbsent(inAl) != inAl.size()) {
throw new StreamCorruptedException("Content is invalid");
}
final Unsafe U = Unsafe.getUnsafe();
U.putReference(
this,
U.objectFieldOffset(CopyOnWriteArraySet.class, "al"),
newAl
);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2025, 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
@ -29,6 +29,7 @@ import java.io.InputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLConnection;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
@ -48,8 +49,11 @@ import java.security.cert.X509CRL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;
import sun.security.x509.AccessDescription;
import sun.security.x509.GeneralNameInterface;
@ -58,6 +62,8 @@ import sun.security.util.Cache;
import sun.security.util.Debug;
import sun.security.util.SecurityProperties;
import javax.security.auth.x500.X500Principal;
/**
* A <code>CertStore</code> that retrieves <code>Certificates</code> or
* <code>CRL</code>s from a URI, for example, as specified in an X.509
@ -182,6 +188,166 @@ class URICertStore extends CertStoreSpi {
return timeoutVal;
}
/**
* Enumeration for the allowed schemes we support when following a
* URI from an authorityInfoAccess extension on a certificate.
*/
private enum AllowedScheme {
HTTP(HttpFtpRuleMatcher.HTTP),
HTTPS(HttpFtpRuleMatcher.HTTPS),
LDAP(LdapRuleMatcher.LDAP),
LDAPS(LdapRuleMatcher.LDAPS),
FTP(HttpFtpRuleMatcher.FTP);
final URIRuleMatcher ruleMatcher;
AllowedScheme(URIRuleMatcher matcher) {
ruleMatcher = matcher;
}
/**
* Return an {@code AllowedScheme} based on a case-insensitive match
* @param name the scheme name to be matched
* @return the {@code AllowedScheme} that corresponds to the
* {@code name} provided, or null if there is no match.
*/
static AllowedScheme nameOf(String name) {
if (name == null) {
return null;
}
try {
return AllowedScheme.valueOf(name.toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException _) {
return null;
}
}
}
private static Set<URI> CA_ISS_URI_FILTERS = null;
private static final boolean CA_ISS_ALLOW_ANY;
static {
boolean allowAny = false;
try {
if (Builder.USE_AIA) {
CA_ISS_URI_FILTERS = new LinkedHashSet<>();
String aiaPropVal = Optional.ofNullable(
SecurityProperties.getOverridableProperty(
"com.sun.security.allowedAIALocations")).
map(String::trim).orElse("");
if (aiaPropVal.equalsIgnoreCase("any")) {
allowAny = true;
if (debug != null) {
debug.println("allowedAIALocations: Warning: " +
"Allow-All URI filtering enabled!");
}
} else {
// Load all the valid rules from the Security property
if (!aiaPropVal.isEmpty()) {
String[] aiaUriStrs = aiaPropVal.trim().split("\\s+");
addCaIssUriFilters(aiaUriStrs);
}
if (CA_ISS_URI_FILTERS.isEmpty()) {
if (debug != null) {
debug.println("allowedAIALocations: Warning: " +
"No valid filters found. Deny-all URI " +
"filtering is active.");
}
}
}
}
} finally {
CA_ISS_ALLOW_ANY = allowAny;
}
}
/**
* Populate the filter collection from the list of AIA CA issuer URIs
* found in the {@code com.sun.security.allowedAIALocations} security
* or system property.
*
* @param aiaUriStrs array containing String URI filters
*/
private static void addCaIssUriFilters(String[] aiaUriStrs) {
for (String aiaStr : aiaUriStrs) {
if (aiaStr != null && !aiaStr.isEmpty()) {
try {
AllowedScheme scheme;
URI aiaUri = new URI(aiaStr).normalize();
// It must be absolute and non-opaque
if (!aiaUri.isAbsolute() || aiaUri.isOpaque()) {
if (debug != null) {
debug.println("allowedAIALocations: Skipping " +
"non-absolute or opaque URI " + aiaUri);
}
} else if (aiaUri.getHost() == null) {
// We do not allow rules with URIs that omit a hostname
// or address.
if (debug != null) {
debug.println("allowedAIALocations: Skipping " +
"URI rule with no hostname or address: " +
aiaUri);
}
} else if ((scheme = AllowedScheme.nameOf(
aiaUri.getScheme())) != null) {
// When it is an LDAP type, we can check the path
// portion (the DN) for proper structure and reject
// the rule early if it isn't correct.
if (scheme == AllowedScheme.LDAP ||
scheme == AllowedScheme.LDAPS) {
try {
new X500Principal(aiaUri.getPath().
replaceFirst("^/+", ""));
} catch (IllegalArgumentException iae) {
if (debug != null) {
debug.println("allowedAIALocations: " +
"Skipping LDAP rule: " + iae);
}
continue;
}
}
// When a URI has a non-null query or fragment
// warn the user upon adding the rule that those
// components will be ignored
if (aiaUri.getQuery() != null) {
if (debug != null) {
debug.println("allowedAIALocations: " +
"Rule will ignore non-null query");
}
}
if (aiaUri.getFragment() != null) {
if (debug != null) {
debug.println("allowedAIALocations: " +
"Rule will ignore non-null fragment");
}
}
CA_ISS_URI_FILTERS.add(aiaUri);
if (debug != null) {
debug.println("allowedAIALocations: Added " +
aiaUri + " to URI filters");
}
} else {
if (debug != null) {
debug.println("allowedAIALocations: Disallowed " +
"filter URI scheme: " +
aiaUri.getScheme());
}
}
} catch (URISyntaxException urise) {
if (debug != null) {
debug.println("allowedAIALocations: Skipping " +
"filter URI entry " + aiaStr +
": parse failure at index " + urise.getIndex());
}
}
}
}
}
/**
* Creates a URICertStore.
*
@ -244,6 +410,39 @@ class URICertStore extends CertStoreSpi {
return null;
}
URI uri = ((URIName) gn).getURI();
// Before performing any instantiation make sure that
// the URI passes any filtering rules. This processing should
// only occur if the com.sun.security.enableAIAcaIssuers is true
// and the "any" rule has not been specified.
if (Builder.USE_AIA && !CA_ISS_ALLOW_ANY) {
URI normAIAUri = uri.normalize();
AllowedScheme scheme = AllowedScheme.nameOf(normAIAUri.getScheme());
if (scheme == null) {
if (debug != null) {
debug.println("allowedAIALocations: No matching ruleset " +
"for scheme " + normAIAUri.getScheme());
}
return null;
}
// Go through each of the filter rules and see if any will
// make a positive match against the caIssuer URI. If nothing
// matches then we won't instantiate a URICertStore.
if (CA_ISS_URI_FILTERS.stream().noneMatch(rule ->
scheme.ruleMatcher.matchRule(rule, normAIAUri))) {
if (debug != null) {
debug.println("allowedAIALocations: Warning - " +
"The caIssuer URI " + normAIAUri +
" in the AuthorityInfoAccess extension is denied " +
"access. Use the com.sun.security.allowedAIALocations" +
" security/system property to allow access.");
}
return null;
}
}
try {
return URICertStore.getInstance(new URICertStoreParameters(uri));
} catch (Exception ex) {
@ -270,7 +469,7 @@ class URICertStore extends CertStoreSpi {
@Override
@SuppressWarnings("unchecked")
public synchronized Collection<X509Certificate> engineGetCertificates
(CertSelector selector) throws CertStoreException {
(CertSelector selector) throws CertStoreException {
if (ldap) {
// caching mechanism, see the class description for more info.
@ -462,4 +661,159 @@ class URICertStore extends CertStoreSpi {
super(spi, p, type, params);
}
}
/**
* URIRuleMatcher - abstract base class for the rule sets used for
* various URI schemes.
*/
static abstract class URIRuleMatcher {
protected final int wellKnownPort;
protected URIRuleMatcher(int port) {
wellKnownPort = port;
}
/**
* Attempt to match the scheme, host and port between a filter
* rule URI and a URI coming from an AIA extension.
*
* @param filterRule the filter rule to match against
* @param caIssuer the AIA URI being compared
* @return true if the scheme, host and port numbers match, false if
* any of the components do not match. If a port number is omitted in
* either the filter rule or AIA URI, the well-known port for that
* scheme is used in the comparison.
*/
boolean schemeHostPortCheck(URI filterRule, URI caIssuer) {
if (!filterRule.getScheme().equalsIgnoreCase(
caIssuer.getScheme())) {
return false;
} else if (!filterRule.getHost().equalsIgnoreCase(
caIssuer.getHost())) {
return false;
} else {
try {
// Check for port matching, taking into consideration
// default ports
int fPort = (filterRule.getPort() == -1) ? wellKnownPort :
filterRule.getPort();
int caiPort = (caIssuer.getPort() == -1) ? wellKnownPort :
caIssuer.getPort();
if (fPort != caiPort) {
return false;
}
} catch (IllegalArgumentException iae) {
return false;
}
}
return true;
}
/**
* Attempt to match an AIA URI against a specific filter rule. The
* specific rules to apply are implementation dependent.
*
* @param filterRule the filter rule to match against
* @param caIssuer the AIA URI being compared
* @return true if all matching rules pass, false if any fail.
*/
abstract boolean matchRule(URI filterRule, URI caIssuer);
}
static class HttpFtpRuleMatcher extends URIRuleMatcher {
static final HttpFtpRuleMatcher HTTP = new HttpFtpRuleMatcher(80);
static final HttpFtpRuleMatcher HTTPS = new HttpFtpRuleMatcher(443);
static final HttpFtpRuleMatcher FTP = new HttpFtpRuleMatcher(21);
private HttpFtpRuleMatcher(int port) {
super(port);
}
@Override
boolean matchRule(URI filterRule, URI caIssuer) {
// Check for scheme/host/port matching
if (!schemeHostPortCheck(filterRule, caIssuer)) {
return false;
}
// Check the path component to make sure the filter is at
// least a root of the AIA caIssuer URI's path. It must be
// a case-sensitive match for all platforms.
if (!isRootOf(filterRule, caIssuer)) {
if (debug != null) {
debug.println("allowedAIALocations: Match failed: " +
"AIA URI is not within the rule's path hierarchy.");
}
return false;
}
return true;
}
/**
* Performs a hierarchical containment check, ensuring that the
* base URI's path is a root component of the candidate path. The
* path comparison is case-sensitive. If the base path ends in a
* slash (/) then all candidate paths that begin with the base
* path are allowed. If it does not end in a slash, then it is
* assumed that the leaf node in the base path is a file component
* and both paths must match exactly.
*
* @param base the URI that contains the root path
* @param candidate the URI that contains the path being evaluated
* @return true if {@code candidate} is a child path of {@code base},
* false otherwise.
*/
private static boolean isRootOf(URI base, URI candidate) {
// Note: The URIs have already been normalized at this point and
// HTTP URIs cannot have null paths. If it's an empty path
// then consider the path to be "/".
String basePath = Optional.of(base.getPath()).
filter(p -> !p.isEmpty()).orElse("/");
String candPath = Optional.of(candidate.getPath()).
filter(p -> !p.isEmpty()).orElse("/");
return (basePath.endsWith("/")) ? candPath.startsWith(basePath) :
candPath.equals(basePath);
}
}
static class LdapRuleMatcher extends URIRuleMatcher {
static final LdapRuleMatcher LDAP = new LdapRuleMatcher(389);
static final LdapRuleMatcher LDAPS = new LdapRuleMatcher(636);
private LdapRuleMatcher(int port) {
super(port);
}
@Override
boolean matchRule(URI filterRule, URI caIssuer) {
// Check for scheme/host/port matching
if (!schemeHostPortCheck(filterRule, caIssuer)) {
return false;
}
// Obtain the base DN component and compare
try {
X500Principal filterBaseDn = new X500Principal(
filterRule.getPath().replaceFirst("^/+", ""));
X500Principal caIssBaseDn = new X500Principal(
caIssuer.getPath().replaceFirst("^/+", ""));
if (!filterBaseDn.equals(caIssBaseDn)) {
if (debug != null) {
debug.println("allowedAIALocations: Match failed: " +
"Base DN mismatch (" + filterBaseDn + " vs " +
caIssBaseDn + ")");
}
return false;
}
} catch (IllegalArgumentException iae) {
if (debug != null) {
debug.println("allowedAIALocations: Match failed on DN: " +
iae);
}
return false;
}
return true;
}
}
}

View File

@ -1655,3 +1655,48 @@ jdk.tls.alpnCharset=ISO_8859_1
# withEncryption method.
#
jdk.epkcs8.defaultAlgorithm=PBEWithHmacSHA256AndAES_128
#
# X.509 AuthorityInfoAccess caIssuer URI Filtering
#
# This property defines a whitespace-separated list of filters that
# are applied to URIs found in the authorityInfoAccess extension in
# X.509 certificates. Any caIssuers URIs in X.509 certificates are only
# followed when the com.sun.security.enableAIAcaIssuers System property is
# enabled and the filter allows the URI. By default this property imposes a
# deny-all ruleset. This property may be overridden by a System property
# of the same name.
#
# The filters must take the form of absolute, hierarchical URIs as defined by
# the java.net.URI class. Additionally, only the following protocols are
# allowed as filters: http, https, ldap and ftp.
# See RFC 5280, section 4.2.2.1 for details about the types of URIs allowed for
# the extension and their specific requirements.
# The filter matching rules are applied to each CA issuer URI as follows:
# 1. The scheme must match (case-insensitive).
# 2. A hostname or address must be specified in the filter URI. It must match
# the host or address in the caIssuers URI (case-insensitive). No name
# resolution is performed on hostnames to match IP addresses.
# 3. The port number must match. For filter and caIssuer URIs, when a port
# number is omitted, the well-known port for that scheme will be used in the
# comparison.
# 4. For hierarchical filesystem schemes (e.g. http[s], ftp):
# a. The normalized path portion of the filter URI is matched in a
# case-sensitive manner. If the final component of the path does not end
# in a slash (/), it is considered to be a file path component and must
# be an exact match of the caIssuer's URI file path component. If the
# final filter component ends in a slash, then it must either match or be
# a prefix of the caIssuer's URI path component (e.g. a filter path of
# /ab/cd/ will match a caIssuer path of /ab/cd/, /ab/cd/ef and
# /ab/cd/ef/ghi).
# b. Query strings will be ignored in filter rules and caIssuer URIs.
# c. Fragments will be ignored in filter rules and caIssuer URIs.
# 5. For ldap URIs:
# a. The base DN must be an exact match (case-insensitive).
# b. Any query string in the rule, if specified, is ignored.
# 6. A single value "any" (case-insensitive) will create an allow-all rule.
#
# As an example, here is a valid filter policy consisting of two rules:
# com.sun.security.allowedAIALocations=http://some.company.com/cacert \
# ldap://ldap.company.com/dc=company,dc=com?caCertificate;binary
com.sun.security.allowedAIALocations=

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2025, 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
@ -34,7 +34,10 @@ import java.awt.peer.DesktopPeer;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.annotation.Native;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
/**
@ -44,6 +47,12 @@ import java.net.URI;
*/
public final class CDesktopPeer implements DesktopPeer {
@Native private static final int OPEN = 0;
@Native private static final int BROWSE = 1;
@Native private static final int EDIT = 2;
@Native private static final int PRINT = 3;
@Native private static final int MAIL = 4;
@Override
public boolean isSupported(Action action) {
return true;
@ -51,27 +60,27 @@ public final class CDesktopPeer implements DesktopPeer {
@Override
public void open(File file) throws IOException {
this.lsOpenFile(file, false);
this.lsOpenFile(file, OPEN);
}
@Override
public void edit(File file) throws IOException {
this.lsOpenFile(file, false);
this.lsOpenFile(file, EDIT);
}
@Override
public void print(File file) throws IOException {
this.lsOpenFile(file, true);
this.lsOpenFile(file, PRINT);
}
@Override
public void mail(URI uri) throws IOException {
this.lsOpen(uri);
this.lsOpen(uri, MAIL);
}
@Override
public void browse(URI uri) throws IOException {
this.lsOpen(uri);
this.lsOpen(uri, BROWSE);
}
@Override
@ -162,24 +171,44 @@ public final class CDesktopPeer implements DesktopPeer {
}
}
private void lsOpen(URI uri) throws IOException {
int status = _lsOpenURI(uri.toString());
private void lsOpen(URI uri, int action) throws IOException {
int status = _lsOpenURI(uri.toString(), action);
if (status != 0 /* noErr */) {
throw new IOException("Failed to mail or browse " + uri + ". Error code: " + status);
String actionString = (action == MAIL) ? "mail" : "browse";
throw new IOException("Failed to " + actionString + " " + uri
+ ". Error code: " + status);
}
}
private void lsOpenFile(File file, boolean print) throws IOException {
int status = _lsOpenFile(file.getCanonicalPath(), print);
private void lsOpenFile(File file, int action) throws IOException {
int status = -1;
Path tmpFile = null;
String tmpTxtPath = null;
try {
if (action == EDIT) {
tmpFile = Files.createTempFile("TmpFile", ".txt");
tmpTxtPath = tmpFile.toAbsolutePath().toString();
}
status = _lsOpenFile(file.getCanonicalPath(), action, tmpTxtPath);
} catch (Exception e) {
throw new IOException("Failed to create tmp file: ", e);
} finally {
if (tmpFile != null) {
Files.deleteIfExists(tmpFile);
}
}
if (status != 0 /* noErr */) {
throw new IOException("Failed to open, edit or print " + file + ". Error code: " + status);
String actionString = (action == OPEN) ? "open"
: (action == EDIT) ? "edit" : "print";
throw new IOException("Failed to " + actionString + " " + file
+ ". Error code: " + status);
}
}
private static native int _lsOpenURI(String uri);
private static native int _lsOpenURI(String uri, int action);
private static native int _lsOpenFile(String path, boolean print);
private static native int _lsOpenFile(String path, int action, String tmpTxtPath);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2025, 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
@ -27,27 +27,60 @@
#import "JNIUtilities.h"
#import <CoreFoundation/CoreFoundation.h>
#import <ApplicationServices/ApplicationServices.h>
#import "sun_lwawt_macosx_CDesktopPeer.h"
/*
* Class: sun_lwawt_macosx_CDesktopPeer
* Method: _lsOpenURI
* Signature: (Ljava/lang/String;)I;
* Signature: (Ljava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_CDesktopPeer__1lsOpenURI
(JNIEnv *env, jclass clz, jstring uri)
(JNIEnv *env, jclass clz, jstring uri, jint action)
{
OSStatus status = noErr;
__block OSStatus status = noErr;
JNI_COCOA_ENTER(env);
// I would love to use NSWorkspace here, but it's not thread safe. Why? I don't know.
// So we use LaunchServices directly.
NSURL *urlToOpen = [NSURL URLWithString:JavaStringToNSString(env, uri)];
NSURL *appURI = nil;
NSURL *url = [NSURL URLWithString:JavaStringToNSString(env, uri)];
if (action == sun_lwawt_macosx_CDesktopPeer_BROWSE) {
// To get the defaultBrowser
NSURL *httpsURL = [NSURL URLWithString:@"https://"];
NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
appURI = [workspace URLForApplicationToOpenURL:httpsURL];
} else if (action == sun_lwawt_macosx_CDesktopPeer_MAIL) {
// To get the default mailer
NSURL *mailtoURL = [NSURL URLWithString:@"mailto://"];
NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
appURI = [workspace URLForApplicationToOpenURL:mailtoURL];
}
LSLaunchFlags flags = kLSLaunchDefaults;
if (appURI == nil) {
return -1;
}
LSApplicationParameters params = {0, flags, NULL, NULL, NULL, NULL, NULL};
status = LSOpenURLsWithRole((CFArrayRef)[NSArray arrayWithObject:url], kLSRolesAll, NULL, &params, NULL, 0);
// Prepare NSOpenConfig object
NSArray<NSURL *> *urls = @[urlToOpen];
NSWorkspaceOpenConfiguration *configuration = [NSWorkspaceOpenConfiguration configuration];
configuration.activates = YES; // To bring app to foreground
configuration.promptsUserIfNeeded = YES; // To allow macOS desktop prompts
// dispatch semaphores used to wait for the completion handler to update and return status
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(NSEC_PER_SEC)); // 1 second timeout
// Asynchronous call to openURL
[[NSWorkspace sharedWorkspace] openURLs:urls
withApplicationAtURL:appURI
configuration:configuration
completionHandler:^(NSRunningApplication *app, NSError *error) {
if (error) {
status = (OSStatus) error.code;
}
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, timeout);
JNI_COCOA_EXIT(env);
return status;
@ -56,32 +89,73 @@ JNI_COCOA_EXIT(env);
/*
* Class: sun_lwawt_macosx_CDesktopPeer
* Method: _lsOpenFile
* Signature: (Ljava/lang/String;Z)I;
* Signature: (Ljava/lang/String;I;Ljava/lang/String;)I;
*/
JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_CDesktopPeer__1lsOpenFile
(JNIEnv *env, jclass clz, jstring jpath, jboolean print)
(JNIEnv *env, jclass clz, jstring jpath, jint action, jstring jtmpTxtPath)
{
OSStatus status = noErr;
__block OSStatus status = noErr;
JNI_COCOA_ENTER(env);
// I would love to use NSWorkspace here, but it's not thread safe. Why? I don't know.
// So we use LaunchServices directly.
NSString *path = NormalizedPathNSStringFromJavaString(env, jpath);
NSURL *url = [NSURL fileURLWithPath:(NSString *)path];
NSURL *urlToOpen = [NSURL fileURLWithPath:(NSString *)path];
// This byzantine workaround is necessary, or else directories won't open in Finder
url = (NSURL *)CFURLCreateWithFileSystemPath(NULL, (CFStringRef)[url path], kCFURLPOSIXPathStyle, false);
urlToOpen = (NSURL *)CFURLCreateWithFileSystemPath(NULL, (CFStringRef)[urlToOpen path],
kCFURLPOSIXPathStyle, false);
LSLaunchFlags flags = kLSLaunchDefaults;
if (print) flags |= kLSLaunchAndPrint;
NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
NSURL *appURI = [workspace URLForApplicationToOpenURL:urlToOpen];
NSURL *defaultTerminalApp = [workspace URLForApplicationToOpenURL:[NSURL URLWithString:@"file:///bin/sh"]];
LSApplicationParameters params = {0, flags, NULL, NULL, NULL, NULL, NULL};
status = LSOpenURLsWithRole((CFArrayRef)[NSArray arrayWithObject:url], kLSRolesAll, NULL, &params, NULL, 0);
[url release];
// Prepare NSOpenConfig object
NSArray<NSURL *> *urls = @[urlToOpen];
NSWorkspaceOpenConfiguration *configuration = [NSWorkspaceOpenConfiguration configuration];
configuration.activates = YES; // To bring app to foreground
configuration.promptsUserIfNeeded = YES; // To allow macOS desktop prompts
// pre-checks for open/print/edit before calling openURLs API
if (action == sun_lwawt_macosx_CDesktopPeer_OPEN
|| action == sun_lwawt_macosx_CDesktopPeer_PRINT) {
if (appURI == nil
|| [[urlToOpen absoluteString] containsString:[appURI absoluteString]]
|| [[defaultTerminalApp absoluteString] containsString:[appURI absoluteString]]) {
return -1;
}
// Additionally set forPrinting=TRUE for print
if (action == sun_lwawt_macosx_CDesktopPeer_PRINT) {
configuration.forPrinting = YES;
}
} else if (action == sun_lwawt_macosx_CDesktopPeer_EDIT) {
if (appURI == nil
|| [[urlToOpen absoluteString] containsString:[appURI absoluteString]]) {
return -1;
}
// for EDIT: if (defaultApp = TerminalApp) then set appURI = DefaultTextEditor
if ([[defaultTerminalApp absoluteString] containsString:[appURI absoluteString]]) {
NSString *path = NormalizedPathNSStringFromJavaString(env, jtmpTxtPath);
NSURL *tempFilePath = [NSURL fileURLWithPath:(NSString *)path];
appURI = [workspace URLForApplicationToOpenURL:tempFilePath];
}
}
// dispatch semaphores used to wait for the completion handler to update and return status
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(NSEC_PER_SEC)); // 1 second timeout
// Asynchronous call - openURLs:withApplicationAtURL
[[NSWorkspace sharedWorkspace] openURLs:urls
withApplicationAtURL:appURI
configuration:configuration
completionHandler:^(NSRunningApplication *app, NSError *error) {
if (error) {
status = (OSStatus) error.code;
}
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, timeout);
JNI_COCOA_EXIT(env);
return status;
}

View File

@ -452,78 +452,54 @@ public class BasicOptionPaneUI extends OptionPaneUI {
} else if ((nl = s.indexOf('\n')) >= 0) {
nll = 1;
}
if (s.contains("<html>")) {
/* line break in html text is done by <br> tag
* and not by /n so it's incorrect to address newline
* same as non-html text.
* Text between <html> </html> tags are extracted
* and rendered as JLabel text
*/
int index1 = s.indexOf("<html>");
int index2 = s.indexOf("</html>");
String str = "";
if (index2 >= 0) {
str = s.substring(index2 + "</html>".length());
s = s.substring(index1, index2 + + "</html>".length());
if (nl >= 0) {
// break up newlines
if (nl == 0) {
JPanel breakPanel = new JPanel() {
public Dimension getPreferredSize() {
Font f = getFont();
if (f != null) {
return new Dimension(1, f.getSize() + 2);
}
return new Dimension(0, 0);
}
};
breakPanel.setName("OptionPane.break");
addMessageComponents(container, cons, breakPanel, maxll,
true);
} else {
addMessageComponents(container, cons, s.substring(0, nl),
maxll, false);
}
JLabel label;
label = new JLabel(s, JLabel.LEADING);
// Prevent recursion of more than
// 200 successive newlines in a message
// and indicate message is truncated via ellipsis
if (recursionCount++ > 200) {
recursionCount = 0;
addMessageComponents(container, cons, new String("..."),
maxll, false);
return;
}
addMessageComponents(container, cons, s.substring(nl + nll), maxll,
false);
} else if (len > maxll) {
Container c = Box.createVerticalBox();
c.setName("OptionPane.verticalBox");
burstStringInto(c, s, maxll);
addMessageComponents(container, cons, c, maxll, true);
} else {
JLabel label = new JLabel();
if (Boolean.TRUE.equals(
this.optionPane.getClientProperty("html.disable"))) {
optionPane.getClientProperty("html.disable"))) {
label.putClientProperty("html.disable", true);
}
label.setText(s);
label.setName("OptionPane.label");
configureMessageLabel(label);
addMessageComponents(container, cons, label, maxll, true);
if (!str.isEmpty()) {
addMessageComponents(container, cons, str, maxll, false);
}
} else {
if (nl >= 0) {
// break up newlines
if (nl == 0) {
JPanel breakPanel = new JPanel() {
public Dimension getPreferredSize() {
Font f = getFont();
if (f != null) {
return new Dimension(1, f.getSize() + 2);
}
return new Dimension(0, 0);
}
};
breakPanel.setName("OptionPane.break");
addMessageComponents(container, cons, breakPanel, maxll,
true);
} else {
addMessageComponents(container, cons, s.substring(0, nl),
maxll, false);
}
// Prevent recursion of more than
// 200 successive newlines in a message
// and indicate message is truncated via ellipsis
if (recursionCount++ > 200) {
recursionCount = 0;
addMessageComponents(container, cons, new String("..."),
maxll, false);
return;
}
addMessageComponents(container, cons, s.substring(nl + nll), maxll,
false);
} else if (len > maxll) {
Container c = Box.createVerticalBox();
c.setName("OptionPane.verticalBox");
burstStringInto(c, s, maxll);
addMessageComponents(container, cons, c, maxll, true);
} else {
JLabel label;
label = new JLabel(s, JLabel.LEADING);
label.setName("OptionPane.label");
configureMessageLabel(label);
addMessageComponents(container, cons, label, maxll, true);
}
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2025, 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
@ -1898,14 +1898,16 @@ public final class SunGraphics2D
protected void validateCompClip() {
int origClipState = clipState;
if (usrClip == null) {
final Shape clip = usrClip;
if (clip == null) {
clipState = CLIP_DEVICE;
clipRegion = devClip;
} else if (usrClip instanceof Rectangle2D) {
} else if (clip instanceof Rectangle2D rect2d) {
clipState = CLIP_RECTANGULAR;
clipRegion = devClip.getIntersection((Rectangle2D) usrClip);
clipRegion = devClip.getIntersection(rect2d);
} else {
PathIterator cpi = usrClip.getPathIterator(null);
PathIterator cpi = clip.getPathIterator(null);
int[] box = new int[4];
ShapeSpanIterator sr = LoopPipe.getFillSSI(this);
try {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2025, 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
@ -27,6 +27,8 @@ package sun.java2d.pipe;
import java.awt.Rectangle;
import java.awt.Shape;
import sun.java2d.InvalidPipeException;
import sun.java2d.SunGraphics2D;
/**
@ -67,7 +69,9 @@ public class SpanClipRenderer implements CompositePipe
public Object startSequence(SunGraphics2D sg, Shape s, Rectangle devR,
int[] abox) {
RegionIterator ri = sg.clipRegion.getIterator();
if (ri.region.isRectangular()) {
throw new InvalidPipeException("Invalid clip data");
}
return new SCRcontext(ri, outpipe.startSequence(sg, s, devR, abox));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025, 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
@ -76,6 +76,7 @@
#include "mlib_ImageCheck.h"
#include "mlib_SysMath.h"
#include "mlib_ImageConv.h"
#include "safe_math.h"
/***************************************************************/
static void mlib_ImageConvMxNMulAdd_F32(mlib_f32 *dst,
@ -272,6 +273,9 @@ mlib_status mlib_convMxNext_f32(mlib_image *dst,
mlib_s32 nch = mlib_ImageGetChannels(dst);
mlib_s32 i, j, j1, k;
if (!SAFE_TO_MULT(3, wid_e) || !SAFE_TO_ADD(3 * wid_e, m)) {
return MLIB_FAILURE;
}
if (3 * wid_e + m > 1024) {
dsa = mlib_malloc((3 * wid_e + m) * sizeof(mlib_d64));
@ -629,6 +633,9 @@ mlib_status mlib_convMxNext_d64(mlib_image *dst,
mlib_s32 nch = mlib_ImageGetChannels(dst);
mlib_s32 i, j, j1, k;
if (!SAFE_TO_MULT(3, wid_e) || !SAFE_TO_ADD(3 * wid_e, m)) {
return MLIB_FAILURE;
}
if (3 * wid_e + m > 1024) {
dsa = mlib_malloc((3 * wid_e + m) * sizeof(mlib_d64));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025, 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
@ -82,6 +82,7 @@
#include "mlib_image.h"
#include "mlib_ImageConv.h"
#include "safe_math.h"
/***************************************************************/
static void mlib_ImageConvMxNMulAdd_S32(mlib_d64 *dst,
@ -229,6 +230,9 @@ mlib_status mlib_convMxNext_s32(mlib_image *dst,
/* internal buffer */
if (!SAFE_TO_MULT(3, wid_e) || !SAFE_TO_ADD(3 * wid_e, m)) {
return MLIB_FAILURE;
}
if (3 * wid_e + m > 1024) {
dsa = mlib_malloc((3 * wid_e + m) * sizeof(mlib_d64));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025, 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
@ -33,6 +33,7 @@
#include "mlib_image.h"
#include "mlib_ImageConv.h"
#include "mlib_c_ImageConv.h"
#include "safe_math.h"
/*
* This define switches between functions of different data types
@ -260,8 +261,14 @@ static mlib_status mlib_ImageConv1xN_ext(mlib_image *dst,
if (max_hsize > hgt) max_hsize = hgt;
shgt = hgt + (n - 1);
if (!SAFE_TO_ADD(max_hsize, (n - 1))) {
return MLIB_FAILURE;
}
smax_hsize = max_hsize + (n - 1);
if (!SAFE_TO_ADD(smax_hsize, 1) || !SAFE_TO_MULT(2, (smax_hsize + 1))) {
return MLIB_FAILURE;
}
bsize = 2 * (smax_hsize + 1);
if (bsize > BUFF_SIZE) {
@ -509,8 +516,16 @@ mlib_status CONV_FUNC_MxN
FREE_AND_RETURN_STATUS;
}
if (!SAFE_TO_ADD(wid, (m - 1))) {
status = MLIB_FAILURE;
FREE_AND_RETURN_STATUS;
}
swid = wid + (m - 1);
if (!SAFE_TO_MULT((n + 3), swid)) {
status = MLIB_FAILURE;
FREE_AND_RETURN_STATUS;
}
bsize = (n + 3)*swid;
if ((bsize > BUFF_SIZE) || (n > MAX_N)) {
@ -919,8 +934,14 @@ mlib_status CONV_FUNC_MxN_I
chan1 = nchannel;
chan2 = chan1 + chan1;
if (!SAFE_TO_ADD(wid, (m - 1))) {
return MLIB_FAILURE;
}
swid = wid + (m - 1);
if (!SAFE_TO_MULT((n + 2), swid)) {
return MLIB_FAILURE;
}
bsize = (n + 2)*swid;
if ((bsize > BUFF_SIZE) || (n > MAX_N)) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2025, 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
@ -32,6 +32,7 @@
#include "mlib_image.h"
#include "mlib_c_ImageConv.h"
#include "safe_math.h"
/*
This define switches between functions of different data types
@ -466,6 +467,10 @@ mlib_status CONV_FUNC(MxN)(mlib_image *dst,
FREE_AND_RETURN_STATUS;
}
if (!SAFE_TO_MULT((n + 3), wid)) {
status = MLIB_FAILURE;
FREE_AND_RETURN_STATUS;
}
bsize = (n + 3)*wid;
if ((bsize > BUFF_SIZE) || (n > MAX_N)) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2025, 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
@ -33,6 +33,7 @@
#include "mlib_image.h"
#include "mlib_ImageConv.h"
#include "safe_math.h"
/***************************************************************/
#define CACHE_SIZE (64*1024)
@ -335,6 +336,10 @@ mlib_status CONV_FUNC(MxN)(mlib_image *dst,
FREE_AND_RETURN_STATUS;
}
if (!SAFE_TO_MULT((n + 2), wid)) {
status = MLIB_FAILURE;
FREE_AND_RETURN_STATUS;
}
bsize = (n + 2)*wid;
if ((bsize > BUFF_SIZE) || (n > MAX_N)) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025, 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
@ -33,6 +33,7 @@
#include "mlib_image.h"
#include "mlib_ImageConv.h"
#include "mlib_c_ImageConv.h"
#include "safe_math.h"
/*
* This define switches between functions of different data types
@ -245,8 +246,14 @@ static mlib_status mlib_ImageConv1xN_ext(mlib_image *dst,
if (max_hsize > hgt) max_hsize = hgt;
shgt = hgt + (n - 1);
if (!SAFE_TO_ADD(max_hsize, (n - 1))) {
return MLIB_FAILURE;
}
smax_hsize = max_hsize + (n - 1);
if (!SAFE_TO_ADD(smax_hsize, 1) || !SAFE_TO_MULT(2, (smax_hsize + 1))) {
return MLIB_FAILURE;
}
bsize = 2 * (smax_hsize + 1);
if (bsize > BUFF_SIZE) {
@ -494,8 +501,16 @@ mlib_status CONV_FUNC_MxN
FREE_AND_RETURN_STATUS;
}
if (!SAFE_TO_ADD(wid, (m - 1))) {
status = MLIB_FAILURE;
FREE_AND_RETURN_STATUS;
}
swid = wid + (m - 1);
if (!SAFE_TO_MULT((n + 3), swid)) {
status = MLIB_FAILURE;
FREE_AND_RETURN_STATUS;
}
bsize = (n + 3)*swid;
if ((bsize > BUFF_SIZE) || (n > MAX_N)) {
@ -904,8 +919,14 @@ mlib_status CONV_FUNC_MxN_I
chan1 = nchannel;
chan2 = chan1 + chan1;
if (!SAFE_TO_ADD(wid, (m - 1))) {
return MLIB_FAILURE;
}
swid = wid + (m - 1);
if (!SAFE_TO_MULT((n + 2), swid)) {
return MLIB_FAILURE;
}
bsize = (n + 2)*swid;
if ((bsize > BUFF_SIZE) || (n > MAX_N)) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025, 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
@ -33,6 +33,7 @@
#include "mlib_image.h"
#include "mlib_ImageConv.h"
#include "mlib_c_ImageConv.h"
#include "safe_math.h"
/*
This define switches between functions of different data types
@ -467,6 +468,10 @@ mlib_status CONV_FUNC(MxN)(mlib_image *dst,
FREE_AND_RETURN_STATUS;
}
if (!SAFE_TO_MULT((n + 3), wid)) {
status = MLIB_FAILURE;
FREE_AND_RETURN_STATUS;
}
bsize = (n + 3)*wid;
if ((bsize > BUFF_SIZE) || (n > MAX_N)) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025, 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
@ -33,6 +33,7 @@
#include "mlib_image.h"
#include "mlib_ImageConv.h"
#include "mlib_c_ImageConv.h"
#include "safe_math.h"
/*
* This define switches between functions of different data types
@ -270,8 +271,14 @@ static mlib_status mlib_ImageConv1xN_ext(mlib_image *dst,
if (max_hsize > hgt) max_hsize = hgt;
shgt = hgt + (n - 1);
if (!SAFE_TO_ADD(max_hsize, (n - 1))) {
return MLIB_FAILURE;
}
smax_hsize = max_hsize + (n - 1);
if (!SAFE_TO_ADD(smax_hsize, 1) || !SAFE_TO_MULT(2, (smax_hsize + 1))) {
return MLIB_FAILURE;
}
bsize = 2 * (smax_hsize + 1);
if (bsize > BUFF_SIZE) {
@ -519,8 +526,16 @@ mlib_status CONV_FUNC_MxN
FREE_AND_RETURN_STATUS;
}
if (!SAFE_TO_ADD(wid, (m - 1))) {
status = MLIB_FAILURE;
FREE_AND_RETURN_STATUS;
}
swid = wid + (m - 1);
if (!SAFE_TO_MULT((n + 3), swid)) {
status = MLIB_FAILURE;
FREE_AND_RETURN_STATUS;
}
bsize = (n + 3)*swid;
if ((bsize > BUFF_SIZE) || (n > MAX_N)) {
@ -927,8 +942,14 @@ mlib_status CONV_FUNC_MxN_I
chan1 = nchannel;
chan2 = chan1 + chan1;
if (!SAFE_TO_ADD(wid, (m - 1))) {
return MLIB_FAILURE;
}
swid = wid + (m - 1);
if (!SAFE_TO_MULT((n + 2), swid)) {
return MLIB_FAILURE;
}
bsize = (n + 2)*swid;
if ((bsize > BUFF_SIZE) || (n > MAX_N)) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025, 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
@ -32,6 +32,7 @@
#include "mlib_image.h"
#include "mlib_c_ImageConv.h"
#include "safe_math.h"
/*
This define switches between functions of different data types
@ -466,6 +467,10 @@ mlib_status CONV_FUNC(MxN)(mlib_image *dst,
FREE_AND_RETURN_STATUS;
}
if (!SAFE_TO_MULT((n + 3), wid)) {
status = MLIB_FAILURE;
FREE_AND_RETURN_STATUS;
}
bsize = (n + 3)*wid;
if ((bsize > BUFF_SIZE) || (n > MAX_N)) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025, 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
@ -50,6 +50,7 @@
#include "mlib_image.h"
#include "mlib_ImageLookUp.h"
#include "safe_math.h"
/***************************************************************/
#define MAX_WIDTH 512
@ -302,6 +303,9 @@ mlib_status mlib_ImageLookUp_Bit_U8_2(const mlib_u8 *src,
mlib_u8 *buff = (mlib_u8*)buff_lcl, *buffs;
mlib_u32 val0, val1;
if (!SAFE_TO_MULT(xsize, 2)) {
return MLIB_FAILURE;
}
size = xsize * 2;
if (size > MAX_WIDTH) {
@ -440,6 +444,9 @@ mlib_status mlib_ImageLookUp_Bit_U8_3(const mlib_u8 *src,
mlib_u8 *buff = (mlib_u8*)buff_lcl, *buffs;
mlib_u32 l0, h0, v0, l1, h1, v1, l2, h2, v2;
if (!SAFE_TO_MULT(3, xsize)) {
return MLIB_FAILURE;
}
size = 3 * xsize;
if (size > MAX_WIDTH) {
@ -583,6 +590,9 @@ mlib_status mlib_ImageLookUp_Bit_U8_4(const mlib_u8 *src,
mlib_u8 *buff = (mlib_u8*)buff_lcl, *buffs;
mlib_u32 l, h;
if (!SAFE_TO_MULT(xsize, 4)) {
return MLIB_FAILURE;
}
size = xsize * 4;
if (size > MAX_WIDTH) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2025, 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
@ -101,6 +101,11 @@ mlib_status mlib_AffineEdges(mlib_affine_param *param,
return MLIB_FAILURE;
}
int intSize = sizeof(mlib_s32);
if (!SAFE_TO_MULT(dstHeight, intSize) ||
!SAFE_TO_ADD(dstHeight * intSize, 7)) {
return MLIB_FAILURE;
}
bsize0 = (dstHeight * sizeof(mlib_s32) + 7) & ~7;
if (lineAddr == NULL) {
@ -109,6 +114,10 @@ mlib_status mlib_AffineEdges(mlib_affine_param *param,
param->buff_malloc = NULL;
if (!SAFE_TO_MULT(4, bsize0) || !SAFE_TO_ADD(4 * bsize0, bsize1)) {
return MLIB_FAILURE;
}
if ((4 * bsize0 + bsize1) > buff_size) {
buff = param->buff_malloc = mlib_malloc(4 * bsize0 + bsize1);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2025, 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
@ -38,6 +38,9 @@ import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.event.EventListenerList;
import sun.awt.shell.ShellFolder;
@ -50,9 +53,11 @@ import sun.awt.shell.ShellFolder;
*/
final class WDesktopPeer implements DesktopPeer {
/* Constants for the operation verbs */
private static String ACTION_OPEN_VERB = "open";
private static String ACTION_EDIT_VERB = "edit";
private static String ACTION_PRINT_VERB = "print";
private static final String ACTION_OPEN_VERB = "open";
private static final String ACTION_EDIT_VERB = "edit";
private static final String ACTION_PRINT_VERB = "print";
private static final String ACTION_BROWSE_VERB = "browse";
private static final String ACTION_MAIL_VERB = "mail";
private static native void init();
@ -95,12 +100,12 @@ final class WDesktopPeer implements DesktopPeer {
@Override
public void mail(URI uri) throws IOException {
this.ShellExecute(uri, ACTION_OPEN_VERB);
this.ShellExecute(uri, ACTION_MAIL_VERB);
}
@Override
public void browse(URI uri) throws IOException {
this.ShellExecute(uri, ACTION_OPEN_VERB);
this.launchUriInBrowser(uri);
}
private void ShellExecute(File file, String verb) throws IOException {
@ -121,6 +126,42 @@ final class WDesktopPeer implements DesktopPeer {
}
}
private void launchUriInBrowser(URI uri) throws IOException {
String defaultBrowser = getDefaultBrowser();
if (defaultBrowser == null) {
throw new IOException("Failed to get default browser");
}
List<String> cmdLineTokens = getCmdLineTokens(uri, defaultBrowser);
try {
ProcessBuilder pb = new ProcessBuilder(cmdLineTokens);
pb.start();
} catch (Exception e) {
throw new IOException("Error launching Browser: ", e);
}
}
private static List<String> getCmdLineTokens(URI uri, String defaultBrowser) {
if (defaultBrowser.contains("%1")) {
defaultBrowser = defaultBrowser.replace("%1", uri.toString());
} else {
defaultBrowser = defaultBrowser + " " + uri.toString();
}
List<String> cmdLineTokens = new ArrayList<>();
int firstIndex = defaultBrowser.indexOf("\"");
int secondIndex = defaultBrowser.indexOf("\"", firstIndex + 1);
if (firstIndex == 0 && secondIndex != firstIndex) {
cmdLineTokens.add(defaultBrowser.substring(firstIndex, secondIndex + 1));
defaultBrowser = defaultBrowser.substring(secondIndex + 1).trim();
}
cmdLineTokens.addAll(Arrays.asList(defaultBrowser.split(" ")));
return cmdLineTokens;
}
private static native String getDefaultBrowser();
private static native String ShellExecute(String fileOrUri, String verb);
private static final EventListenerList listenerList = new EventListenerList();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2025, 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
@ -30,6 +30,12 @@
#include <float.h>
#include <shlobj.h>
#include "awt_Toolkit.h"
#include <Windows.h>
#include <shlwapi.h> // for AssocQueryStringW
#include <wchar.h>
#include <cwchar>
#include <string.h>
#include <winsafer.h> // for SaferiIsExecutableFileType
#define BUFFER_LIMIT MAX_PATH+1
@ -78,14 +84,23 @@ JNIEXPORT jstring JNICALL Java_sun_awt_windows_WDesktopPeer_ShellExecute
LPCWSTR fileOrUri_c = JNU_GetStringPlatformChars(env, fileOrUri_j, NULL);
CHECK_NULL_RETURN(fileOrUri_c, NULL);
LPCWSTR verb_c = JNU_GetStringPlatformChars(env, verb_j, NULL);
if (verb_c == NULL) {
JNU_ReleaseStringPlatformChars(env, fileOrUri_j, fileOrUri_c);
return NULL;
}
if (wcscmp(verb_c, L"open") == 0) {
BOOL isExecutable = SaferiIsExecutableFileType(fileOrUri_c, FALSE);
if (isExecutable) {
return env->NewStringUTF("Unsupported URI content");
}
}
// set action verb for mail() to open before calling ShellExecute
LPCWSTR actionVerb = wcscmp(verb_c, L"mail") == 0 ? L"open" : verb_c;
// 6457572: ShellExecute possibly changes FPU control word - saving it here
unsigned oldcontrol87 = _control87(0, 0);
HINSTANCE retval = ::ShellExecute(NULL, verb_c, fileOrUri_c, NULL, NULL,
HINSTANCE retval = ::ShellExecute(NULL, actionVerb, fileOrUri_c, NULL, NULL,
SW_SHOWNORMAL);
DWORD error = ::GetLastError();
_control87(oldcontrol87, 0xffffffff);
@ -113,10 +128,38 @@ JNIEXPORT jstring JNICALL Java_sun_awt_windows_WDesktopPeer_ShellExecute
return errmsg;
}
}
return NULL;
}
/*
* Class: sun_awt_windows_WDesktopPeer
* Method: getDefaultBrowser
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_sun_awt_windows_WDesktopPeer_getDefaultBrowser
(JNIEnv *env, jclass cls)
{
LPCWSTR fileExtension = L"https";
WCHAR defaultBrowser_c [MAX_PATH];
DWORD cchBuffer = MAX_PATH;
// Use AssocQueryString to get the default browser
HRESULT hr = AssocQueryStringW(
ASSOCF_NONE, // No special flags
ASSOCSTR_COMMAND, // Request the command string
fileExtension, // File extension
NULL, // pszExtra (optional)
defaultBrowser_c, // Output buffer - result
&cchBuffer // Size of the output buffer
);
if (FAILED(hr)) {
return NULL;
}
return JNU_NewStringPlatform(env, defaultBrowser_c);
}
/*
* Class: sun_awt_windows_WDesktopPeer
* Method: moveToTrash

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025, 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
@ -31,6 +31,7 @@ import java.net.Socket;
import java.rmi.server.RMIClientSocketFactory;
import java.util.StringTokenizer;
import javax.net.SocketFactory;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
@ -119,6 +120,16 @@ public class SslRMIClientSocketFactory
//
final SSLSocket sslSocket = (SSLSocket)
sslSocketFactory.createSocket(host, port);
if (Boolean.parseBoolean(
System.getProperty("jdk.rmi.ssl.client.enableEndpointIdentification", "true"))) {
SSLParameters params = sslSocket.getSSLParameters();
if (params == null) {
params = new SSLParameters();
}
params.setEndpointIdentificationAlgorithm("HTTPS");
sslSocket.setSSLParameters(params);
}
// Set the SSLSocket Enabled Cipher Suites
//
final String enabledCipherSuites =

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
@ -184,9 +184,12 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt
if (directIn != 0) {
inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
} else {
} else if (jIn != NULL) {
inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
// may happen if out of memory
if (inBufP == NULL) { return 0; }
} else {
inBufP = NULL;
}
if (directOut != 0) {
@ -194,7 +197,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt
} else {
outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
if (outBufP == NULL) {
if (directIn == 0) {
if (directIn == 0 && inBufP != NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
}
return 0;
@ -208,7 +211,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt
(CK_BYTE_PTR)(outBufP + jOutOfs),
&ckEncryptedLen);
if (directIn == 0) {
if (directIn == 0 && inBufP != NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
}
if (directOut == 0) {
@ -251,9 +254,12 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptUpdate
if (directIn != 0) {
inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
} else {
} else if (jIn != NULL) {
inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
// may happen if out of memory
if (inBufP == NULL) { return 0; }
} else {
inBufP = NULL;
}
if (directOut != 0) {
@ -261,7 +267,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptUpdate
} else {
outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
if (outBufP == NULL) {
if (directIn == 0) {
if (directIn == 0 && inBufP != NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
}
return 0;
@ -275,7 +281,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptUpdate
(CK_BYTE_PTR)(outBufP + jOutOfs),
&ckEncryptedPartLen);
if (directIn == 0) {
if (directIn == 0 && inBufP != NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
}
if (directOut == 0) {
@ -462,9 +468,12 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt
if (directIn != 0) {
inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
} else {
} else if (jIn != NULL) {
inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
// may happen if out of memory
if (inBufP == NULL) { return 0; }
} else {
inBufP = NULL;
}
if (directOut != 0) {
@ -472,7 +481,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt
} else {
outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
if (outBufP == NULL) {
if (directIn == 0) {
if (directIn == 0 && inBufP != NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
}
return 0;
@ -485,7 +494,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt
(CK_BYTE_PTR)(outBufP + jOutOfs),
&ckOutLen);
if (directIn == 0) {
if (directIn == 0 && inBufP != NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
}
if (directOut == 0) {
@ -528,9 +537,12 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptUpdate
if (directIn != 0) {
inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
} else {
} else if (jIn != NULL) {
inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
// may happen if out of memory
if (inBufP == NULL) { return 0; }
} else {
inBufP = NULL;
}
if (directOut != 0) {
@ -538,7 +550,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptUpdate
} else {
outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
if (outBufP == NULL) {
if (directIn == 0) {
if (directIn == 0 && inBufP != NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
}
return 0;
@ -551,7 +563,7 @@ Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptUpdate
(CK_BYTE_PTR)(outBufP + jOutOfs),
&ckDecryptedPartLen);
if (directIn == 0) {
if (directIn == 0 && inBufP != NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
}
if (directOut == 0) {

View File

@ -36,6 +36,7 @@ import java.util.Set;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import sun.net.httpserver.UnmodifiableHeaders;
import sun.net.httpserver.Utils;
/**
* HTTP request and response headers are represented by this class which
@ -216,8 +217,13 @@ public class Headers implements Map<String, List<String>> {
@Override
public List<String> put(String key, List<String> value) {
// checkHeader is called in this class to fail fast
// It also must be called in sendResponseHeaders because
// Headers instances internal state can be modified
// external to these methods.
Utils.checkHeader(key, false);
for (String v : value)
checkValue(v);
Utils.checkHeader(v, true);
return map.put(normalize(key), value);
}
@ -229,7 +235,8 @@ public class Headers implements Map<String, List<String>> {
* @param value the value to add to the header
*/
public void add(String key, String value) {
checkValue(value);
Utils.checkHeader(key, false);
Utils.checkHeader(value, true);
String k = normalize(key);
List<String> l = map.get(k);
if (l == null) {
@ -239,30 +246,6 @@ public class Headers implements Map<String, List<String>> {
l.add(value);
}
private static void checkValue(String value) {
int len = value.length();
for (int i=0; i<len; i++) {
char c = value.charAt(i);
if (c == '\r') {
// is allowed if it is followed by \n and a whitespace char
if (i >= len - 2) {
throw new IllegalArgumentException("Illegal CR found in header");
}
char c1 = value.charAt(i+1);
char c2 = value.charAt(i+2);
if (c1 != '\n') {
throw new IllegalArgumentException("Illegal char found after CR in header");
}
if (c2 != ' ' && c2 != '\t') {
throw new IllegalArgumentException("No whitespace found after CRLF in header");
}
i+=2;
} else if (c == '\n') {
throw new IllegalArgumentException("Illegal LF found in header");
}
}
}
/**
* Sets the given {@code value} as the sole header value for the given
* {@code key}. If the mapping does not already exist, then it is created.
@ -304,7 +287,7 @@ public class Headers implements Map<String, List<String>> {
public void replaceAll(BiFunction<? super String, ? super List<String>, ? extends List<String>> function) {
var f = function.andThen(values -> {
Objects.requireNonNull(values);
values.forEach(Headers::checkValue);
values.forEach(value -> Utils.checkHeader(value, true));
return values;
});
Map.super.replaceAll(f);

View File

@ -207,6 +207,8 @@ class ExchangeImpl {
return uos_orig;
}
private static final byte[] CRLF = new byte[] {0x0D, 0x0A};
public void sendResponseHeaders(int rCode, long contentLen)
throws IOException
{
@ -215,10 +217,11 @@ class ExchangeImpl {
throw new IOException("headers already sent");
}
this.rcode = rCode;
String statusLine = "HTTP/1.1 " + rCode + Code.msg(rCode) + "\r\n";
String statusLine = "HTTP/1.1 " + rCode + Code.msg(rCode);
ByteArrayOutputStream tmpout = new ByteArrayOutputStream();
PlaceholderOutputStream o = getPlaceholderResponseBody();
tmpout.write(bytes(statusLine, 0), 0, statusLine.length());
tmpout.write(bytes(statusLine, false, 0), 0, statusLine.length());
tmpout.write(CRLF);
boolean noContentToSend = false; // assume there is content
boolean noContentLengthHeader = false; // must not send Content-length is set
rspHdrs.set("Date", FORMATTER.format(Instant.now()));
@ -305,11 +308,11 @@ class ExchangeImpl {
List<String> values = entry.getValue();
for (String val : values) {
int i = key.length();
buf = bytes(key, 2);
buf = bytes(key, true, 2);
buf[i++] = ':';
buf[i++] = ' ';
os.write(buf, 0, i);
buf = bytes(val, 2);
buf = bytes(val, false, 2);
i = val.length();
buf[i++] = '\r';
buf[i++] = '\n';
@ -327,8 +330,14 @@ class ExchangeImpl {
* Make sure that at least "extra" bytes are free at end
* of rspbuf. Reallocate rspbuf if not big enough.
* caller must check return value to see if rspbuf moved
*
* Header values are supposed to be limited to 7-bit ASCII
* but 8-bit has to be allowed (for ISO_8859_1). For efficiency
* we just down cast 16 bit Java chars to byte. We don't allow
* any character that can't be encoded in 8 bits.
*/
private byte[] bytes(String s, int extra) {
private byte[] bytes(String s, boolean isKey, int extra) throws IOException {
Utils.checkHeader(s, !isKey);
int slen = s.length();
if (slen+extra > rspbuf.length) {
int diff = slen + extra - rspbuf.length;

View File

@ -88,4 +88,37 @@ public class Utils {
}
return true;
}
/* Throw IAE if illegal character found. isValue is true if String is
* a value. Otherwise it is header name
*/
public static void checkHeader(String str, boolean isValue) {
int len = str.length();
for (int i=0; i<len; i++) {
char c = str.charAt(i);
if (c == '\r') {
if (!isValue) {
throw new IllegalArgumentException("Illegal CR found in header");
}
// is allowed if it is followed by \n and a whitespace char
if (i >= len - 2) {
throw new IllegalArgumentException("Illegal CR found in header");
}
char c1 = str.charAt(i+1);
char c2 = str.charAt(i+2);
if (c1 != '\n') {
throw new IllegalArgumentException("Illegal char found after CR in header");
}
if (c2 != ' ' && c2 != '\t') {
throw new IllegalArgumentException("No whitespace found after CRLF in header");
}
i+=2;
} else if (c == '\n') {
throw new IllegalArgumentException("Illegal LF found in header");
} else if (c > 255) {
throw new IllegalArgumentException("Illegal character found in header");
}
}
}
}

View File

@ -40,10 +40,27 @@ import jtreg.SkippedException;
public class BrowseTest extends JPanel {
static final String INSTRUCTIONS = """
This test could launch default file manager to open user's home
directory, and default web browser to show the URL of java vendor.
After test execution close the native file manager and web browser
Set your default browser as per the test platform.
macOS - Safari
windows - MS Edge
linux - Firefox
This test checks 2 cases:
1) Directory URI:
On macOS and windows, verify that a browser window opens and
EITHER the browser OR native file manager shows the user's
home directory.
On Linux verify that the user's home directory is shown by the
default file manager.
2) Web URI:
Verify that the Web URI (URL of java vendor) opens in the browser.
After test execution close the native file manager and any web browser
windows if they were launched by test.
Also check output for any unexpected EXCEPTIONS,
if you see any failure messages press Fail otherwise press Pass.
""";
@ -53,7 +70,7 @@ public class BrowseTest extends JPanel {
URI dirURI = new File(System.getProperty("user.home")).toURI();
URI webURI = URI.create(System.getProperty("java.vendor.url", "http://www.java.com"));
boolean failed = false;
PassFailJFrame.log("Testing 1st case: Directory URI ...");
try {
PassFailJFrame.log("Try to browse " + dirURI + " ...");
desktop.browse(dirURI);
@ -62,6 +79,7 @@ public class BrowseTest extends JPanel {
PassFailJFrame.log("EXCEPTION: " + e.getMessage());
}
PassFailJFrame.log("Testing 2nd case: Web URI ...");
try {
PassFailJFrame.log("Try to browse " + webURI + " ...");
desktop.browse(webURI);

View File

@ -48,7 +48,7 @@ public class EditAndPrintTest extends JPanel {
This test tries to edit and print a directory, which will expectedly raise IOException.
Then this test would edit and print a .txt file, which should be successful.
After test execution close the editor if it was launched by test.
If you see any EXCEPTION messages in the output press FAIL.
If you see any EXCEPTION messages in case of .txt file in the output press FAIL.
""";
static Desktop desktop;

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2025, 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.
*
* 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.
*/
/*
* @test
* @bug 8365058
* @summary Check basic correctness of de-serialization
* @run junit SerializationTest
*/
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class SerializationTest {
// Ensure basic serialization round trip correctness
@ParameterizedTest
@MethodSource
void roundTripTest(CopyOnWriteArraySet<?> expected) {
var bytes = ser(expected);
var actual = deSer(bytes);
assertEquals(CopyOnWriteArraySet.class, actual.getClass());
assertEquals(expected, actual);
}
private static Stream<CopyOnWriteArraySet<?>> roundTripTest() {
return Stream.of(
new CopyOnWriteArraySet<>(),
new CopyOnWriteArraySet<>(List.of(1, 2, 3)),
new CopyOnWriteArraySet<>(Set.of("Foo", "Bar", "Baz"))
);
}
private static byte[] ser(Object obj) {
return assertDoesNotThrow(() -> {
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(byteArrayOutputStream)) {
oos.writeObject(obj);
return byteArrayOutputStream.toByteArray();
}
}, "Unexpected error during serialization");
}
private static Object deSer(byte[] bytes) {
return assertDoesNotThrow(() -> {
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream)) {
return ois.readObject();
}
}, "Unexpected error during de-serialization");
}
}

View File

@ -402,6 +402,8 @@ public class SecurityTest {
opts.add(JDKToolFinder.getJDKTool("java"));
opts.addAll(Arrays.asList(jdk.test.lib.Utils.getTestJavaOpts()));
opts.add("-Djdk.rmi.ssl.client.enableEndpointIdentification=false");
// We need to forward some properties to the client side
opts.add("-Dtest.src=" + System.getProperty("test.src"));

View File

@ -137,6 +137,7 @@ public class SSLSocketParametersTest extends SSLContextTemplate {
}
public static void main(String[] args) throws Exception {
System.setProperty("jdk.rmi.ssl.client.enableEndpointIdentification", "false");
SSLSocketParametersTest test = new SSLSocketParametersTest();
test.runTest(Integer.parseInt(args[0]));
}

View File

@ -1,68 +0,0 @@
/*
* 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.
*
* 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.
*/
/* @test
* @bug 5074006
* @key headful
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
* @summary Swing JOptionPane shows <html> tag as a string after newline
* @run main/manual TestJOptionHTMLTag
*/
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
public class TestJOptionHTMLTag {
static String instructions
= """
INSTRUCTIONS:
A dialog will be shown.
If it does not contain </html> string, press Pass else press Fail.
""";
static PassFailJFrame passFailJFrame;
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(() -> {
try {
String message = "<html>" + "This is a test\n" + "</html>";
JOptionPane optionPane = new JOptionPane();
optionPane.setMessage(message);
optionPane.setMessageType(JOptionPane.INFORMATION_MESSAGE);
JDialog dialog = new JDialog();
dialog.setContentPane(optionPane);
dialog.pack();
dialog.setVisible(true);
passFailJFrame = new PassFailJFrame(instructions);
PassFailJFrame.addTestWindow(dialog);
PassFailJFrame.positionTestWindow(dialog, PassFailJFrame.Position.HORIZONTAL);
} catch (Exception e) {
e.printStackTrace();
}
});
passFailJFrame.awaitAndCheck();
}
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2015, Red Hat Inc
* Copyright (c) 2025, 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
@ -205,6 +206,7 @@ public class JMXInterfaceBindingTest {
// This is needed for testing on loopback
args.add("-Djava.rmi.server.hostname=" + address);
if (useSSL) {
args.add("-Djdk.rmi.ssl.client.enableEndpointIdentification=false");
args.add("-Dcom.sun.management.jmxremote.registry.ssl=true");
args.add("-Djavax.net.ssl.keyStore=" + KEYSTORE_LOC);
args.add("-Djavax.net.ssl.trustStore=" + TRUSTSTORE_LOC);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025, 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
@ -169,6 +169,7 @@ public class RmiBootstrapTest extends RmiTestBase {
final List<Path> credentialFiles = prepareTestFiles(args[0]);
Security.setProperty("jdk.tls.disabledAlgorithms", "");
System.setProperty("jdk.rmi.ssl.client.enableEndpointIdentification", "false");
try {
MAX_GET_FREE_PORT_TRIES = Integer.parseInt(System.getProperty("test.getfreeport.max.tries", "10"));

View File

@ -179,6 +179,7 @@ public class RmiRegistrySslTest {
initTestEnvironment();
List<String> command = new ArrayList<>();
command.add("-Djdk.rmi.ssl.client.enableEndpointIdentification=false");
command.add("-Dtest.src=" + TEST_SRC);
command.add("-Dtest.rmi.port=" + port);
command.addAll(Arrays.asList(args));

View File

@ -47,6 +47,7 @@ import com.sun.net.httpserver.*;
import java.io.*;
import java.math.BigInteger;
import java.net.InetSocketAddress;
import java.security.Security;
import java.security.cert.*;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
@ -69,6 +70,7 @@ public class AIACertTimeout {
private static X509Certificate eeCert;
public static void main(String[] args) throws Exception {
Security.setProperty("com.sun.security.allowedAIALocations", "any");
int servTimeoutMsec = (args != null && args.length >= 1) ?
Integer.parseInt(args[0]) : -1;
boolean expectedPass = args != null && args.length >= 2 &&

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, 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
@ -38,6 +38,7 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.security.Security;
import java.security.cert.CertPath;
import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorException;
@ -47,7 +48,6 @@ import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -67,25 +67,27 @@ public class ExtensionsWithLDAP {
* Not After : Jan 17 18:03:59 2043 GMT
* Subject: CN=Root
*/
private static final String CA_CERT = ""
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIC8TCCAdmgAwIBAgIJAJsSNtj5wdqqMA0GCSqGSIb3DQEBDQUAMA8xDTALBgNV\n"
+ "BAMMBFJvb3QwHhcNMTUwOTAxMTgwMzU5WhcNNDMwMTE3MTgwMzU5WjAPMQ0wCwYD\n"
+ "VQQDDARSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvj892vPm\n"
+ "bB++x9QqqyBveP+ZqQ2B1stV7vh5JmDnOTevkZUOcemp3SXu/esNLSbpL+fARYXH\n"
+ "V5ubnrfip6RbvcxPfVIIDJrRTLIIsU6W7M6/LJLbLkEVGy4ZV4IHkOw9W2O92rcv\n"
+ "BkoqhzZnOTGR6uT3rRcKx4RevEKBKhZO+OPPf//lnckOybmYL7t7yQrajzHro76b\n"
+ "QTXYjAUq/DKhglXfC7vF/JzlAvG2IunGmIfjGcnuDo/9X3Bxef/q5TxCS35fvb7t\n"
+ "svC+g2QhTcBkQh4uNW2jSjlTIVp1uErCfP5aCjLaez5mqmb1hxPIlcvsNR23HwU6\n"
+ "bQO7z7NBo9Do6QIDAQABo1AwTjAdBgNVHQ4EFgQUmLZNOBBkqdYoElyxklPYHmAb\n"
+ "QXIwHwYDVR0jBBgwFoAUmLZNOBBkqdYoElyxklPYHmAbQXIwDAYDVR0TBAUwAwEB\n"
+ "/zANBgkqhkiG9w0BAQ0FAAOCAQEAYV4fOhDi5q7+XNXCxO8Eil2frR9jqdP4LaQp\n"
+ "3L0evW0gvPX68s2WmkPWzIu4TJcpdGFQqxyQFSXuKBXjthyiln77QItGTHWeafES\n"
+ "q5ESrKdSaJZq1bTIrrReCIP74f+fY/F4Tnb3dCqzaljXfzpdbeRsIW6gF71xcOUQ\n"
+ "nnPEjGVPLUegN+Wn/jQpeLxxIB7FmNXncdRUfMfZ43xVSKuMCy1UUYqJqTa/pXZj\n"
+ "jCMeRPThRjRqHlJ69jStfWUQATbLyj9KN09rUaJxzmUSt61UqJi7sjcGySaCjAJc\n"
+ "IcCdVmX/DmRLsdv8W36O3MgrvpT1zR3kaAlv2d8HppnBqcL3xg==\n"
+ "-----END CERTIFICATE-----";
private static final String CA_CERT =
"""
-----BEGIN CERTIFICATE-----
MIIC8TCCAdmgAwIBAgIJAJsSNtj5wdqqMA0GCSqGSIb3DQEBDQUAMA8xDTALBgNV
BAMMBFJvb3QwHhcNMTUwOTAxMTgwMzU5WhcNNDMwMTE3MTgwMzU5WjAPMQ0wCwYD
VQQDDARSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvj892vPm
bB++x9QqqyBveP+ZqQ2B1stV7vh5JmDnOTevkZUOcemp3SXu/esNLSbpL+fARYXH
V5ubnrfip6RbvcxPfVIIDJrRTLIIsU6W7M6/LJLbLkEVGy4ZV4IHkOw9W2O92rcv
BkoqhzZnOTGR6uT3rRcKx4RevEKBKhZO+OPPf//lnckOybmYL7t7yQrajzHro76b
QTXYjAUq/DKhglXfC7vF/JzlAvG2IunGmIfjGcnuDo/9X3Bxef/q5TxCS35fvb7t
svC+g2QhTcBkQh4uNW2jSjlTIVp1uErCfP5aCjLaez5mqmb1hxPIlcvsNR23HwU6
bQO7z7NBo9Do6QIDAQABo1AwTjAdBgNVHQ4EFgQUmLZNOBBkqdYoElyxklPYHmAb
QXIwHwYDVR0jBBgwFoAUmLZNOBBkqdYoElyxklPYHmAbQXIwDAYDVR0TBAUwAwEB
/zANBgkqhkiG9w0BAQ0FAAOCAQEAYV4fOhDi5q7+XNXCxO8Eil2frR9jqdP4LaQp
3L0evW0gvPX68s2WmkPWzIu4TJcpdGFQqxyQFSXuKBXjthyiln77QItGTHWeafES
q5ESrKdSaJZq1bTIrrReCIP74f+fY/F4Tnb3dCqzaljXfzpdbeRsIW6gF71xcOUQ
nnPEjGVPLUegN+Wn/jQpeLxxIB7FmNXncdRUfMfZ43xVSKuMCy1UUYqJqTa/pXZj
jCMeRPThRjRqHlJ69jStfWUQATbLyj9KN09rUaJxzmUSt61UqJi7sjcGySaCjAJc
IcCdVmX/DmRLsdv8W36O3MgrvpT1zR3kaAlv2d8HppnBqcL3xg==
-----END CERTIFICATE-----
""";
/*
* Certificate:
@ -106,39 +108,41 @@ public class ExtensionsWithLDAP {
* Authority Information Access:
* CA Issuers - URI:ldap://ldap.host.for.aia/dc=Root?cACertificate
*/
private static final String EE_CERT = ""
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIDHTCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQ0FADAPMQ0wCwYDVQQDDARSb290\n"
+ "MB4XDTE1MDkwMTE4MDM1OVoXDTQzMDExNzE4MDM1OVowDTELMAkGA1UEAwwCRUUw\n"
+ "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpyz97liuWPDYcLH9TX8Bi\n"
+ "T78olCmAfmevvch6ncXUVuCzbdaKuKXwn4EVbDszsVJLoK5zdtP+X3iDhutj+IgK\n"
+ "mLhuczF3M9VIcWr+JJUyTH4+3h/RT8cjCDZOmk9iXkb5ifruVsLqzb9g+Vp140Oz\n"
+ "7leikne7KmclHvTfvFd0WDI7Gb9vo4f5rT717BXJ/n+M6pNk8DLpLiEu6eziYvXR\n"
+ "v5x+t5Go3x0eCXdaxEQUf2j876Wfr2qHRJK7lDfFe1DDsMg/KpKGiILYZ+g2qtVM\n"
+ "ZSxtp5BZEtfB5qV/IE5kWO+mCIAGpXSZIdbERR6pZUq8GLEe1T9e+sO6H24w2F19\n"
+ "AgMBAAGjgYUwgYIwNAYDVR0fBC0wKzApoCegJYYjbGRhcDovL2xkYXAuaG9zdC5m\n"
+ "b3IuY3JsZHAvbWFpbi5jcmwwSgYIKwYBBQUHAQEEPjA8MDoGCCsGAQUFBzAChi5s\n"
+ "ZGFwOi8vbGRhcC5ob3N0LmZvci5haWEvZGM9Um9vdD9jQUNlcnRpZmljYXRlMA0G\n"
+ "CSqGSIb3DQEBDQUAA4IBAQBWDfZHpuUx0yn5d3+BuztFqoks1MkGdk+USlH0TB1/\n"
+ "gWWBd+4S4PCKlpSur0gj2rMW4fP5HQfNlHci8JV8/bG4KuKRAXW56dg1818Hl3pc\n"
+ "iIrUSRn8uUjH3p9qb+Rb/u3mmVQRyJjN2t/zceNsO8/+Dd808OB9aEwGs8lMT0nn\n"
+ "ZYaaAqYz1GIY/Ecyx1vfEZEQ1ljo6i/r70C3igbypBUShxSiGsleiVTLOGNA+MN1\n"
+ "/a/Qh0bkaQyTGqK3bwvzzMeQVqWu2EWTBD/PmND5ExkpRICdv8LBVXfLnpoBr4lL\n"
+ "hnxn9+e0Ah+t8dS5EKfn44w5bI5PCu2bqxs6RCTxNjcY\n"
+ "-----END CERTIFICATE-----";
private static final String EE_CERT =
"""
-----BEGIN CERTIFICATE-----
MIIDHTCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQ0FADAPMQ0wCwYDVQQDDARSb290
MB4XDTE1MDkwMTE4MDM1OVoXDTQzMDExNzE4MDM1OVowDTELMAkGA1UEAwwCRUUw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpyz97liuWPDYcLH9TX8Bi
T78olCmAfmevvch6ncXUVuCzbdaKuKXwn4EVbDszsVJLoK5zdtP+X3iDhutj+IgK
mLhuczF3M9VIcWr+JJUyTH4+3h/RT8cjCDZOmk9iXkb5ifruVsLqzb9g+Vp140Oz
7leikne7KmclHvTfvFd0WDI7Gb9vo4f5rT717BXJ/n+M6pNk8DLpLiEu6eziYvXR
v5x+t5Go3x0eCXdaxEQUf2j876Wfr2qHRJK7lDfFe1DDsMg/KpKGiILYZ+g2qtVM
ZSxtp5BZEtfB5qV/IE5kWO+mCIAGpXSZIdbERR6pZUq8GLEe1T9e+sO6H24w2F19
AgMBAAGjgYUwgYIwNAYDVR0fBC0wKzApoCegJYYjbGRhcDovL2xkYXAuaG9zdC5m
b3IuY3JsZHAvbWFpbi5jcmwwSgYIKwYBBQUHAQEEPjA8MDoGCCsGAQUFBzAChi5s
ZGFwOi8vbGRhcC5ob3N0LmZvci5haWEvZGM9Um9vdD9jQUNlcnRpZmljYXRlMA0G
CSqGSIb3DQEBDQUAA4IBAQBWDfZHpuUx0yn5d3+BuztFqoks1MkGdk+USlH0TB1/
gWWBd+4S4PCKlpSur0gj2rMW4fP5HQfNlHci8JV8/bG4KuKRAXW56dg1818Hl3pc
iIrUSRn8uUjH3p9qb+Rb/u3mmVQRyJjN2t/zceNsO8/+Dd808OB9aEwGs8lMT0nn
ZYaaAqYz1GIY/Ecyx1vfEZEQ1ljo6i/r70C3igbypBUShxSiGsleiVTLOGNA+MN1
/a/Qh0bkaQyTGqK3bwvzzMeQVqWu2EWTBD/PmND5ExkpRICdv8LBVXfLnpoBr4lL
hnxn9+e0Ah+t8dS5EKfn44w5bI5PCu2bqxs6RCTxNjcY
-----END CERTIFICATE-----""";
public static void main(String[] args) throws Exception {
String extension = args[0];
String targetHost = args[1];
Security.setProperty("com.sun.security.allowedAIALocations",
"ldap://" + targetHost + "/dc=Root");
X509Certificate trustedCert = loadCertificate(CA_CERT);
X509Certificate eeCert = loadCertificate(EE_CERT);
Set<TrustAnchor> trustedCertsSet = new HashSet<>();
trustedCertsSet.add(new TrustAnchor(trustedCert, null));
CertPath cp = (CertPath) CertificateFactory.getInstance("X509")
.generateCertPath(Arrays.asList(eeCert));
CertPath cp = CertificateFactory.getInstance("X509")
.generateCertPath(List.of(eeCert));
// CertPath validator should try to parse CRLDP and AIA extensions,
// and load CRLs/certs which they point to.
@ -151,7 +155,7 @@ public class ExtensionsWithLDAP {
= (InetSocketAddress) socket.getRemoteSocketAddress();
hosts.add(remoteAddress.getHostName());
};
try (SocksProxy proxy = SocksProxy.startProxy(socketConsumer)) {
try (SocksProxy _ = SocksProxy.startProxy(socketConsumer)) {
CertPathValidator.getInstance("PKIX").validate(cp,
new PKIXParameters(trustedCertsSet));
throw new RuntimeException("CertPathValidatorException not thrown");