mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
Merge
Reviewed-by: kcr, prr, smarks
This commit is contained in:
commit
e25a5a4821
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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=
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
@ -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, ¶ms, 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, ¶ms, 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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
|
||||
@ -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));
|
||||
|
||||
|
||||
@ -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));
|
||||
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 =
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
@ -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"));
|
||||
|
||||
|
||||
@ -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]));
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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"));
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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 &&
|
||||
|
||||
@ -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");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user