From 269efa35c4bd226ee71695d04ebcbb6c28cf43d2 Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Fri, 31 Jan 2025 16:41:16 +0000 Subject: [PATCH 01/22] initial impl --- .../share/classes/java/net/HostPortrange.java | 13 +- .../classes/java/net/Inet4AddressImpl.java | 6 +- .../share/classes/java/net/Inet6Address.java | 7 +- .../share/classes/java/net/InetAddress.java | 58 ++- .../classes/java/net/NetworkInterface.java | 7 +- .../share/classes/java/net/Proxy.java | 12 +- .../classes/java/net/SocketPermission.java | 14 +- .../classes/java/net/SocksSocketImpl.java | 8 +- src/java.base/share/classes/java/net/URI.java | 15 +- src/java.base/share/classes/java/net/URL.java | 7 +- .../classes/java/net/URLStreamHandler.java | 17 +- .../classes/jdk/internal/util/Exceptions.java | 365 ++++++++++++++++++ src/java.base/share/classes/module-info.java | 2 + .../classes/sun/net/util/IPAddressUtil.java | 8 +- .../sun/net/util/SocketExceptions.java | 96 ----- .../share/classes/sun/net/www/ParseUtil.java | 8 +- .../sun/net/www/protocol/jar/Handler.java | 21 +- .../net/www/protocol/jar/JarFileFactory.java | 8 +- .../www/protocol/jar/JarURLConnection.java | 19 +- .../sun/net/www/protocol/jmod/Handler.java | 8 +- .../sun/nio/ch/DatagramSocketAdaptor.java | 7 +- .../classes/sun/nio/ch/NioSocketImpl.java | 6 +- .../classes/sun/nio/ch/SocketChannelImpl.java | 10 +- .../share/conf/security/java.security | 9 +- src/java.base/share/native/libnet/net_util.c | 29 +- src/java.base/share/native/libnet/net_util.h | 10 +- .../ch/UnixAsynchronousSocketChannelImpl.java | 9 +- .../sun/nio/fs/UnixUserPrincipals.java | 12 +- .../unix/native/libnet/net_util_md.c | 18 +- .../WindowsAsynchronousSocketChannelImpl.java | 12 +- .../sun/nio/fs/WindowsSecurityDescriptor.java | 8 +- .../sun/nio/fs/WindowsUserPrincipals.java | 13 +- .../windows/native/libnet/Inet4AddressImpl.c | 7 +- .../windows/native/libnet/Inet6AddressImpl.c | 4 +- .../net/http/HttpRequestBuilderImpl.java | 7 +- .../net/http/ResponseBodyHandlers.java | 11 +- .../net/http/websocket/OpeningHandshake.java | 10 +- .../httpserver/simpleserver/JWebServer.java | 13 +- .../simpleserver/CommandLineNegativeTest.java | 8 +- test/jdk/java/net/URI/Test.java | 3 +- 40 files changed, 672 insertions(+), 233 deletions(-) create mode 100644 src/java.base/share/classes/jdk/internal/util/Exceptions.java delete mode 100644 src/java.base/share/classes/sun/net/util/SocketExceptions.java diff --git a/src/java.base/share/classes/java/net/HostPortrange.java b/src/java.base/share/classes/java/net/HostPortrange.java index fd516b8d2d732..e232e3428ddd0 100644 --- a/src/java.base/share/classes/java/net/HostPortrange.java +++ b/src/java.base/share/classes/java/net/HostPortrange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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,9 @@ import java.util.Locale; import sun.net.util.IPAddressUtil; +import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.throwException; + /** * Parses a string containing a host/domain name and port range */ @@ -67,7 +70,7 @@ public int hashCode() { // Refer to RFC 2732 for more information. // first separate string into two fields: hoststr, portstr - String hoststr, portstr = null; + String hoststr = null, portstr = null; this.scheme = scheme; // check for IPv6 address @@ -77,7 +80,8 @@ public int hashCode() { if (rb != -1) { hoststr = str.substring(1, rb); } else { - throw new IllegalArgumentException("invalid IPv6 address: " + str); + throwException(IllegalArgumentException.class, "invalid IPv6 address%s", + filterHostName(str).prefixWith(": ")); } int sep = str.indexOf(':', rb + 1); if (sep != -1 && str.length() > sep) { @@ -156,7 +160,8 @@ public int hashCode() { try { portrange = parsePort(portstr); } catch (Exception e) { - throw new IllegalArgumentException("invalid port range: " + portstr); + throwException(IllegalArgumentException.class, "invalid port range%s", + filterHostName(portstr).prefixWith(": ")); } } diff --git a/src/java.base/share/classes/java/net/Inet4AddressImpl.java b/src/java.base/share/classes/java/net/Inet4AddressImpl.java index c7feaf4c195e6..d3d1a73bedbd5 100644 --- a/src/java.base/share/classes/java/net/Inet4AddressImpl.java +++ b/src/java.base/share/classes/java/net/Inet4AddressImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ import java.net.spi.InetAddressResolver.LookupPolicy; import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4; +import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.throwException; /* * Package private implementation of InetAddressImpl for IPv4. @@ -38,7 +40,7 @@ final class Inet4AddressImpl implements InetAddressImpl { public InetAddress[] lookupAllHostAddr(String hostname, LookupPolicy lookupPolicy) throws UnknownHostException { if ((lookupPolicy.characteristics() & IPV4) == 0) { - throw new UnknownHostException(hostname); + throwException(UnknownHostException.class, filterHostName(hostname)); } return lookupAllHostAddr(hostname); } diff --git a/src/java.base/share/classes/java/net/Inet6Address.java b/src/java.base/share/classes/java/net/Inet6Address.java index 06a74ca3adc27..632e094b0a211 100644 --- a/src/java.base/share/classes/java/net/Inet6Address.java +++ b/src/java.base/share/classes/java/net/Inet6Address.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, 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 @@ -35,6 +35,8 @@ import java.util.Enumeration; import java.util.Arrays; import java.util.Objects; +import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.throwException; /** * This class represents an Internet Protocol version 6 (IPv6) address. @@ -581,7 +583,8 @@ static InetAddress parseAddressString(String addressLiteral, boolean removeSqBra if (addrBytes.length == Inet4Address.INADDRSZ) { if (numericZone != -1 || ifname != null) { // IPv4-mapped address must not contain zone-id - throw new UnknownHostException(addressLiteral + ": invalid IPv4-mapped address"); + throwException(UnknownHostException.class, "%sinvalid IPv4-mapped address", + filterHostName(addressLiteral).suffixWith(": ")); } return new Inet4Address(null, addrBytes); } diff --git a/src/java.base/share/classes/java/net/InetAddress.java b/src/java.base/share/classes/java/net/InetAddress.java index 4bceebdcd0ede..b5f654f51cdda 100644 --- a/src/java.base/share/classes/java/net/InetAddress.java +++ b/src/java.base/share/classes/java/net/InetAddress.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -54,6 +54,7 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Stream; +import jdk.internal.util.Exceptions; import jdk.internal.access.JavaNetInetAddressAccess; import jdk.internal.access.SharedSecrets; import jdk.internal.misc.Blocker; @@ -68,6 +69,9 @@ import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4_FIRST; import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6; import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6_FIRST; +import static jdk.internal.util.Exceptions.exception; +import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.throwException; /** * This class represents an Internet Protocol (IP) address. @@ -382,6 +386,7 @@ public byte[] addressBytes(Inet6Address inet6Address) { } } ); + Exceptions.setup(); // needed for native exceptions init(); } @@ -902,7 +907,7 @@ private static class CachedLookup implements Addresses, Comparable @Override public InetAddress[] get() throws UnknownHostException { if (inetAddresses == null) { - throw new UnknownHostException(host); + throwException(UnknownHostException.class, filterHostName(host)); } return inetAddresses; } @@ -1095,7 +1100,11 @@ public InetAddress[] get() throws UnknownHostException { } } if (inetAddresses == null || inetAddresses.length == 0) { - throw ex == null ? new UnknownHostException(host) : ex; + if (ex == null) { + throwException(UnknownHostException.class, filterHostName(host)); + } else { + throw ex; + } } return inetAddresses; } @@ -1203,16 +1212,19 @@ public String lookupByAddress(byte[] addr) throws UnknownHostException { } } } catch (IOException e) { - throw new UnknownHostException("Unable to resolve address " - + Arrays.toString(addr) + " as hosts file " + hostsFile - + " not found "); + throwException(UnknownHostException.class, + "Unable to resolve address %s as hosts file %s not found", + filterHostName(Arrays.toString(addr)), + filterHostName(hostsFile) + .replaceWith("from ${jdk.net.hosts.file} system property")); } if ((host == null) || (host.isEmpty()) || (host.equals(" "))) { - throw new UnknownHostException("Requested address " - + Arrays.toString(addr) - + " resolves to an invalid entry in hosts file " - + hostsFile); + throwException(UnknownHostException.class, + "Requested address %s resolves to an invalid entry in hosts file %s", + filterHostName(Arrays.toString(addr)), + filterHostName(hostsFile) + .replaceWith("from ${jdk.net.hosts.file} system property")); } return host; } @@ -1273,8 +1285,11 @@ public Stream lookupByName(String host, LookupPolicy lookupPolicy) } } } catch (IOException e) { - throw new UnknownHostException("Unable to resolve host " + host - + " as hosts file " + hostsFile + " not found "); + throwException(UnknownHostException.class, + "Unable to resolve host %s as hosts file %s not found", + filterHostName(host), filterHostName(hostsFile) + .replaceWith("from ${jdk.net.hosts.file} system property")); + } // Check if only IPv4 addresses are requested if (needIPv4 && !needIPv6) { @@ -1305,8 +1320,9 @@ public Stream lookupByName(String host, LookupPolicy lookupPolicy) private void checkResultsList(List addressesList, String hostName) throws UnknownHostException { if (addressesList.isEmpty()) { - throw new UnknownHostException("Unable to resolve host " + hostName - + " in hosts file " + hostsFile); + throwException(UnknownHostException.class, "Unable to resolve host %s in hosts file %s", + filterHostName(hostName), filterHostName(hostsFile) + .replaceWith("from ${jdk.net.hosts.file} system property")); } } @@ -1543,7 +1559,8 @@ public static InetAddress[] getAllByName(String host) // Here we check the address string for ambiguity only inetAddress = Inet4Address.parseAddressString(host, false); } catch (IllegalArgumentException iae) { - var uhe = new UnknownHostException(host); + UnknownHostException uhe = exception(UnknownHostException.class, + filterHostName(host)); uhe.initCause(iae); throw uhe; } @@ -1570,7 +1587,8 @@ public static InetAddress[] getAllByName(String host) private static UnknownHostException invalidIPv6LiteralException(String host, boolean wrapInBrackets) { String hostString = wrapInBrackets ? "[" + host + "]" : host; - return new UnknownHostException(hostString + ": invalid IPv6 address literal"); + return exception(UnknownHostException.class, "%sinvalid IPv6 address literal", + filterHostName(hostString).suffixWith(": ")); } /** @@ -1708,7 +1726,8 @@ static InetAddress[] getAddressesFromNameService(String host) InetAddress[] result = addresses == null ? null : addresses.toArray(InetAddress[]::new); if (result == null || result.length == 0) { - throw ex == null ? new UnknownHostException(host) : ex; + throw ex == null ? exception(UnknownHostException.class, filterHostName(host)) + : ex; } return result; } @@ -1780,9 +1799,8 @@ public static InetAddress getLocalHost() throws UnknownHostException { localAddr = getAllByName0(local, false)[0]; } catch (UnknownHostException uhe) { // Rethrow with a more informative error message. - UnknownHostException uhe2 = - new UnknownHostException(local + ": " + - uhe.getMessage()); + UnknownHostException uhe2 = exception(UnknownHostException.class, + filterHostName(local).suffixWith(": ") + uhe.getMessage()); uhe2.initCause(uhe); throw uhe2; } diff --git a/src/java.base/share/classes/java/net/NetworkInterface.java b/src/java.base/share/classes/java/net/NetworkInterface.java index 29a07d9b76dfe..e4024d7c97e8f 100644 --- a/src/java.base/share/classes/java/net/NetworkInterface.java +++ b/src/java.base/share/classes/java/net/NetworkInterface.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, 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 @@ -34,6 +34,8 @@ import java.util.Spliterators; import java.util.stream.Stream; import java.util.stream.StreamSupport; +import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.throwException; /** * This class represents a Network Interface. @@ -323,7 +325,8 @@ public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketE + addr.holder.family); } } else { - throw new IllegalArgumentException("invalid address type: " + addr); + throwException(IllegalArgumentException.class, "invalid address type%s", + filterHostName(addr.toString()).prefixWith(": ")); } return getByInetAddress0(addr); } diff --git a/src/java.base/share/classes/java/net/Proxy.java b/src/java.base/share/classes/java/net/Proxy.java index db434238558fe..849520fea5854 100644 --- a/src/java.base/share/classes/java/net/Proxy.java +++ b/src/java.base/share/classes/java/net/Proxy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -26,6 +26,8 @@ package java.net; import java.util.Objects; +import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.throwException; /** * This class represents a proxy setting, typically a type (http, socks) and @@ -93,8 +95,12 @@ private Proxy() { * incompatible */ public Proxy(Type type, SocketAddress sa) { - if ((type == Type.DIRECT) || !(sa instanceof InetSocketAddress)) - throw new IllegalArgumentException("type " + type + " is not compatible with address " + sa); + if ((type == Type.DIRECT) || !(sa instanceof InetSocketAddress)) { + throwException(IllegalArgumentException.class, + "type " + type + " is not compatible with address %s", + filterHostName(sa.toString()) + .replaceWith("type " + sa.getClass().toString())); + } this.type = type; this.sa = sa; } diff --git a/src/java.base/share/classes/java/net/SocketPermission.java b/src/java.base/share/classes/java/net/SocketPermission.java index e3a85bbf856f8..4880e17b0842f 100644 --- a/src/java.base/share/classes/java/net/SocketPermission.java +++ b/src/java.base/share/classes/java/net/SocketPermission.java @@ -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 @@ -46,6 +46,8 @@ import sun.security.util.SecurityConstants; import sun.security.util.Debug; +import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.throwException; /** * This class represents access to a network via sockets. @@ -392,8 +394,8 @@ private void init(String host, int mask) { if (rb != -1) { host = host.substring(start, rb); } else { - throw new - IllegalArgumentException("invalid host/port: "+host); + throwException(IllegalArgumentException.class, + "invalid host/port%s", filterHostName(host).prefixWith(": ")); } sep = hostport.indexOf(':', rb+1); } else { @@ -410,8 +412,8 @@ private void init(String host, int mask) { try { portrange = parsePort(port); } catch (Exception e) { - throw new - IllegalArgumentException("invalid port range: "+port); + throwException(IllegalArgumentException.class, + "invalid port range%s", filterHostName(port).prefixWith(": ")); } } else { portrange = new int[] { PORT_MIN, PORT_MAX }; @@ -784,7 +786,7 @@ void getIP() throw uhe; } catch (IndexOutOfBoundsException iobe) { invalid = true; - throw new UnknownHostException(getName()); + throwException(UnknownHostException.class, filterHostName(getName())); } } diff --git a/src/java.base/share/classes/java/net/SocksSocketImpl.java b/src/java.base/share/classes/java/net/SocksSocketImpl.java index 54ff612be0263..baad82c75a734 100644 --- a/src/java.base/share/classes/java/net/SocksSocketImpl.java +++ b/src/java.base/share/classes/java/net/SocksSocketImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, 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 @@ -37,6 +37,8 @@ import sun.net.www.ParseUtil; import static sun.net.util.IPAddressUtil.isIPv6LiteralAddress; +import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.throwException; /** * SOCKS (V4 & V5) TCP socket implementation (RFC 1928). @@ -330,7 +332,7 @@ protected void connect(SocketAddress endpoint, int timeout) throws IOException { // SOCKS Protocol version 4 doesn't know how to deal with // DOMAIN type of addresses (unresolved addresses here) if (epoint.isUnresolved()) - throw new UnknownHostException(epoint.toString()); + throwException(UnknownHostException.class, filterHostName(epoint.toString())); connectV4(in, out, epoint, deadlineMillis); return; } @@ -349,7 +351,7 @@ protected void connect(SocketAddress endpoint, int timeout) throws IOException { // SOCKS Protocol version 4 doesn't know how to deal with // DOMAIN type of addresses (unresolved addresses here) if (epoint.isUnresolved()) - throw new UnknownHostException(epoint.toString()); + throwException(UnknownHostException.class, filterHostName(epoint.toString())); connectV4(in, out, epoint, deadlineMillis); return; } diff --git a/src/java.base/share/classes/java/net/URI.java b/src/java.base/share/classes/java/net/URI.java index 3aa2a18ccf83d..0d9415bf6a2d7 100644 --- a/src/java.base/share/classes/java/net/URI.java +++ b/src/java.base/share/classes/java/net/URI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, 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 @@ -42,8 +42,12 @@ import java.text.Normalizer; import jdk.internal.access.JavaNetUriAccess; import jdk.internal.access.SharedSecrets; +import jdk.internal.util.Exceptions; import sun.nio.cs.UTF_8; +import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.throwURISyntaxException; + /** * Represents a Uniform Resource Identifier (URI) reference. * @@ -2032,7 +2036,7 @@ private static void checkPath(String s, String scheme, String path) { if (scheme != null) { if (path != null && !path.isEmpty() && path.charAt(0) != '/') - throw new URISyntaxException(s, "Relative path in absolute URI"); + throwURISyntaxException("%s", "Relative path in absolute URI", -1, filterHostName(s)); } } @@ -2988,11 +2992,14 @@ private class Parser { // -- Methods for throwing URISyntaxException in various ways -- private void fail(String reason) throws URISyntaxException { - throw new URISyntaxException(input, reason); + throwURISyntaxException("%s", reason, -1, filterHostName(input)); } private void fail(String reason, int p) throws URISyntaxException { - throw new URISyntaxException(input, reason, p); + if (!Exceptions.enhancedHostExceptions()) { + p = -1; + } + throwURISyntaxException("%s", reason, p, filterHostName(input)); } private void failExpecting(String expected, int p) diff --git a/src/java.base/share/classes/java/net/URL.java b/src/java.base/share/classes/java/net/URL.java index be4daa28f3357..170fd99cde1ea 100644 --- a/src/java.base/share/classes/java/net/URL.java +++ b/src/java.base/share/classes/java/net/URL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -44,6 +44,8 @@ import jdk.internal.misc.ThreadTracker; import jdk.internal.misc.VM; import sun.net.util.IPAddressUtil; +import static jdk.internal.util.Exceptions.throwURISyntaxException; +import static jdk.internal.util.Exceptions.filterHostName; /** * Class {@code URL} represents a Uniform Resource @@ -1168,7 +1170,8 @@ public URI toURI() throws URISyntaxException { URI uri = new URI(toString()); if (authority != null && isBuiltinStreamHandler(handler)) { String s = IPAddressUtil.checkAuthority(this); - if (s != null) throw new URISyntaxException(authority, s); + if (s != null) + throwURISyntaxException("%s", s, -1, filterHostName(authority)); } return uri; } diff --git a/src/java.base/share/classes/java/net/URLStreamHandler.java b/src/java.base/share/classes/java/net/URLStreamHandler.java index 1400741b2bb13..ed225a6061bc7 100644 --- a/src/java.base/share/classes/java/net/URLStreamHandler.java +++ b/src/java.base/share/classes/java/net/URLStreamHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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,9 @@ import java.util.Objects; import sun.net.util.IPAddressUtil; +import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.filterHostName; + /** * The abstract class {@code URLStreamHandler} is the common * superclass for all stream protocol handlers. A stream protocol @@ -205,8 +208,8 @@ protected void parseURL(URL u, String spec, int start, int limit) { host = nhost.substring(0,ind+1); if (!IPAddressUtil. isIPv6LiteralAddress(host.substring(1, ind))) { - throw new IllegalArgumentException( - "Invalid host: "+ host); + throwException(IllegalArgumentException.class, "Invalid host%s", + filterHostName(host).prefixWith(": ")); } port = -1 ; @@ -219,13 +222,13 @@ protected void parseURL(URL u, String spec, int start, int limit) { nhost.length(), 10); } } else { - throw new IllegalArgumentException( - "Invalid authority field: " + authority); + throwException(IllegalArgumentException.class, "Invalid authority field%s", + filterHostName(authority).prefixWith(": ")); } } } else { - throw new IllegalArgumentException( - "Invalid authority field: " + authority); + throwException(IllegalArgumentException.class, "Invalid authority field%s", + filterHostName(authority).prefixWith(": ")); } } else { ind = host.indexOf(':'); diff --git a/src/java.base/share/classes/jdk/internal/util/Exceptions.java b/src/java.base/share/classes/jdk/internal/util/Exceptions.java new file mode 100644 index 0000000000000..9ea532053ba8b --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/util/Exceptions.java @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2018, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.util; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.net.UnixDomainSocketAddress; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.function.Consumer; +import java.util.stream.Stream; + +import sun.security.util.SecurityProperties; +import jdk.internal.misc.VM; + +/** + * Contains static utility methods which take an Exception + * and return either the same exception or a new instance + * of the same exception type with an "enhanced" message + * description. + * + * If the system/security property "jdk.includeInExceptions" is not + * set or does not contain the category hostInfo, + * then the original exception is returned. + * + * Code using this mechanism should use one of the static throwException + * methods below to generate and throw the exception in one method. + * exception() methods are also provided to generate an exception which + * then be modified before being thrown or used. Lastly, formatMsg() + * can generate a formatted (enhanced or restricted) string only. + * + * The SensitiveInfo objects should be generated with one of the following: + * public static SensitiveInfo filterHostName(String host) + * public static SensitiveInfo filterJarName(String name) + * public static SensitiveInfo filterUserName(String name) + */ +public final class Exceptions { + private Exceptions() {} + + private static volatile boolean enhancedHostExceptionText; + private static volatile boolean enhancedUserExceptionText; + private static volatile boolean enhancedJarExceptionText; + private static volatile boolean initialized = false; + + /** + * Suffix added to all exception messages when enhanced exceptions are disabled + */ + private static final String ENH_DISABLED_MSG = "[enhanced exceptions disabled]"; + + + public static String enhancedDisabledMsg() { + return ENH_DISABLED_MSG; + } + + /** + * Base class for generating exception messages that may + * contain sensitive information which in certain contexts + * needs to be filtered out, in case it gets revealed in + * unexpected places. Exception messages are either enhanced + * or restricted. Enhanced messages include sensitive information. + * Restricted messages don't. + * + * Sub-class for any new category that needs to be independently + * controlled. Consider using a unique value for the + * SecurityProperties.includedInExceptions(String value) mechanism + * Current values defined are "hostInfo", "jar" and "userInfo" + * New code can also piggy back on existing categories + * + * A SensitiveInfo contains the following components + * all of which default to empty strings. + * + * prefix, the sensitive info itself, a suffix + * and a replacement string. + * + * The output(boolean enhance) method generates an enhanced + * string when enhance is true. + * This comprises (enhance == true) + * prefix + info + suffix + * When (enhance == false), then by default the output is: + * "" empty string + * However, if a replacement is set, then when enhance == false + * the output is the replacement string. + */ + public static abstract class SensitiveInfo { + String info, suffix, prefix, replacement; + boolean enhanced; + + SensitiveInfo(String info) { + this.info = info; + prefix = suffix = replacement = ""; + } + public SensitiveInfo prefixWith(String prefix) { + this.prefix = prefix; + return this; + } + public SensitiveInfo suffixWith(String suffix) { + this.suffix = suffix; + return this; + } + public SensitiveInfo replaceWith(String replacement) { + this.replacement = replacement; + return this; + } + + public boolean enhanced() { + return enhanced; + } + + /** + * Implementation should call output(boolean) + */ + public abstract String output(); + + protected String output(boolean enhance) { + if (enhance) { + this.enhanced = true; + return prefix + info + suffix; + } else { + return replacement; + } + } + } + + /** + * Throw an exception of the given class (which has a single arg (String) constructor + * with the given format string. For each %s in the format string, there must be a + * SensitiveInfo following that generates a message string in either enhanced or + * restricted mode. The entire string is then passed to the exception constructor + * Format specifiers other than %s are not supported, and will cause a runtime exception. + */ + public static void throwException(Class exClass, String format, + SensitiveInfo... infos) throws X + { + throw exception(exClass, format, infos); + } + + /** + * Simplified version of above with one SensitiveInfo and a "%s" format string + */ + public static void throwException(Class exClass, SensitiveInfo... infos) throws X + { + throwException(exClass, "%s", infos); + } + + /** + * Returns the exception without throwing it + */ + public static X exception(Class exClass, String format, + SensitiveInfo... infos) + { + try { + Constructor ctor = exClass.getConstructor(String.class); + String msg = formatMsg(format, infos); + return ctor.newInstance(msg); + } catch (ReflectiveOperationException e) { + throw new InternalError(); + } + } + + public static X exception(Class exClass, SensitiveInfo... infos) + { + return exception(exClass, "%s", infos); + } + + /** + * Special case for URISyntaxException (has two additional parameters) + */ + public static URISyntaxException throwURISyntaxException(String format, String arg2, + int index, SensitiveInfo... infos) + throws URISyntaxException + { + String msg = formatMsg(format, infos); + URISyntaxException ex = new URISyntaxException(msg, arg2, index); + throw ex; + } + + static final class HostInfo extends SensitiveInfo { + public HostInfo(String host) { + super(host); + } + @Override + public String output() { + setup(); + return super.output(enhancedHostExceptionText); + } + } + + static final class JarInfo extends SensitiveInfo { + public JarInfo(String name) { + super(name); + } + @Override + public String output() { + setup(); + return super.output(enhancedJarExceptionText); + } + } + + static final class UserInfo extends SensitiveInfo { + public UserInfo(String host) { + super(host); + } + @Override + public String output() { + setup(); + return super.output(enhancedUserExceptionText); + } + } + + // remove leading, trailing and duplicated space characters + static String trim(String s) { + int len = s.length(); + if (len == 0) return s; + + StringBuilder sb = new StringBuilder(); + + // initial value deals with leading spaces + boolean inSpace = true; + for (int i=0; i 0 && sb.charAt(sblen - 1) == ' ') + sb.deleteCharAt(sblen - 1); + return sb.toString(); + } + + public static SensitiveInfo filterHostName(String host) { + return new HostInfo(host); + } + + public static SensitiveInfo filterJarName(String name) { + return new JarInfo(name); + } + + public static SensitiveInfo filterUserName(String name) { + return new UserInfo(name); + } + + /** + * Transform each SensitiveInfo into a String argument which is passed + * to String.format(). This string is then trimmed. + */ + public static String formatMsg(String format, SensitiveInfo... infos) { + String[] args = new String[infos.length]; + + int i = 0; + boolean enhanced = true; + + for (SensitiveInfo info : infos) { + args[i++] = info.output(); + if (!info.enhanced()) + enhanced = false; + } + return trim(String.format(format, (Object[])args) + + (enhanced ? "" : " " + ENH_DISABLED_MSG)); + } + + /** + * Simplification of above. Equivalent to: + * formatMsg("%s", SensitiveInfo[1]); // ie with one arg + */ + private static String formatMsg(SensitiveInfo info) { + return trim(info.output()); + } + + public static void setup() { + if (initialized || !VM.isBooted()) + return; + enhancedHostExceptionText = SecurityProperties.includedInExceptions("hostInfo"); + enhancedUserExceptionText = SecurityProperties.includedInExceptions("userInfo"); + enhancedJarExceptionText = SecurityProperties.INCLUDE_JAR_NAME_IN_EXCEPTIONS; + initialized = true; + } + + public static boolean enhancedHostExceptions() { + setup(); + return enhancedHostExceptionText; + } + + /** + * The enhanced message text is the socket address appended to + * the original IOException message + */ + public static IOException ioException(IOException e, SocketAddress addr) { + setup(); + if (addr == null) { + return e; + } + if (!enhancedHostExceptionText) { + return create(e, e.getMessage() + " " + ENH_DISABLED_MSG); + } + if (addr instanceof UnixDomainSocketAddress) { + return ofUnixDomain(e, (UnixDomainSocketAddress)addr); + } else if (addr instanceof InetSocketAddress) { + return ofInet(e, (InetSocketAddress)addr); + } else { + return e; + } + } + + private static IOException ofInet(IOException e, InetSocketAddress addr) { + return create(e, String.join(": ", e.getMessage(), addr.toString())); + } + + private static IOException ofUnixDomain(IOException e, UnixDomainSocketAddress addr) { + String path = addr.getPath().toString(); + StringBuilder sb = new StringBuilder(); + sb.append(e.getMessage()); + sb.append(": "); + sb.append(path); + String enhancedMsg = sb.toString(); + return create(e, enhancedMsg); + } + + // return a new instance of the same type with the given detail + // msg, or if the type doesn't support detail msgs, return given + // instance. + private static T create(T e, String msg) { + try { + Class clazz = e.getClass(); + @SuppressWarnings("unchecked") + Constructor ctor = (Constructor)clazz.getConstructor(String.class); + T e1 = (ctor.newInstance(msg)); + e1.setStackTrace(e.getStackTrace()); + return e1; + } catch (Exception e0) { + // Some eg AsynchronousCloseException have no detail msg + return e; + } + } +} diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 66e6267367c26..7b05b8ce99cd7 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -270,8 +270,10 @@ java.prefs, java.security.jgss, java.smartcardio, + java.net.http, jdk.charsets, jdk.internal.vm.ci, + jdk.httpserver, jdk.jlink, jdk.jpackage, jdk.net; diff --git a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java index b3da295c4a7c5..dbab94dcd9dbb 100644 --- a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java +++ b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -37,6 +37,9 @@ import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import static jdk.internal.util.Exceptions.exception; +import static jdk.internal.util.Exceptions.filterHostName; + public class IPAddressUtil { private static final int INADDR4SZ = 4; private static final int INADDR16SZ = 16; @@ -161,7 +164,8 @@ public static byte[] validateNumericFormatV4(String src, boolean throwIAE) { * @return an {@code IllegalArgumentException} instance */ public static IllegalArgumentException invalidIpAddressLiteral(String src) { - return new IllegalArgumentException("Invalid IP address literal: " + src); + return exception(IllegalArgumentException.class, "Invalid IP address literal%s", + filterHostName(src).prefixWith(": ")); } /* diff --git a/src/java.base/share/classes/sun/net/util/SocketExceptions.java b/src/java.base/share/classes/sun/net/util/SocketExceptions.java deleted file mode 100644 index 1198898edcb3f..0000000000000 --- a/src/java.base/share/classes/sun/net/util/SocketExceptions.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.net.util; - -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.net.InetSocketAddress; -import java.net.UnixDomainSocketAddress; -import java.net.SocketAddress; - -import sun.security.util.SecurityProperties; - -public final class SocketExceptions { - private SocketExceptions() {} - - private static final boolean enhancedExceptionText = - SecurityProperties.includedInExceptions("hostInfo"); - - /** - * Utility which takes an exception and returns either the same exception - * or a new exception of the same type with the same stack trace - * and detail message enhanced with addressing information from the - * given InetSocketAddress. - * - * If the system/security property "jdk.includeInExceptions" is not - * set or does not contain the category hostInfo, - * then the original exception is returned. - * - * Only specific IOException subtypes are supported. - */ - public static IOException of(IOException e, SocketAddress addr) { - if (!enhancedExceptionText || addr == null) { - return e; - } - if (addr instanceof UnixDomainSocketAddress) { - return ofUnixDomain(e, (UnixDomainSocketAddress)addr); - } else if (addr instanceof InetSocketAddress) { - return ofInet(e, (InetSocketAddress)addr); - } else { - return e; - } - } - - private static IOException ofInet(IOException e, InetSocketAddress addr) { - return create(e, String.join(": ", e.getMessage(), addr.toString())); - } - - private static IOException ofUnixDomain(IOException e, UnixDomainSocketAddress addr) { - String path = addr.getPath().toString(); - StringBuilder sb = new StringBuilder(); - sb.append(e.getMessage()); - sb.append(": "); - sb.append(path); - String enhancedMsg = sb.toString(); - return create(e, enhancedMsg); - } - - // return a new instance of the same type with the given detail - // msg, or if the type doesn't support detail msgs, return given - // instance. - private static IOException create(final IOException e, final String msg) { - try { - Class clazz = e.getClass(); - Constructor ctor = clazz.getConstructor(String.class); - IOException e1 = (IOException)(ctor.newInstance(msg)); - e1.setStackTrace(e.getStackTrace()); - return e1; - } catch (Exception e0) { - // Some eg AsynchronousCloseException have no detail msg - return e; - } - } -} diff --git a/src/java.base/share/classes/sun/net/www/ParseUtil.java b/src/java.base/share/classes/sun/net/www/ParseUtil.java index 628eeb948ad88..a5bfdb18bf138 100644 --- a/src/java.base/share/classes/sun/net/www/ParseUtil.java +++ b/src/java.base/share/classes/sun/net/www/ParseUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, 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 @@ -40,6 +40,8 @@ import java.util.HexFormat; import sun.nio.cs.UTF_8; +import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.throwURISyntaxException; /** * A class that contains useful routines common to sun.net.www @@ -502,8 +504,8 @@ private static void checkPath(String s, String scheme, String path) { if (scheme != null) { if (path != null && !path.isEmpty() && path.charAt(0) != '/') - throw new URISyntaxException(s, - "Relative path in absolute URI"); + throwURISyntaxException("%s", "Relative path in absolute URI", + -1, filterHostName(s)); } } diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java b/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java index 2884f825b8439..de9fba4aacc73 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, 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 @@ -27,6 +27,8 @@ import java.io.IOException; import java.net.*; +import static jdk.internal.util.Exceptions.filterJarName; +import static jdk.internal.util.Exceptions.throwException; /* * Jar URL Handler @@ -181,8 +183,10 @@ private String parseAbsoluteSpec(String spec) { String innerSpec = spec.substring(0, index - 1); newURL(innerSpec); } catch (MalformedURLException e) { - throw new NullPointerException("invalid url: " + - spec + " (" + e + ")"); + throwException(NullPointerException.class, "invalid url: %s %s", + filterJarName(spec), filterJarName(e.getMessage()) + .prefixWith("(") + .suffixWith(")")); } return spec; } @@ -193,19 +197,16 @@ private String parseContextSpec(URL url, String spec) { if (spec.startsWith("/")) { int bangSlash = indexOfBangSlash(ctxFile); if (bangSlash == -1) { - throw new NullPointerException("malformed " + - "context url:" + - url + - ": no !/"); + throwException(NullPointerException.class, "malformed context url%s : no !/", + filterJarName(url.toString()).prefixWith(": ")); } ctxFile = ctxFile.substring(0, bangSlash); } else { // chop up the last component int lastSlash = ctxFile.lastIndexOf('/'); if (lastSlash == -1) { - throw new NullPointerException("malformed " + - "context url:" + - url); + throwException(NullPointerException.class, "malformed context url%s", + filterJarName(url.toString()).prefixWith(": ")); } else if (lastSlash < ctxFile.length() - 1) { ctxFile = ctxFile.substring(0, lastSlash + 1); } diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java b/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java index 9afbea8bf76e8..f24d36ea83398 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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,6 +34,8 @@ import jdk.internal.util.OperatingSystem; import sun.net.util.URLUtil; +import static jdk.internal.util.Exceptions.filterJarName; +import static jdk.internal.util.Exceptions.throwException; /* A factory for cached JAR file. This class is used to both retrieve * and cache Jar files. @@ -107,7 +109,7 @@ JarFile getOrCreate(URL url, boolean useCaches) throws IOException { result = URLJarFile.getJarFile(patched, this); } if (result == null) - throw new FileNotFoundException(url.toString()); + throwException(FileNotFoundException.class, filterJarName(url.toString())); return result; } @@ -198,7 +200,7 @@ JarFile get(URL url, boolean useCaches) throws IOException { result = URLJarFile.getJarFile(url, this); } if (result == null) - throw new FileNotFoundException(url.toString()); + throwException(FileNotFoundException.class, filterJarName(url.toString())); return result; } diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java index 85d36fe23207e..e685e57e47628 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, 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 @@ -37,6 +37,9 @@ import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import static jdk.internal.util.Exceptions.filterJarName; +import static jdk.internal.util.Exceptions.throwException; + /** * @author Benjamin Renaud @@ -126,9 +129,10 @@ public void connect() throws IOException { factory.closeIfNotCached(url, jarFile); } catch (Exception e) { } - throw new FileNotFoundException("JAR entry " + entryName + - " not found in " + - jarFile.getName()); + throwException(FileNotFoundException.class, + "JAR entry %s not found in jar file %s", + filterJarName(entryName), + filterJarName(jarFile.getName())); } } @@ -166,9 +170,10 @@ public InputStream getInputStream() throws IOException { throw new IOException("no entry name specified"); } else { if (jarEntry == null) { - throw new FileNotFoundException("JAR entry " + entryName + - " not found in " + - jarFile.getName()); + throwException(FileNotFoundException.class, + "JAR entry %s not found in jar file %s", + filterJarName(entryName), + filterJarName(jarFile.getName())); } result = new JarURLInputStream (jarFile.getInputStream(jarEntry)); } diff --git a/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java b/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java index 95bc2179a312a..aa5f9e906d9a7 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -31,6 +31,9 @@ import java.net.MalformedURLException; import java.io.IOException; +import static jdk.internal.util.Exceptions.filterJarName; +import static jdk.internal.util.Exceptions.throwException; + /** * Placeholder protocol handler for the jmod protocol. */ @@ -43,7 +46,8 @@ protected URLConnection openConnection(URL url) throws IOException { String s = url.toString(); int index = s.indexOf("!/"); if (index == -1) - throw new MalformedURLException("no !/ found in url spec:" + s); + throwException(MalformedURLException.class, "no !/ found in url spec%s", + filterJarName(s).prefixWith(": ")); throw new IOException("Can't connect to jmod URL"); } diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java index 4930e1447a3aa..8d9aa9c77c425 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -53,6 +53,8 @@ import java.util.concurrent.locks.ReentrantLock; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.filterHostName; /** * A multicast datagram socket based on a datagram channel. @@ -490,7 +492,8 @@ public void setInterface(InetAddress inf) throws SocketException { NetworkInterface ni = NetworkInterface.getByInetAddress(inf); if (ni == null) { String address = inf.getHostAddress(); - throw new SocketException("No network interface with address " + address); + throwException(SocketException.class, "No network interface found with address %s", + filterHostName(address)); } synchronized (outgoingInterfaceLock) { // set interface and update cached values diff --git a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java index 7c64d6721e2c7..c937069f94a66 100644 --- a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -58,7 +58,7 @@ import sun.net.NetHooks; import sun.net.PlatformSocketImpl; import sun.net.ext.ExtendedSocketOptions; -import sun.net.util.SocketExceptions; +import jdk.internal.util.Exceptions; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; @@ -605,7 +605,7 @@ protected void connect(SocketAddress remote, int millis) throws IOException { assert Thread.currentThread().isVirtual(); throw new SocketException("Closed by interrupt"); } else { - throw SocketExceptions.of(ioe, isa); + throw Exceptions.ioException(ioe, isa); } } } diff --git a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java index 893bd17ceed89..4a8402f6b0fa5 100644 --- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, 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 @@ -64,7 +64,7 @@ import sun.net.ConnectionResetException; import sun.net.NetHooks; import sun.net.ext.ExtendedSocketOptions; -import sun.net.util.SocketExceptions; +import jdk.internal.util.Exceptions; /** * An implementation of SocketChannels @@ -975,7 +975,7 @@ public boolean connect(SocketAddress remote) throws IOException { } catch (IOException ioe) { // connect failed, close the channel close(); - throw SocketExceptions.of(ioe, sa); + throw Exceptions.ioException(ioe, sa); } } @@ -1065,7 +1065,7 @@ public boolean finishConnect() throws IOException { } catch (IOException ioe) { // connect failed, close the channel close(); - throw SocketExceptions.of(ioe, remoteAddress); + throw Exceptions.ioException(ioe, remoteAddress); } } @@ -1325,7 +1325,7 @@ void blockingConnect(SocketAddress remote, long nanos) throws IOException { } catch (IOException ioe) { // connect failed, close the channel close(); - throw SocketExceptions.of(ioe, sa); + throw Exceptions.ioException(ioe, sa); } } diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index 693d19438f6da..513052122418d 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -1275,11 +1275,16 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # jar - enables more detailed information in the IOExceptions thrown # by classes in the java.util.jar package # +# userInfo - enables more detailed information in exceptions which may contain +# user identity information +# # The property setting in this file can be overridden by a system property of # the same name, with the same syntax and possible values. # -#jdk.includeInExceptions=hostInfo,jar - +# When enhanced exceptions are disabled the following string is appended +# to each restricted exception message "[enhanced exceptions disabled]" +# +#jdk.includeInExceptions=hostInfo,jar,userInfo # # Disabled mechanisms for the Simple Authentication and Security Layer (SASL) # diff --git a/src/java.base/share/native/libnet/net_util.c b/src/java.base/share/native/libnet/net_util.c index a198152563a09..346d79d5563b7 100644 --- a/src/java.base/share/native/libnet/net_util.c +++ b/src/java.base/share/native/libnet/net_util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, 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 @@ -86,9 +86,36 @@ DEF_JNI_OnLoad(JavaVM *vm, void *reserved) /* check if SO_REUSEPORT is supported on this platform */ REUSEPORT_available = reuseport_supported(IPv6_available); + return JNI_VERSION_1_2; } +static int enhancedExceptionsInitialized = 0; +static int enhancedExceptionsAllowed = -1; + +#define CHECK_NULL_THROW_ERROR(X) \ + if (X == NULL) { \ + JNU_ThrowByName(env, "java/lang/InternalError", \ + "can't initialize enhanced exceptions"); \ + return -1; \ + } + +int getEnhancedExceptionsAllowed(JNIEnv *env) { + jclass cls; + jfieldID fid; + + if (enhancedExceptionsInitialized) { + return enhancedExceptionsAllowed; + } + cls = (*env)->FindClass(env, "jdk/internal/util/Exceptions"); + CHECK_NULL_THROW_ERROR(cls); + fid = (*env)->GetStaticFieldID(env, cls, "enhancedHostExceptionText", "Z"); + CHECK_NULL_THROW_ERROR(fid); + enhancedExceptionsAllowed = (*env)->GetStaticBooleanField(env, cls, fid); + enhancedExceptionsInitialized = 1; + return enhancedExceptionsAllowed; +} + static int initialized = 0; JNIEXPORT void JNICALL initInetAddressIDs(JNIEnv *env) { diff --git a/src/java.base/share/native/libnet/net_util.h b/src/java.base/share/native/libnet/net_util.h index a1fa9571821ca..123aca2d98f66 100644 --- a/src/java.base/share/native/libnet/net_util.h +++ b/src/java.base/share/native/libnet/net_util.h @@ -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 @@ -115,6 +115,12 @@ JNIEXPORT jint JNICALL ipv6_available(); JNIEXPORT jint JNICALL reuseport_available(); +/** + * Message appended to exception texts when enhanced exceptions disabled + * Must be kept consistent with Java implementation + */ +#define ENH_DISABLED_MSG "[enhanced exceptions disabled]" + /** * This function will fill a SOCKETADDRESS structure from an InetAddress * object. @@ -183,4 +189,6 @@ int lookupCharacteristicsToAddressFamily(int characteristics); int addressesInSystemOrder(int characteristics); +int getEnhancedExceptionsAllowed(JNIEnv *env); + #endif /* NET_UTILS_H */ diff --git a/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java b/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java index b9c099ef92fb8..5e75e3b2486d6 100644 --- a/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java +++ b/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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,9 +32,10 @@ import java.io.IOException; import java.io.FileDescriptor; +import jdk.internal.util.Exceptions; + import sun.net.ConnectionResetException; import sun.net.NetHooks; -import sun.net.util.SocketExceptions; /** * Unix implementation of AsynchronousSocketChannel @@ -264,7 +265,7 @@ private void finishConnect(boolean mayInvokeDirect) { if (e != null) { if (e instanceof IOException) { var isa = (InetSocketAddress)pendingRemote; - e = SocketExceptions.of((IOException)e, isa); + e = Exceptions.ioException((IOException)e, isa); } // close channel if connection cannot be established try { @@ -355,7 +356,7 @@ Future implConnect(SocketAddress remote, // close channel if connect fails if (e != null) { if (e instanceof IOException) { - e = SocketExceptions.of((IOException)e, isa); + e = Exceptions.ioException((IOException)e, isa); } try { close(); diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java b/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java index f50dea108b0f1..742d1f5da0841 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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,9 @@ import java.io.IOException; import static sun.nio.fs.UnixNativeDispatcher.*; +import static jdk.internal.util.Exceptions.filterUserName; +import static jdk.internal.util.Exceptions.throwException; + /** * Unix implementation of java.nio.file.attribute.UserPrincipal */ @@ -132,18 +135,19 @@ public static Group fromGid(int gid) { private static int lookupName(String name, boolean isGroup) throws IOException { - int id; + int id = -1; try { id = (isGroup) ? getgrnam(name) : getpwnam(name); } catch (UnixException x) { - throw new IOException(name + ": " + x.errorString()); + throwException(IOException.class, "%s " + x.errorString(), + filterUserName(name).suffixWith(": ")); } if (id == -1) { // lookup failed, allow input to be uid or gid try { id = Integer.parseInt(name); } catch (NumberFormatException ignore) { - throw new UserPrincipalNotFoundException(name); + throwException(UserPrincipalNotFoundException.class, filterUserName(name)); } } return id; diff --git a/src/java.base/unix/native/libnet/net_util_md.c b/src/java.base/unix/native/libnet/net_util_md.c index 1713d0a8ccdbd..0154036be5896 100644 --- a/src/java.base/unix/native/libnet/net_util_md.c +++ b/src/java.base/unix/native/libnet/net_util_md.c @@ -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 @@ -184,16 +184,26 @@ void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, { int size; char *buf; - const char *format = "%s: %s"; const char *error_string = gai_strerror(gai_error); if (error_string == NULL) error_string = "unknown error"; + int enhancedExceptions = getEnhancedExceptionsAllowed(env); + + if (enhancedExceptions) { + size = strlen(hostname); + } else { + size = strlen(ENH_DISABLED_MSG) + 1; + } + size += strlen(error_string) + 3; - size = strlen(format) + strlen(hostname) + strlen(error_string) + 2; buf = (char *) malloc(size); if (buf) { jstring s; - snprintf(buf, size, format, hostname, error_string); + if (enhancedExceptions) { + snprintf(buf, size, "%s: %s", hostname, error_string); + } else { + snprintf(buf, size, " %s %s", error_string, ENH_DISABLED_MSG); + } s = JNU_NewStringPlatform(env, buf); if (s != NULL) { jobject x = JNU_NewObjectByName(env, diff --git a/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java b/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java index f8b5fab431660..36065f040a0a9 100644 --- a/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java +++ b/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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,9 +33,9 @@ import java.net.*; import java.util.concurrent.*; import java.io.IOException; +import jdk.internal.util.Exceptions; import jdk.internal.invoke.MhUtil; import jdk.internal.misc.Unsafe; -import sun.net.util.SocketExceptions; /** * Windows implementation of AsynchronousSocketChannel using overlapped I/O. @@ -253,7 +253,7 @@ public void run() { if (exc != null) { closeChannel(); - exc = SocketExceptions.of(toIOException(exc), remote); + exc = Exceptions.ioException(toIOException(exc), remote); result.setFailure(exc); } Invoker.invoke(result); @@ -280,7 +280,7 @@ public void completed(int bytesTransferred, boolean canInvokeDirect) { if (exc != null) { closeChannel(); IOException ee = toIOException(exc); - ee = SocketExceptions.of(ee, remote); + ee = Exceptions.ioException(ee, remote); result.setFailure(ee); } @@ -296,12 +296,12 @@ public void completed(int bytesTransferred, boolean canInvokeDirect) { */ @Override public void failed(int error, IOException x) { - x = SocketExceptions.of(x, remote); + x = Exceptions.ioException(x, remote); if (isOpen()) { closeChannel(); result.setFailure(x); } else { - x = SocketExceptions.of(new AsynchronousCloseException(), remote); + x = Exceptions.ioException(new AsynchronousCloseException(), remote); result.setFailure(x); } Invoker.invoke(result); diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java b/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java index da3460592f498..2c6563fb21db3 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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,8 @@ import static sun.nio.fs.WindowsNativeDispatcher.*; import static sun.nio.fs.WindowsConstants.*; +import static jdk.internal.util.Exceptions.filterUserName; +import static jdk.internal.util.Exceptions.throwException; /** * A SecurityDescriptor for use when setting a file's ACL or creating a file @@ -136,8 +138,8 @@ private WindowsSecurityDescriptor(List acl) throws IOException { Math.max(SIZEOF_ACCESS_ALLOWED_ACE, SIZEOF_ACCESS_DENIED_ACE); } catch (WindowsException x) { - throw new IOException("Failed to get SID for " + user.getName() - + ": " + x.errorString()); + throwException(IOException.class, "Failed to get SID %s : " + x.errorString(), + filterUserName(user.getName()).prefixWith("for ")); } } diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java b/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java index 336bbe22cfb5a..8a33043ffa464 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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,8 @@ import static sun.nio.fs.WindowsConstants.*; import static sun.nio.fs.WindowsNativeDispatcher.*; +import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.filterUserName; class WindowsUserPrincipals { private WindowsUserPrincipals() { } @@ -132,13 +134,14 @@ static UserPrincipal fromSid(long sidAddress) throws IOException { static UserPrincipal lookup(String name) throws IOException { // invoke LookupAccountName to get buffer size needed for SID - int size; + int size = 0; try { size = LookupAccountName(name, 0L, 0); } catch (WindowsException x) { if (x.lastError() == ERROR_NONE_MAPPED) throw new UserPrincipalNotFoundException(name); - throw new IOException(name + ": " + x.errorString()); + throwException(IOException.class, "%s " + x.errorString(), + filterUserName(name).suffixWith(": ")); } assert size > 0; @@ -153,7 +156,9 @@ static UserPrincipal lookup(String name) throws IOException { // return user principal return fromSid(sidBuffer.address()); } catch (WindowsException x) { - throw new IOException(name + ": " + x.errorString()); + throwException(IOException.class, "%s " + x.errorString(), + filterUserName(name).suffixWith(": ")); } + return null; // can't happen. Exception will be thrown } } diff --git a/src/java.base/windows/native/libnet/Inet4AddressImpl.c b/src/java.base/windows/native/libnet/Inet4AddressImpl.c index 0e2d6a3455f43..5f235a85338d5 100644 --- a/src/java.base/windows/native/libnet/Inet4AddressImpl.c +++ b/src/java.base/windows/native/libnet/Inet4AddressImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, 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 @@ -88,8 +88,9 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, if (error) { // report error - NET_ThrowByNameWithLastError(env, "java/net/UnknownHostException", - hostname); + NET_ThrowByNameWithLastError( + env, "java/net/UnknownHostException", + getEnhancedExceptionsAllowed(env) ? hostname : ENH_DISABLED_MSG); goto cleanupAndReturn; } else { int i = 0; diff --git a/src/java.base/windows/native/libnet/Inet6AddressImpl.c b/src/java.base/windows/native/libnet/Inet6AddressImpl.c index 244e2fefa9b1f..b3d10a33fa01b 100644 --- a/src/java.base/windows/native/libnet/Inet6AddressImpl.c +++ b/src/java.base/windows/native/libnet/Inet6AddressImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, 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 @@ -84,7 +84,7 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, if (error) { // report error NET_ThrowByNameWithLastError(env, "java/net/UnknownHostException", - hostname); + getEnhancedExceptionsAllowed(env) ? hostname : ENH_DISABLED_MSG); goto cleanupAndReturn; } else { int i = 0, inetCount = 0, inet6Count = 0, inetIndex = 0, diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java index e4dee55d8ea37..b294799a35fc3 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, 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 @@ -39,6 +39,8 @@ import static jdk.internal.net.http.common.Utils.isValidName; import static jdk.internal.net.http.common.Utils.isValidValue; import static jdk.internal.net.http.common.Utils.newIAE; +import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.throwException; public class HttpRequestBuilderImpl implements HttpRequest.Builder { @@ -82,7 +84,8 @@ static void checkURI(URI uri) { throw newIAE("invalid URI scheme %s", scheme); } if (uri.getHost() == null) { - throw newIAE("unsupported URI %s", uri); + throwException(IllegalArgumentException.class, "unsupported URI %s", + filterHostName(uri.toString())); } } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java index 79b2332ae37cc..b7507f8aaa634 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -46,6 +46,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import jdk.internal.net.http.ResponseSubscribers.PathSubscriber; +import jdk.internal.util.Exceptions; import static java.util.regex.Pattern.CASE_INSENSITIVE; public final class ResponseBodyHandlers { @@ -190,7 +191,13 @@ static boolean allowedInToken(char c) { static final UncheckedIOException unchecked(ResponseInfo rinfo, String msg) { - String s = String.format("%s in response [%d, %s]", msg, rinfo.statusCode(), rinfo.headers()); + String s; + if (Exceptions.enhancedHostExceptions()) { + s = String.format("%s in response [%d, %s]", msg, rinfo.statusCode(), rinfo.headers()); + } else { + s = String.format("%s in response [%d] %s", msg, rinfo.statusCode(), + Exceptions.enhancedDisabledMsg()); + } return new UncheckedIOException(new IOException(s)); } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java index c1c0853504c5f..1bdf39daccc7a 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, 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 @@ -61,6 +61,8 @@ import static java.lang.String.format; import static jdk.internal.net.http.common.Utils.isValidName; import static jdk.internal.net.http.common.Utils.stringOf; +import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.throwException; public class OpeningHandshake { @@ -336,9 +338,11 @@ private static URI checkURI(URI uri) { if (!("ws".equalsIgnoreCase(scheme) || "wss".equalsIgnoreCase(scheme))) throw illegal("invalid URI scheme: " + scheme); if (uri.getHost() == null) - throw illegal("URI must contain a host: " + uri); + throwException(IllegalArgumentException.class, "URI must contain a host%s", + filterHostName(uri.toString()).prefixWith(": ")); if (uri.getFragment() != null) - throw illegal("URI must not contain a fragment: " + uri); + throwException(IllegalArgumentException.class, "URI must not contain a fragment%s", + filterHostName(uri.toString()).prefixWith(": ")); return uri; } diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java index a7daa46bdffe9..0a52105f88db7 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -37,6 +37,8 @@ public class JWebServer { private static final String SYS_PROP_MAX_CONNECTIONS = "jdk.httpserver.maxConnections"; private static final String DEFAULT_JWEBSERVER_MAX_CONNECTIONS = "200"; + private static final String SYS_PROP_ENHANCED_EXCEP = "jdk.includeInExceptions"; + private static final String DEFAULT_ENHANCED_EXCEP = "hostInfo"; /** * This constructor should never be called. */ @@ -63,6 +65,7 @@ public class JWebServer { */ public static void main(String... args) { setMaxReqTime(); + setEnhancedExceptions(); setMaxConnectionsIfNotSet(); int ec = SimpleFileServerImpl.start(new PrintWriter(System.out, true, UTF_8), "jwebserver", args); @@ -82,6 +85,14 @@ private static void setMaxReqTime() { } } + static void setEnhancedExceptions() { + if (System.getProperty(SYS_PROP_ENHANCED_EXCEP) != null) { + // an explicit value has already been set, so we don't override it + return; + } + System.setProperty(SYS_PROP_ENHANCED_EXCEP, DEFAULT_ENHANCED_EXCEP); + } + static void setMaxConnectionsIfNotSet() { if (System.getProperty(SYS_PROP_MAX_CONNECTIONS) == null) { System.setProperty(SYS_PROP_MAX_CONNECTIONS, DEFAULT_JWEBSERVER_MAX_CONNECTIONS); diff --git a/test/jdk/com/sun/net/httpserver/simpleserver/CommandLineNegativeTest.java b/test/jdk/com/sun/net/httpserver/simpleserver/CommandLineNegativeTest.java index 3a22d54f36d04..fc1c6eda5f12f 100644 --- a/test/jdk/com/sun/net/httpserver/simpleserver/CommandLineNegativeTest.java +++ b/test/jdk/com/sun/net/httpserver/simpleserver/CommandLineNegativeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -235,7 +235,11 @@ static String getJava(Path image) { } static OutputAnalyzer simpleserver(String... args) throws Throwable { - var pb = new ProcessBuilder(args) + String[] nargs = new String[args.length + 1]; + nargs[0] = args[0]; + System.arraycopy(args, 1, nargs, 2, args.length-1); + nargs[1] = "-Djdk.includeInExceptions=hostInfo"; + var pb = new ProcessBuilder(nargs) .directory(TEST_DIR.toFile()); var outputAnalyser = ProcessTools.executeCommand(pb) .outputTo(System.out) diff --git a/test/jdk/java/net/URI/Test.java b/test/jdk/java/net/URI/Test.java index 00d473f87beff..1b97ca22d8d56 100644 --- a/test/jdk/java/net/URI/Test.java +++ b/test/jdk/java/net/URI/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, 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 @@ -26,6 +26,7 @@ * @bug 4464135 4505046 4503239 4438319 4991359 4866303 7023363 7041800 * 7171415 6339649 6933879 8037396 8272072 8051627 8297687 * @author Mark Reinhold + * @run main/othervm -Djdk.includeInExceptions=hostInfo Test */ import java.io.ByteArrayInputStream; From ccb31ea662d12567ff219e94d64816c8cf57c9e7 Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Thu, 20 Feb 2025 13:50:22 +0000 Subject: [PATCH 02/22] update --- .../share/conf/security/java.security | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index 513052122418d..5f6f0b33eb508 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -1254,8 +1254,11 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # # Enhanced exception message information # -# By default, exception messages should not include potentially sensitive -# information such as file names, host names, or port numbers. This property +# Exception messages may include potentially sensitive information such as file +# names, host names, or port numbers. By default, socket related exceptions +# have this information restricted (meaning the sensitive details are removed). +# This property can be used to relax this restriction or to place further +# restrictions on other categories, defined below. The property # accepts one or more comma separated values, each of which represents a # category of enhanced exception message information to enable. Values are # case-insensitive. Leading and trailing whitespaces, surrounding each value, @@ -1268,16 +1271,25 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # # The categories are: # -# hostInfo - IOExceptions thrown by java.net.Socket and the socket types in the +# socket - IOExceptions thrown by java.net.Socket and the socket types in the # java.nio.channels package will contain enhanced exception # message information # -# jar - enables more detailed information in the IOExceptions thrown +# addressLookup - UnknownHostExceptions and other exceptions thrown by the +# java.net.InetAddress class +# +# net - All other exceptions thrown in networking code not included +# in the categories above. This include URL/URI, NetworkInterface +# and URLConnection among others. +# +# jar - enables more detailed information in the IOExceptions thrown # by classes in the java.util.jar package # # userInfo - enables more detailed information in exceptions which may contain # user identity information # +# For compatibility with previous releases, the special value hostInfo encompasses +# all the network related categories (socket,addressLookup,net) # The property setting in this file can be overridden by a system property of # the same name, with the same syntax and possible values. # @@ -1286,6 +1298,9 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # #jdk.includeInExceptions=hostInfo,jar,userInfo # +# The default setting +jdk.includeInExceptions=addressLookup,net +# # Disabled mechanisms for the Simple Authentication and Security Layer (SASL) # # Disabled mechanisms will not be negotiated by both SASL clients and servers. From fce5f694e01b26d7eeecdccac657b756d1f78f1a Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Fri, 28 Feb 2025 16:27:51 +0000 Subject: [PATCH 03/22] update --- .../share/classes/java/net/HostPortrange.java | 6 +- .../classes/java/net/Inet4AddressImpl.java | 4 +- .../share/classes/java/net/Inet6Address.java | 4 +- .../share/classes/java/net/InetAddress.java | 26 +-- .../classes/java/net/NetworkInterface.java | 4 +- .../share/classes/java/net/Proxy.java | 4 +- .../classes/java/net/SocketPermission.java | 8 +- .../classes/java/net/SocksSocketImpl.java | 6 +- src/java.base/share/classes/java/net/URI.java | 10 +- src/java.base/share/classes/java/net/URL.java | 4 +- .../classes/java/net/URLStreamHandler.java | 8 +- .../security-related-system-properties.html | 194 ++++++++++++++++++ .../classes/jdk/internal/util/Exceptions.java | 95 ++++++--- .../classes/sun/net/util/IPAddressUtil.java | 4 +- .../share/classes/sun/net/www/ParseUtil.java | 4 +- .../sun/nio/ch/DatagramSocketAdaptor.java | 4 +- .../share/conf/security/java.security | 9 +- src/java.base/share/native/libnet/net_util.c | 2 +- src/java.base/share/native/libnet/net_util.h | 6 - .../unix/native/libnet/net_util_md.c | 4 +- .../windows/native/libnet/Inet4AddressImpl.c | 2 +- .../windows/native/libnet/Inet6AddressImpl.c | 2 +- .../net/http/HttpRequestBuilderImpl.java | 4 +- .../net/http/ResponseBodyHandlers.java | 5 +- .../net/http/websocket/OpeningHandshake.java | 6 +- .../httpserver/simpleserver/JWebServer.java | 2 +- .../TestJDKIncludeInExceptions.java | 6 +- 27 files changed, 328 insertions(+), 105 deletions(-) create mode 100644 src/java.base/share/classes/java/security/doc-files/security-related-system-properties.html diff --git a/src/java.base/share/classes/java/net/HostPortrange.java b/src/java.base/share/classes/java/net/HostPortrange.java index e232e3428ddd0..fa08ffc318d4a 100644 --- a/src/java.base/share/classes/java/net/HostPortrange.java +++ b/src/java.base/share/classes/java/net/HostPortrange.java @@ -29,7 +29,7 @@ import java.util.Locale; import sun.net.util.IPAddressUtil; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterNetInfo; import static jdk.internal.util.Exceptions.throwException; /** @@ -81,7 +81,7 @@ public int hashCode() { hoststr = str.substring(1, rb); } else { throwException(IllegalArgumentException.class, "invalid IPv6 address%s", - filterHostName(str).prefixWith(": ")); + filterNetInfo(str).prefixWith(": ")); } int sep = str.indexOf(':', rb + 1); if (sep != -1 && str.length() > sep) { @@ -161,7 +161,7 @@ public int hashCode() { portrange = parsePort(portstr); } catch (Exception e) { throwException(IllegalArgumentException.class, "invalid port range%s", - filterHostName(portstr).prefixWith(": ")); + filterNetInfo(portstr).prefixWith(": ")); } } diff --git a/src/java.base/share/classes/java/net/Inet4AddressImpl.java b/src/java.base/share/classes/java/net/Inet4AddressImpl.java index d3d1a73bedbd5..0872b1306c336 100644 --- a/src/java.base/share/classes/java/net/Inet4AddressImpl.java +++ b/src/java.base/share/classes/java/net/Inet4AddressImpl.java @@ -27,7 +27,7 @@ import java.net.spi.InetAddressResolver.LookupPolicy; import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterLookupInfo; import static jdk.internal.util.Exceptions.throwException; /* @@ -40,7 +40,7 @@ final class Inet4AddressImpl implements InetAddressImpl { public InetAddress[] lookupAllHostAddr(String hostname, LookupPolicy lookupPolicy) throws UnknownHostException { if ((lookupPolicy.characteristics() & IPV4) == 0) { - throwException(UnknownHostException.class, filterHostName(hostname)); + throwException(UnknownHostException.class, filterLookupInfo(hostname)); } return lookupAllHostAddr(hostname); } diff --git a/src/java.base/share/classes/java/net/Inet6Address.java b/src/java.base/share/classes/java/net/Inet6Address.java index 632e094b0a211..96cf5ced3d0a0 100644 --- a/src/java.base/share/classes/java/net/Inet6Address.java +++ b/src/java.base/share/classes/java/net/Inet6Address.java @@ -35,7 +35,7 @@ import java.util.Enumeration; import java.util.Arrays; import java.util.Objects; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterLookupInfo; import static jdk.internal.util.Exceptions.throwException; /** @@ -584,7 +584,7 @@ static InetAddress parseAddressString(String addressLiteral, boolean removeSqBra if (numericZone != -1 || ifname != null) { // IPv4-mapped address must not contain zone-id throwException(UnknownHostException.class, "%sinvalid IPv4-mapped address", - filterHostName(addressLiteral).suffixWith(": ")); + filterLookupInfo(addressLiteral).suffixWith(": ")); } return new Inet4Address(null, addrBytes); } diff --git a/src/java.base/share/classes/java/net/InetAddress.java b/src/java.base/share/classes/java/net/InetAddress.java index b5f654f51cdda..e055089d85286 100644 --- a/src/java.base/share/classes/java/net/InetAddress.java +++ b/src/java.base/share/classes/java/net/InetAddress.java @@ -70,7 +70,7 @@ import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6; import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6_FIRST; import static jdk.internal.util.Exceptions.exception; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterLookupInfo; import static jdk.internal.util.Exceptions.throwException; /** @@ -907,7 +907,7 @@ private static class CachedLookup implements Addresses, Comparable @Override public InetAddress[] get() throws UnknownHostException { if (inetAddresses == null) { - throwException(UnknownHostException.class, filterHostName(host)); + throwException(UnknownHostException.class, filterLookupInfo(host)); } return inetAddresses; } @@ -1101,7 +1101,7 @@ public InetAddress[] get() throws UnknownHostException { } if (inetAddresses == null || inetAddresses.length == 0) { if (ex == null) { - throwException(UnknownHostException.class, filterHostName(host)); + throwException(UnknownHostException.class, filterLookupInfo(host)); } else { throw ex; } @@ -1214,16 +1214,16 @@ public String lookupByAddress(byte[] addr) throws UnknownHostException { } catch (IOException e) { throwException(UnknownHostException.class, "Unable to resolve address %s as hosts file %s not found", - filterHostName(Arrays.toString(addr)), - filterHostName(hostsFile) + filterLookupInfo(Arrays.toString(addr)), + filterLookupInfo(hostsFile) .replaceWith("from ${jdk.net.hosts.file} system property")); } if ((host == null) || (host.isEmpty()) || (host.equals(" "))) { throwException(UnknownHostException.class, "Requested address %s resolves to an invalid entry in hosts file %s", - filterHostName(Arrays.toString(addr)), - filterHostName(hostsFile) + filterLookupInfo(Arrays.toString(addr)), + filterLookupInfo(hostsFile) .replaceWith("from ${jdk.net.hosts.file} system property")); } return host; @@ -1287,7 +1287,7 @@ public Stream lookupByName(String host, LookupPolicy lookupPolicy) } catch (IOException e) { throwException(UnknownHostException.class, "Unable to resolve host %s as hosts file %s not found", - filterHostName(host), filterHostName(hostsFile) + filterLookupInfo(host), filterLookupInfo(hostsFile) .replaceWith("from ${jdk.net.hosts.file} system property")); } @@ -1321,7 +1321,7 @@ private void checkResultsList(List addressesList, String hostName) throws UnknownHostException { if (addressesList.isEmpty()) { throwException(UnknownHostException.class, "Unable to resolve host %s in hosts file %s", - filterHostName(hostName), filterHostName(hostsFile) + filterLookupInfo(hostName), filterLookupInfo(hostsFile) .replaceWith("from ${jdk.net.hosts.file} system property")); } } @@ -1560,7 +1560,7 @@ public static InetAddress[] getAllByName(String host) inetAddress = Inet4Address.parseAddressString(host, false); } catch (IllegalArgumentException iae) { UnknownHostException uhe = exception(UnknownHostException.class, - filterHostName(host)); + filterLookupInfo(host)); uhe.initCause(iae); throw uhe; } @@ -1588,7 +1588,7 @@ public static InetAddress[] getAllByName(String host) private static UnknownHostException invalidIPv6LiteralException(String host, boolean wrapInBrackets) { String hostString = wrapInBrackets ? "[" + host + "]" : host; return exception(UnknownHostException.class, "%sinvalid IPv6 address literal", - filterHostName(hostString).suffixWith(": ")); + filterLookupInfo(hostString).suffixWith(": ")); } /** @@ -1726,7 +1726,7 @@ static InetAddress[] getAddressesFromNameService(String host) InetAddress[] result = addresses == null ? null : addresses.toArray(InetAddress[]::new); if (result == null || result.length == 0) { - throw ex == null ? exception(UnknownHostException.class, filterHostName(host)) + throw ex == null ? exception(UnknownHostException.class, filterLookupInfo(host)) : ex; } return result; @@ -1800,7 +1800,7 @@ public static InetAddress getLocalHost() throws UnknownHostException { } catch (UnknownHostException uhe) { // Rethrow with a more informative error message. UnknownHostException uhe2 = exception(UnknownHostException.class, - filterHostName(local).suffixWith(": ") + uhe.getMessage()); + filterLookupInfo(local).suffixWith(": ") + uhe.getMessage()); uhe2.initCause(uhe); throw uhe2; } diff --git a/src/java.base/share/classes/java/net/NetworkInterface.java b/src/java.base/share/classes/java/net/NetworkInterface.java index e4024d7c97e8f..6f0a7406f47b2 100644 --- a/src/java.base/share/classes/java/net/NetworkInterface.java +++ b/src/java.base/share/classes/java/net/NetworkInterface.java @@ -34,7 +34,7 @@ import java.util.Spliterators; import java.util.stream.Stream; import java.util.stream.StreamSupport; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterNetInfo; import static jdk.internal.util.Exceptions.throwException; /** @@ -326,7 +326,7 @@ public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketE } } else { throwException(IllegalArgumentException.class, "invalid address type%s", - filterHostName(addr.toString()).prefixWith(": ")); + filterNetInfo(addr.toString()).prefixWith(": ")); } return getByInetAddress0(addr); } diff --git a/src/java.base/share/classes/java/net/Proxy.java b/src/java.base/share/classes/java/net/Proxy.java index 849520fea5854..616207726046d 100644 --- a/src/java.base/share/classes/java/net/Proxy.java +++ b/src/java.base/share/classes/java/net/Proxy.java @@ -26,7 +26,7 @@ package java.net; import java.util.Objects; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterNetInfo; import static jdk.internal.util.Exceptions.throwException; /** @@ -98,7 +98,7 @@ public Proxy(Type type, SocketAddress sa) { if ((type == Type.DIRECT) || !(sa instanceof InetSocketAddress)) { throwException(IllegalArgumentException.class, "type " + type + " is not compatible with address %s", - filterHostName(sa.toString()) + filterNetInfo(sa.toString()) .replaceWith("type " + sa.getClass().toString())); } this.type = type; diff --git a/src/java.base/share/classes/java/net/SocketPermission.java b/src/java.base/share/classes/java/net/SocketPermission.java index 4880e17b0842f..8fa17275f21e2 100644 --- a/src/java.base/share/classes/java/net/SocketPermission.java +++ b/src/java.base/share/classes/java/net/SocketPermission.java @@ -46,7 +46,7 @@ import sun.security.util.SecurityConstants; import sun.security.util.Debug; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterNetInfo; import static jdk.internal.util.Exceptions.throwException; /** @@ -395,7 +395,7 @@ private void init(String host, int mask) { host = host.substring(start, rb); } else { throwException(IllegalArgumentException.class, - "invalid host/port%s", filterHostName(host).prefixWith(": ")); + "invalid host/port%s", filterNetInfo(host).prefixWith(": ")); } sep = hostport.indexOf(':', rb+1); } else { @@ -413,7 +413,7 @@ private void init(String host, int mask) { portrange = parsePort(port); } catch (Exception e) { throwException(IllegalArgumentException.class, - "invalid port range%s", filterHostName(port).prefixWith(": ")); + "invalid port range%s", filterNetInfo(port).prefixWith(": ")); } } else { portrange = new int[] { PORT_MIN, PORT_MAX }; @@ -786,7 +786,7 @@ void getIP() throw uhe; } catch (IndexOutOfBoundsException iobe) { invalid = true; - throwException(UnknownHostException.class, filterHostName(getName())); + throwException(UnknownHostException.class, filterNetInfo(getName())); } } diff --git a/src/java.base/share/classes/java/net/SocksSocketImpl.java b/src/java.base/share/classes/java/net/SocksSocketImpl.java index baad82c75a734..da939cc4b706f 100644 --- a/src/java.base/share/classes/java/net/SocksSocketImpl.java +++ b/src/java.base/share/classes/java/net/SocksSocketImpl.java @@ -37,7 +37,7 @@ import sun.net.www.ParseUtil; import static sun.net.util.IPAddressUtil.isIPv6LiteralAddress; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterSocketInfo; import static jdk.internal.util.Exceptions.throwException; /** @@ -332,7 +332,7 @@ protected void connect(SocketAddress endpoint, int timeout) throws IOException { // SOCKS Protocol version 4 doesn't know how to deal with // DOMAIN type of addresses (unresolved addresses here) if (epoint.isUnresolved()) - throwException(UnknownHostException.class, filterHostName(epoint.toString())); + throwException(UnknownHostException.class, filterSocketInfo(epoint.toString())); connectV4(in, out, epoint, deadlineMillis); return; } @@ -351,7 +351,7 @@ protected void connect(SocketAddress endpoint, int timeout) throws IOException { // SOCKS Protocol version 4 doesn't know how to deal with // DOMAIN type of addresses (unresolved addresses here) if (epoint.isUnresolved()) - throwException(UnknownHostException.class, filterHostName(epoint.toString())); + throwException(UnknownHostException.class, filterSocketInfo(epoint.toString())); connectV4(in, out, epoint, deadlineMillis); return; } diff --git a/src/java.base/share/classes/java/net/URI.java b/src/java.base/share/classes/java/net/URI.java index 0d9415bf6a2d7..b22e2d6d94b78 100644 --- a/src/java.base/share/classes/java/net/URI.java +++ b/src/java.base/share/classes/java/net/URI.java @@ -45,7 +45,7 @@ import jdk.internal.util.Exceptions; import sun.nio.cs.UTF_8; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterNetInfo; import static jdk.internal.util.Exceptions.throwURISyntaxException; /** @@ -2036,7 +2036,7 @@ private static void checkPath(String s, String scheme, String path) { if (scheme != null) { if (path != null && !path.isEmpty() && path.charAt(0) != '/') - throwURISyntaxException("%s", "Relative path in absolute URI", -1, filterHostName(s)); + throwURISyntaxException("%s", "Relative path in absolute URI", -1, filterNetInfo(s)); } } @@ -2992,14 +2992,14 @@ private class Parser { // -- Methods for throwing URISyntaxException in various ways -- private void fail(String reason) throws URISyntaxException { - throwURISyntaxException("%s", reason, -1, filterHostName(input)); + throwURISyntaxException("%s", reason, -1, filterNetInfo(input)); } private void fail(String reason, int p) throws URISyntaxException { - if (!Exceptions.enhancedHostExceptions()) { + if (!Exceptions.enhancedNetExceptions()) { p = -1; } - throwURISyntaxException("%s", reason, p, filterHostName(input)); + throwURISyntaxException("%s", reason, p, filterNetInfo(input)); } private void failExpecting(String expected, int p) diff --git a/src/java.base/share/classes/java/net/URL.java b/src/java.base/share/classes/java/net/URL.java index 170fd99cde1ea..0c2057a178f62 100644 --- a/src/java.base/share/classes/java/net/URL.java +++ b/src/java.base/share/classes/java/net/URL.java @@ -45,7 +45,7 @@ import jdk.internal.misc.VM; import sun.net.util.IPAddressUtil; import static jdk.internal.util.Exceptions.throwURISyntaxException; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterNetInfo; /** * Class {@code URL} represents a Uniform Resource @@ -1171,7 +1171,7 @@ public URI toURI() throws URISyntaxException { if (authority != null && isBuiltinStreamHandler(handler)) { String s = IPAddressUtil.checkAuthority(this); if (s != null) - throwURISyntaxException("%s", s, -1, filterHostName(authority)); + throwURISyntaxException("%s", s, -1, filterNetInfo(authority)); } return uri; } diff --git a/src/java.base/share/classes/java/net/URLStreamHandler.java b/src/java.base/share/classes/java/net/URLStreamHandler.java index ed225a6061bc7..519f0f33a07f8 100644 --- a/src/java.base/share/classes/java/net/URLStreamHandler.java +++ b/src/java.base/share/classes/java/net/URLStreamHandler.java @@ -31,7 +31,7 @@ import sun.net.util.IPAddressUtil; import static jdk.internal.util.Exceptions.throwException; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterNetInfo; /** * The abstract class {@code URLStreamHandler} is the common @@ -209,7 +209,7 @@ protected void parseURL(URL u, String spec, int start, int limit) { if (!IPAddressUtil. isIPv6LiteralAddress(host.substring(1, ind))) { throwException(IllegalArgumentException.class, "Invalid host%s", - filterHostName(host).prefixWith(": ")); + filterNetInfo(host).prefixWith(": ")); } port = -1 ; @@ -223,12 +223,12 @@ protected void parseURL(URL u, String spec, int start, int limit) { } } else { throwException(IllegalArgumentException.class, "Invalid authority field%s", - filterHostName(authority).prefixWith(": ")); + filterNetInfo(authority).prefixWith(": ")); } } } else { throwException(IllegalArgumentException.class, "Invalid authority field%s", - filterHostName(authority).prefixWith(": ")); + filterNetInfo(authority).prefixWith(": ")); } } else { ind = host.indexOf(':'); diff --git a/src/java.base/share/classes/java/security/doc-files/security-related-system-properties.html b/src/java.base/share/classes/java/security/doc-files/security-related-system-properties.html new file mode 100644 index 0000000000000..a6d338d653c3e --- /dev/null +++ b/src/java.base/share/classes/java/security/doc-files/security-related-system-properties.html @@ -0,0 +1,194 @@ + + + + + + Security-Related System Properties + + + +

Security-Related System Properties

+

+ There are several system properties used to + alter the mechanisms and behavior of the various classes of the + java.security package. Some are checked only once at startup of the VM, + and therefore are best set using the -D option of the java command, + while others have a more dynamic nature and can also be changed using + the System.setProperty() API. +

+ +

Debug

+

{@systemProperty java.security.debug}

+

To monitor security access, you can set the java.security.debug system property, + which determines what trace messages are printed during execution. + To view security properties, security providers, and TLS-related settings, + specify the -XshowSettings:security option in the java command. + You can enable debugging in JGSS and other related technologies with various system properties or environment variables. + The following table lists java.security.debug options table:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Security Debug Options
OptionDescription
allTurn on all the debugging options
certpathTurns on debugging for the PKIX CertPathValidator and CertPathBuilder implementations. Use the ocsp option with the certpath option for OCSP protocol tracing. A hexadecimal dump of the OCSP request and response bytes is displayed. + You can use the following options with the certpath option: +
    +
  • ocsp: Dump OCSP protocol exchanges
  • +
  • verbose: Print additional debugging information
  • +
+
configfileJAAS (Java Authentication and Authorization Service) configuration file loading
configparserJAAS configuration file parsing
gssloginconfigJava GSS (Generic Security Services) login configuration file debugging
jarJAR file verification
jcaJCA engine class debugging
keystoreKeystore debugging
logincontextLoginContext results
pcscJava Smart Card I/O and SunPCSC provider debugging
pkcs11PKCS11 session manager debugging
pkcs11keystorePKCS11 KeyStore debugging
pkcs12PKCS12 KeyStore debugging
propertiesjava.security configuration file debugging
providerSecurity provider debugging The following options can be used with the provider option: + engine=(engines) : The output is displayed only for a specified list of JCA engines. + The supported values for (engines) are: +
    +
  • Cipher
  • +
  • KeyAgreement
  • +
  • KeyGenerator
  • +
  • KeyPairGenerator
  • +
  • KeyStore
  • +
  • Mac
  • +
  • MessageDigest
  • +
  • SecureRandom
  • +
  • Signature
  • +
+
sclPermissions that SecureClassLoader assigns
securerandomSecureRandom debugging
sunpkcs11SunPKCS11 provider debugging
+threadPrint thread and caller information
+timestampPrint timestamp information
tsTimestamping debugging
x509X.509 certificate debugging. You can use the following option with X.509 +
    +
  • ava: Embed non-printable/non-escaped characters in AVA components as hex strings
  • +
+
+ + \ No newline at end of file diff --git a/src/java.base/share/classes/jdk/internal/util/Exceptions.java b/src/java.base/share/classes/jdk/internal/util/Exceptions.java index 9ea532053ba8b..83859bd9130b9 100644 --- a/src/java.base/share/classes/jdk/internal/util/Exceptions.java +++ b/src/java.base/share/classes/jdk/internal/util/Exceptions.java @@ -44,10 +44,6 @@ * of the same exception type with an "enhanced" message * description. * - * If the system/security property "jdk.includeInExceptions" is not - * set or does not contain the category hostInfo, - * then the original exception is returned. - * * Code using this mechanism should use one of the static throwException * methods below to generate and throw the exception in one method. * exception() methods are also provided to generate an exception which @@ -55,28 +51,22 @@ * can generate a formatted (enhanced or restricted) string only. * * The SensitiveInfo objects should be generated with one of the following: - * public static SensitiveInfo filterHostName(String host) + * public static SensitiveInfo filterLookupInfo(String host) + * public static SensitiveInfo filterSocketInfo(String host) + * public static SensitiveInfo filterNetInfo(String host) * public static SensitiveInfo filterJarName(String name) * public static SensitiveInfo filterUserName(String name) */ public final class Exceptions { private Exceptions() {} - private static volatile boolean enhancedHostExceptionText; + private static volatile boolean enhancedSocketExceptionText; + private static volatile boolean enhancedNetExceptionText; + private static volatile boolean enhancedLookupExceptionText; private static volatile boolean enhancedUserExceptionText; private static volatile boolean enhancedJarExceptionText; private static volatile boolean initialized = false; - /** - * Suffix added to all exception messages when enhanced exceptions are disabled - */ - private static final String ENH_DISABLED_MSG = "[enhanced exceptions disabled]"; - - - public static String enhancedDisabledMsg() { - return ENH_DISABLED_MSG; - } - /** * Base class for generating exception messages that may * contain sensitive information which in certain contexts @@ -88,7 +78,7 @@ public static String enhancedDisabledMsg() { * Sub-class for any new category that needs to be independently * controlled. Consider using a unique value for the * SecurityProperties.includedInExceptions(String value) mechanism - * Current values defined are "hostInfo", "jar" and "userInfo" + * Current values defined are "socket", "jar" and "userInfo" * New code can also piggy back on existing categories * * A SensitiveInfo contains the following components @@ -199,14 +189,37 @@ public static URISyntaxException throwURISyntaxException(String format, String a throw ex; } - static final class HostInfo extends SensitiveInfo { - public HostInfo(String host) { + static final class SocketInfo extends SensitiveInfo { + public SocketInfo(String host) { + super(host); + } + @Override + public String output() { + setup(); + return super.output(enhancedSocketExceptionText); + } + } + + static final class NetInfo extends SensitiveInfo { + public NetInfo(String host) { + super(host); + } + @Override + public String output() { + setup(); + return super.output(enhancedNetExceptionText); + } + } + + + static final class LookupInfo extends SensitiveInfo { + public LookupInfo(String host) { super(host); } @Override public String output() { setup(); - return super.output(enhancedHostExceptionText); + return super.output(enhancedLookupExceptionText); } } @@ -258,8 +271,16 @@ static String trim(String s) { return sb.toString(); } - public static SensitiveInfo filterHostName(String host) { - return new HostInfo(host); + public static SensitiveInfo filterSocketInfo(String host) { + return new SocketInfo(host); + } + + public static SensitiveInfo filterNetInfo(String host) { + return new NetInfo(host); + } + + public static SensitiveInfo filterLookupInfo(String host) { + return new LookupInfo(host); } public static SensitiveInfo filterJarName(String name) { @@ -285,8 +306,7 @@ public static String formatMsg(String format, SensitiveInfo... infos) { if (!info.enhanced()) enhanced = false; } - return trim(String.format(format, (Object[])args) + - (enhanced ? "" : " " + ENH_DISABLED_MSG)); + return trim(String.format(format, (Object[])args)); } /** @@ -300,15 +320,32 @@ private static String formatMsg(SensitiveInfo info) { public static void setup() { if (initialized || !VM.isBooted()) return; - enhancedHostExceptionText = SecurityProperties.includedInExceptions("hostInfo"); + // for compatibility + var hostCompatFlag = SecurityProperties.includedInExceptions("hostInfo"); + enhancedSocketExceptionText = SecurityProperties.includedInExceptions("socket") + | hostCompatFlag; + enhancedNetExceptionText = SecurityProperties.includedInExceptions("net") + | hostCompatFlag; + enhancedLookupExceptionText = SecurityProperties.includedInExceptions("addressLookup") + | hostCompatFlag; enhancedUserExceptionText = SecurityProperties.includedInExceptions("userInfo"); enhancedJarExceptionText = SecurityProperties.INCLUDE_JAR_NAME_IN_EXCEPTIONS; initialized = true; } - public static boolean enhancedHostExceptions() { + public static boolean enhancedNetExceptions() { + setup(); + return enhancedNetExceptionText; + } + + public static boolean enhancedSocketExceptions() { + setup(); + return enhancedSocketExceptionText; + } + + public static boolean enhancedLookupExceptions() { setup(); - return enhancedHostExceptionText; + return enhancedLookupExceptionText; } /** @@ -320,8 +357,8 @@ public static IOException ioException(IOException e, SocketAddress addr) { if (addr == null) { return e; } - if (!enhancedHostExceptionText) { - return create(e, e.getMessage() + " " + ENH_DISABLED_MSG); + if (!enhancedSocketExceptionText) { + return create(e, e.getMessage()); } if (addr instanceof UnixDomainSocketAddress) { return ofUnixDomain(e, (UnixDomainSocketAddress)addr); diff --git a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java index dbab94dcd9dbb..d4021f85ffbd4 100644 --- a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java +++ b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java @@ -38,7 +38,7 @@ import java.util.concurrent.ConcurrentHashMap; import static jdk.internal.util.Exceptions.exception; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterNetInfo; public class IPAddressUtil { private static final int INADDR4SZ = 4; @@ -165,7 +165,7 @@ public static byte[] validateNumericFormatV4(String src, boolean throwIAE) { */ public static IllegalArgumentException invalidIpAddressLiteral(String src) { return exception(IllegalArgumentException.class, "Invalid IP address literal%s", - filterHostName(src).prefixWith(": ")); + filterNetInfo(src).prefixWith(": ")); } /* diff --git a/src/java.base/share/classes/sun/net/www/ParseUtil.java b/src/java.base/share/classes/sun/net/www/ParseUtil.java index a5bfdb18bf138..e2e3c8635149c 100644 --- a/src/java.base/share/classes/sun/net/www/ParseUtil.java +++ b/src/java.base/share/classes/sun/net/www/ParseUtil.java @@ -40,7 +40,7 @@ import java.util.HexFormat; import sun.nio.cs.UTF_8; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterNetInfo; import static jdk.internal.util.Exceptions.throwURISyntaxException; /** @@ -505,7 +505,7 @@ private static void checkPath(String s, String scheme, String path) if (scheme != null) { if (path != null && !path.isEmpty() && path.charAt(0) != '/') throwURISyntaxException("%s", "Relative path in absolute URI", - -1, filterHostName(s)); + -1, filterNetInfo(s)); } } diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java index 8d9aa9c77c425..aae88452ba0bf 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java @@ -54,7 +54,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import static jdk.internal.util.Exceptions.throwException; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterNetInfo; /** * A multicast datagram socket based on a datagram channel. @@ -493,7 +493,7 @@ public void setInterface(InetAddress inf) throws SocketException { if (ni == null) { String address = inf.getHostAddress(); throwException(SocketException.class, "No network interface found with address %s", - filterHostName(address)); + filterNetInfo(address)); } synchronized (outgoingInterfaceLock) { // set interface and update cached values diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index 5f6f0b33eb508..d17f69b59e0f4 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -1282,20 +1282,19 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # in the categories above. This include URL/URI, NetworkInterface # and URLConnection among others. # +# hostInfo - Special value which signifies the three categories above combined +# (socket, addressLookup, net). This is provided for compatibility +# with previous releases. +# # jar - enables more detailed information in the IOExceptions thrown # by classes in the java.util.jar package # # userInfo - enables more detailed information in exceptions which may contain # user identity information # -# For compatibility with previous releases, the special value hostInfo encompasses -# all the network related categories (socket,addressLookup,net) # The property setting in this file can be overridden by a system property of # the same name, with the same syntax and possible values. # -# When enhanced exceptions are disabled the following string is appended -# to each restricted exception message "[enhanced exceptions disabled]" -# #jdk.includeInExceptions=hostInfo,jar,userInfo # # The default setting diff --git a/src/java.base/share/native/libnet/net_util.c b/src/java.base/share/native/libnet/net_util.c index 346d79d5563b7..0c47bfffe4b15 100644 --- a/src/java.base/share/native/libnet/net_util.c +++ b/src/java.base/share/native/libnet/net_util.c @@ -109,7 +109,7 @@ int getEnhancedExceptionsAllowed(JNIEnv *env) { } cls = (*env)->FindClass(env, "jdk/internal/util/Exceptions"); CHECK_NULL_THROW_ERROR(cls); - fid = (*env)->GetStaticFieldID(env, cls, "enhancedHostExceptionText", "Z"); + fid = (*env)->GetStaticFieldID(env, cls, "enhancedLookupExceptionText", "Z"); CHECK_NULL_THROW_ERROR(fid); enhancedExceptionsAllowed = (*env)->GetStaticBooleanField(env, cls, fid); enhancedExceptionsInitialized = 1; diff --git a/src/java.base/share/native/libnet/net_util.h b/src/java.base/share/native/libnet/net_util.h index 123aca2d98f66..89537a7f47d04 100644 --- a/src/java.base/share/native/libnet/net_util.h +++ b/src/java.base/share/native/libnet/net_util.h @@ -115,12 +115,6 @@ JNIEXPORT jint JNICALL ipv6_available(); JNIEXPORT jint JNICALL reuseport_available(); -/** - * Message appended to exception texts when enhanced exceptions disabled - * Must be kept consistent with Java implementation - */ -#define ENH_DISABLED_MSG "[enhanced exceptions disabled]" - /** * This function will fill a SOCKETADDRESS structure from an InetAddress * object. diff --git a/src/java.base/unix/native/libnet/net_util_md.c b/src/java.base/unix/native/libnet/net_util_md.c index 0154036be5896..0d345fc2617a7 100644 --- a/src/java.base/unix/native/libnet/net_util_md.c +++ b/src/java.base/unix/native/libnet/net_util_md.c @@ -192,7 +192,7 @@ void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, if (enhancedExceptions) { size = strlen(hostname); } else { - size = strlen(ENH_DISABLED_MSG) + 1; + size = 0; } size += strlen(error_string) + 3; @@ -202,7 +202,7 @@ void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, if (enhancedExceptions) { snprintf(buf, size, "%s: %s", hostname, error_string); } else { - snprintf(buf, size, " %s %s", error_string, ENH_DISABLED_MSG); + snprintf(buf, size, " %s", error_string); } s = JNU_NewStringPlatform(env, buf); if (s != NULL) { diff --git a/src/java.base/windows/native/libnet/Inet4AddressImpl.c b/src/java.base/windows/native/libnet/Inet4AddressImpl.c index 5f235a85338d5..0ef0cae5be781 100644 --- a/src/java.base/windows/native/libnet/Inet4AddressImpl.c +++ b/src/java.base/windows/native/libnet/Inet4AddressImpl.c @@ -90,7 +90,7 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, // report error NET_ThrowByNameWithLastError( env, "java/net/UnknownHostException", - getEnhancedExceptionsAllowed(env) ? hostname : ENH_DISABLED_MSG); + getEnhancedExceptionsAllowed(env) ? hostname : ""); goto cleanupAndReturn; } else { int i = 0; diff --git a/src/java.base/windows/native/libnet/Inet6AddressImpl.c b/src/java.base/windows/native/libnet/Inet6AddressImpl.c index b3d10a33fa01b..0281e2ddecb73 100644 --- a/src/java.base/windows/native/libnet/Inet6AddressImpl.c +++ b/src/java.base/windows/native/libnet/Inet6AddressImpl.c @@ -84,7 +84,7 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, if (error) { // report error NET_ThrowByNameWithLastError(env, "java/net/UnknownHostException", - getEnhancedExceptionsAllowed(env) ? hostname : ENH_DISABLED_MSG); + getEnhancedExceptionsAllowed(env) ? hostname : ""); goto cleanupAndReturn; } else { int i = 0, inetCount = 0, inet6Count = 0, inetIndex = 0, diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java index b294799a35fc3..5968bfb99de14 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java @@ -39,7 +39,7 @@ import static jdk.internal.net.http.common.Utils.isValidName; import static jdk.internal.net.http.common.Utils.isValidValue; import static jdk.internal.net.http.common.Utils.newIAE; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterNetInfo; import static jdk.internal.util.Exceptions.throwException; public class HttpRequestBuilderImpl implements HttpRequest.Builder { @@ -85,7 +85,7 @@ static void checkURI(URI uri) { } if (uri.getHost() == null) { throwException(IllegalArgumentException.class, "unsupported URI %s", - filterHostName(uri.toString())); + filterNetInfo(uri.toString())); } } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java index b7507f8aaa634..c8e8f1f9d392e 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java @@ -192,11 +192,10 @@ static boolean allowedInToken(char c) { static final UncheckedIOException unchecked(ResponseInfo rinfo, String msg) { String s; - if (Exceptions.enhancedHostExceptions()) { + if (Exceptions.enhancedNetExceptions()) { s = String.format("%s in response [%d, %s]", msg, rinfo.statusCode(), rinfo.headers()); } else { - s = String.format("%s in response [%d] %s", msg, rinfo.statusCode(), - Exceptions.enhancedDisabledMsg()); + s = String.format("%s in response [%d]", msg, rinfo.statusCode()); } return new UncheckedIOException(new IOException(s)); } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java index 1bdf39daccc7a..017bc329bfb30 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java @@ -61,7 +61,7 @@ import static java.lang.String.format; import static jdk.internal.net.http.common.Utils.isValidName; import static jdk.internal.net.http.common.Utils.stringOf; -import static jdk.internal.util.Exceptions.filterHostName; +import static jdk.internal.util.Exceptions.filterNetInfo; import static jdk.internal.util.Exceptions.throwException; public class OpeningHandshake { @@ -339,10 +339,10 @@ private static URI checkURI(URI uri) { throw illegal("invalid URI scheme: " + scheme); if (uri.getHost() == null) throwException(IllegalArgumentException.class, "URI must contain a host%s", - filterHostName(uri.toString()).prefixWith(": ")); + filterNetInfo(uri.toString()).prefixWith(": ")); if (uri.getFragment() != null) throwException(IllegalArgumentException.class, "URI must not contain a fragment%s", - filterHostName(uri.toString()).prefixWith(": ")); + filterNetInfo(uri.toString()).prefixWith(": ")); return uri; } diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java index 0a52105f88db7..b387c6df998b8 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java @@ -38,7 +38,7 @@ public class JWebServer { private static final String DEFAULT_JWEBSERVER_MAX_CONNECTIONS = "200"; private static final String SYS_PROP_ENHANCED_EXCEP = "jdk.includeInExceptions"; - private static final String DEFAULT_ENHANCED_EXCEP = "hostInfo"; + private static final String DEFAULT_ENHANCED_EXCEP = "net"; /** * This constructor should never be called. */ diff --git a/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java b/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java index 353309c16545c..bbf222e9d5ac9 100644 --- a/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java +++ b/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java @@ -28,7 +28,7 @@ * @bug 8207846 8208691 * @summary Test the default setting of the jdk.net.includeInExceptions * security property - * @comment In OpenJDK, this property is empty by default and on purpose. + * @comment In OpenJDK, this property has value "addressLookup,net" by default * This test assures the default is not changed. * @run main TestJDKIncludeInExceptions */ @@ -36,9 +36,9 @@ public class TestJDKIncludeInExceptions { public static void main(String args[]) throws Exception { String incInExc = Security.getProperty("jdk.includeInExceptions"); - if (incInExc != null) { + if (incInExc == null || !incInExc.equals("addressLookup,net")) { throw new RuntimeException("Test failed: default value of " + - "jdk.includeInExceptions security property is not null: " + + "jdk.includeInExceptions security property does not have expected value: " + incInExc); } } From d94e95dcbbe91f6e66ff566d54c97a3af13fffb6 Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Wed, 5 Mar 2025 08:07:54 +0000 Subject: [PATCH 04/22] update --- src/java.base/share/conf/security/java.security | 6 ++++-- .../JavaDotSecurity/TestJDKIncludeInExceptions.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index d17f69b59e0f4..ae75f3a63dbd7 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -1297,8 +1297,10 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # #jdk.includeInExceptions=hostInfo,jar,userInfo # -# The default setting -jdk.includeInExceptions=addressLookup,net +# If the property is set to an empty string, then this is the most restricted +# setting with all categories disabled. The following is the default +# (out of the box) ssetting. +jdk.includeInExceptions=addressLookup,net,userInfo # # Disabled mechanisms for the Simple Authentication and Security Layer (SASL) # diff --git a/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java b/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java index bbf222e9d5ac9..67b15e80ba4fe 100644 --- a/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java +++ b/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java @@ -36,7 +36,7 @@ public class TestJDKIncludeInExceptions { public static void main(String args[]) throws Exception { String incInExc = Security.getProperty("jdk.includeInExceptions"); - if (incInExc == null || !incInExc.equals("addressLookup,net")) { + if (incInExc == null || !incInExc.equals("addressLookup,net,userInfo")) { throw new RuntimeException("Test failed: default value of " + "jdk.includeInExceptions security property does not have expected value: " + incInExc); From 23f9ee0cb9278f7f7651b68a30904bf04d2a1636 Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Wed, 5 Mar 2025 08:26:31 +0000 Subject: [PATCH 05/22] moved test --- test/jdk/sun/net/util/ExceptionsTest.java | 173 ++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 test/jdk/sun/net/util/ExceptionsTest.java diff --git a/test/jdk/sun/net/util/ExceptionsTest.java b/test/jdk/sun/net/util/ExceptionsTest.java new file mode 100644 index 0000000000000..8cac3db70ee47 --- /dev/null +++ b/test/jdk/sun/net/util/ExceptionsTest.java @@ -0,0 +1,173 @@ +/* + * 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. + */ +import java.io.IOException; +import java.net.InetAddress; +import java.util.Arrays; +import jdk.internal.util.Exceptions; +import jdk.internal.util.Exceptions.SensitiveInfo; +import static jdk.internal.util.Exceptions.formatMsg; +import static jdk.internal.util.Exceptions.filterNetInfo; +import static jdk.internal.util.Exceptions.enhancedLookupExceptions; +import static jdk.internal.util.Exceptions.enhancedNetExceptions; + +/* + * @test + * @bug 8348986 + * @summary Improve coverage of enhanced exception messages + * @modules java.base/jdk.internal.util + * @run main/othervm -Djdk.includeInExceptions=hostInfo ExceptionsTest + * @run main/othervm ExceptionsTest + * @run main/othervm -Djdk.includeInExceptions=userInfo ExceptionsTest + * @run main/othervm -Djdk.net.hosts.file=does.not.exist -Djdk.includeInExceptions=userInfo ExceptionsTest + * @run main/othervm -Djdk.net.hosts.file=does.not.exist -Djdk.includeInExceptions=hostInfo ExceptionsTest + */ +public class ExceptionsTest { + + static boolean netEnabled() { + System.out.printf("netEnabled = %b\n", enhancedNetExceptions()); + return enhancedNetExceptions(); + } + + static boolean dnsEnabled() { + System.out.printf("dnsEnabled = %b\n", enhancedLookupExceptions()); + return enhancedLookupExceptions(); + } + + static boolean hostFileEnabled() { + return System.getProperty("jdk.net.hosts.file", "").length() > 0; + } + + static String[][][] tests = { + // + // If a format argument is of the form ".pre(xxx)" or ".suf(yyy)", then that is + // interpreted as a .prefixWith("xxx") or .suffixWith("yyy") call to the preceding + // argument. .rep() signifies .replaceWith() + // + // Number of elements in array + // --------------------------- + // 1 N 2 + // + // Format string args to format Enhanced o/p non-enhanced o/p + // + /* 1 */ {{"foo: %s bar"}, {"abc"}, {"foo: abc bar", "foo: bar"}}, + /* 2 */ {{"foo: %s bar"}, {"a", "b"}, {"foo: a bar", "foo: bar"}}, + /* 3 */ {{"foo: %s bar"}, {null}, {"foo: null bar", "foo: bar"}}, + /* 4 */ {{"foo: %s bar"}, {""}, {"foo: bar", "foo: bar"}}, + /* 5 */ {{"%s foo: %s bar"}, {"a", "b"}, {"a foo: b bar", "foo: bar"}}, + /* 6 */ {{"foo: %s bar %s"}, {"a", "b"}, {"foo: a bar b", "foo: bar"}}, + /* 7 */ {{"foo: %s bar %s"}, {"abc", "def"}, {"foo: abc bar def", "foo: bar"}}, + /* 8 */ {{"%s bar %s"}, {"abc", ".pre(foo: )", "def"}, {"foo: abc bar def", "bar"}}, + /* 9 */ {{"%s baz"}, {"abc", ".suf(: bar)"}, {"abc: bar baz", "baz"}}, + /* 10 */ {{"%s baz"}, {"abc", ".suf(: bar)" + , ".rep(bob)"}, {"abc: bar baz", "bob baz"}} + }; + + + static void dnsTest() { + String host = "fub.z.a.bar.foo"; + try { + var addr = InetAddress.getByName(host); + } catch (IOException e) { + if (!dnsEnabled() && e.toString().contains(host)) + throw new RuntimeException("Name lookup failed"); + } + } + + static void hostFileTest() { + String result1 = "Unable to resolve host www.rte.ie as hosts file does.not.exist not found"; + String result2 = "Unable to resolve host as hosts file " + + "from ${jdk.net.hosts.file} system property not found"; + + try { + var a = InetAddress.getByName("www.rte.ie"); + } catch (IOException e) { + if (dnsEnabled() && !e.toString().contains(result1)) { + System.out.println("Lookup failed: " + e.toString()); + throw new RuntimeException("Name lookup failed"); + } + if (!dnsEnabled() && !e.toString().contains(result2)) { + System.out.println("Lookup failed: " + e.toString()); + throw new RuntimeException("Name lookup failed"); + } + } + } + + + final static String PRE = ".pre("; + final static String SUF = ".suf("; + final static String REP = ".rep("; + + static SensitiveInfo[] getArgs(String[] args) { + SensitiveInfo[] sa = new SensitiveInfo[args.length]; + + int index = 0; + for (String s : args) { + if (s != null && s.startsWith(PRE)) { + var preArg = s.substring(PRE.length(), s.indexOf(')')); + sa[index-1] = sa[index-1].prefixWith(preArg); + } else if (s != null && s.startsWith(SUF)) { + var sufArg = s.substring(SUF.length(), s.indexOf(')')); + sa[index-1] = sa[index-1].suffixWith(sufArg); + } else if (s != null && s.startsWith(REP)) { + var repArg = s.substring(REP.length(), s.indexOf(')')); + sa[index-1] = sa[index-1].replaceWith(repArg); + } else { + sa[index++] = filterNetInfo(s); + } + } + return Arrays.copyOf(sa, index); + } + + public static void main(String[] a) { + if (!hostFileEnabled()) { + dnsTest(); + } else { + hostFileTest(); + return; + } + + int count = 1; + for (String[][] test : tests) { + String format = test[0][0]; + String expectedEnhanced = test[2][0]; + String expectedNormal = test[2][1]; + SensitiveInfo[] args = getArgs(test[1]); + + String output = formatMsg(format, args); + if (netEnabled()) { + if (!output.equals(expectedEnhanced)) { + var msg = String.format("FAIL %d: got: \"%s\" Expected: \"%s\"", count, + output, expectedEnhanced); + throw new RuntimeException(msg); + } + } else { + if (!output.equals(expectedNormal)) { + var msg = String.format("FAIL %d: got: \"%s\" Expected: \"%s\"", count, + output, expectedNormal); + throw new RuntimeException(msg); + } + } + count++; + } + } +} From fa25ccc4874d980832d7f0279df99b1f0582e890 Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Wed, 5 Mar 2025 08:32:02 +0000 Subject: [PATCH 06/22] whitespace --- .../share/classes/jdk/internal/util/Exceptions.java | 2 +- src/java.base/share/conf/security/java.security | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/util/Exceptions.java b/src/java.base/share/classes/jdk/internal/util/Exceptions.java index 83859bd9130b9..87981fa15d166 100644 --- a/src/java.base/share/classes/jdk/internal/util/Exceptions.java +++ b/src/java.base/share/classes/jdk/internal/util/Exceptions.java @@ -322,7 +322,7 @@ public static void setup() { return; // for compatibility var hostCompatFlag = SecurityProperties.includedInExceptions("hostInfo"); - enhancedSocketExceptionText = SecurityProperties.includedInExceptions("socket") + enhancedSocketExceptionText = SecurityProperties.includedInExceptions("socket") | hostCompatFlag; enhancedNetExceptionText = SecurityProperties.includedInExceptions("net") | hostCompatFlag; diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index ae75f3a63dbd7..c2de3a63ef32a 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -1254,10 +1254,10 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # # Enhanced exception message information # -# Exception messages may include potentially sensitive information such as file +# Exception messages may include potentially sensitive information such as file # names, host names, or port numbers. By default, socket related exceptions -# have this information restricted (meaning the sensitive details are removed). -# This property can be used to relax this restriction or to place further +# have this information restricted (meaning the sensitive details are removed). +# This property can be used to relax this restriction or to place further # restrictions on other categories, defined below. The property # accepts one or more comma separated values, each of which represents a # category of enhanced exception message information to enable. Values are @@ -1275,7 +1275,7 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # java.nio.channels package will contain enhanced exception # message information # -# addressLookup - UnknownHostExceptions and other exceptions thrown by the +# addressLookup - UnknownHostExceptions and other exceptions thrown by the # java.net.InetAddress class # # net - All other exceptions thrown in networking code not included @@ -1283,7 +1283,7 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # and URLConnection among others. # # hostInfo - Special value which signifies the three categories above combined -# (socket, addressLookup, net). This is provided for compatibility +# (socket, addressLookup, net). This is provided for compatibility # with previous releases. # # jar - enables more detailed information in the IOExceptions thrown @@ -1298,7 +1298,7 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep #jdk.includeInExceptions=hostInfo,jar,userInfo # # If the property is set to an empty string, then this is the most restricted -# setting with all categories disabled. The following is the default +# setting with all categories disabled. The following is the default # (out of the box) ssetting. jdk.includeInExceptions=addressLookup,net,userInfo # From c4419860f449e29cc4cf4303996fb683502b8f7e Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Wed, 5 Mar 2025 10:02:29 +0000 Subject: [PATCH 07/22] remove file added by mistake --- .../security-related-system-properties.html | 194 ------------------ 1 file changed, 194 deletions(-) delete mode 100644 src/java.base/share/classes/java/security/doc-files/security-related-system-properties.html diff --git a/src/java.base/share/classes/java/security/doc-files/security-related-system-properties.html b/src/java.base/share/classes/java/security/doc-files/security-related-system-properties.html deleted file mode 100644 index a6d338d653c3e..0000000000000 --- a/src/java.base/share/classes/java/security/doc-files/security-related-system-properties.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - Security-Related System Properties - - - -

Security-Related System Properties

-

- There are several system properties used to - alter the mechanisms and behavior of the various classes of the - java.security package. Some are checked only once at startup of the VM, - and therefore are best set using the -D option of the java command, - while others have a more dynamic nature and can also be changed using - the System.setProperty() API. -

- -

Debug

-

{@systemProperty java.security.debug}

-

To monitor security access, you can set the java.security.debug system property, - which determines what trace messages are printed during execution. - To view security properties, security providers, and TLS-related settings, - specify the -XshowSettings:security option in the java command. - You can enable debugging in JGSS and other related technologies with various system properties or environment variables. - The following table lists java.security.debug options table:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Security Debug Options
OptionDescription
allTurn on all the debugging options
certpathTurns on debugging for the PKIX CertPathValidator and CertPathBuilder implementations. Use the ocsp option with the certpath option for OCSP protocol tracing. A hexadecimal dump of the OCSP request and response bytes is displayed. - You can use the following options with the certpath option: -
    -
  • ocsp: Dump OCSP protocol exchanges
  • -
  • verbose: Print additional debugging information
  • -
-
configfileJAAS (Java Authentication and Authorization Service) configuration file loading
configparserJAAS configuration file parsing
gssloginconfigJava GSS (Generic Security Services) login configuration file debugging
jarJAR file verification
jcaJCA engine class debugging
keystoreKeystore debugging
logincontextLoginContext results
pcscJava Smart Card I/O and SunPCSC provider debugging
pkcs11PKCS11 session manager debugging
pkcs11keystorePKCS11 KeyStore debugging
pkcs12PKCS12 KeyStore debugging
propertiesjava.security configuration file debugging
providerSecurity provider debugging The following options can be used with the provider option: - engine=(engines) : The output is displayed only for a specified list of JCA engines. - The supported values for (engines) are: -
    -
  • Cipher
  • -
  • KeyAgreement
  • -
  • KeyGenerator
  • -
  • KeyPairGenerator
  • -
  • KeyStore
  • -
  • Mac
  • -
  • MessageDigest
  • -
  • SecureRandom
  • -
  • Signature
  • -
-
sclPermissions that SecureClassLoader assigns
securerandomSecureRandom debugging
sunpkcs11SunPKCS11 provider debugging
+threadPrint thread and caller information
+timestampPrint timestamp information
tsTimestamping debugging
x509X.509 certificate debugging. You can use the following option with X.509 -
    -
  • ava: Embed non-printable/non-escaped characters in AVA components as hex strings
  • -
-
- - \ No newline at end of file From 074da251a22ffcbd011e91e91362a67ba8c37e4b Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Thu, 6 Mar 2025 10:41:44 +0000 Subject: [PATCH 08/22] doc + copyright update --- .../classes/jdk/internal/util/Exceptions.java | 22 ++++++++++++------- .../share/conf/security/java.security | 7 +++--- .../simpleserver/CommandLineNegativeTest.java | 2 +- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/util/Exceptions.java b/src/java.base/share/classes/jdk/internal/util/Exceptions.java index 87981fa15d166..c49ef0ca57ec4 100644 --- a/src/java.base/share/classes/jdk/internal/util/Exceptions.java +++ b/src/java.base/share/classes/jdk/internal/util/Exceptions.java @@ -39,10 +39,8 @@ import jdk.internal.misc.VM; /** - * Contains static utility methods which take an Exception - * and return either the same exception or a new instance - * of the same exception type with an "enhanced" message - * description. + * Contains static utility methods which can filter exception + * message strings for sensitive information. * * Code using this mechanism should use one of the static throwException * methods below to generate and throw the exception in one method. @@ -50,10 +48,13 @@ * then be modified before being thrown or used. Lastly, formatMsg() * can generate a formatted (enhanced or restricted) string only. * + * The methods above take variable numbers of SensitiveInfo objects + * as parameters which contain the text that may have to be filtered. + * * The SensitiveInfo objects should be generated with one of the following: * public static SensitiveInfo filterLookupInfo(String host) - * public static SensitiveInfo filterSocketInfo(String host) - * public static SensitiveInfo filterNetInfo(String host) + * public static SensitiveInfo filterSocketInfo(String s) + * public static SensitiveInfo filterNetInfo(String s) * public static SensitiveInfo filterJarName(String name) * public static SensitiveInfo filterUserName(String name) */ @@ -78,7 +79,10 @@ private Exceptions() {} * Sub-class for any new category that needs to be independently * controlled. Consider using a unique value for the * SecurityProperties.includedInExceptions(String value) mechanism - * Current values defined are "socket", "jar" and "userInfo" + * Current values defined are "socket", "jar", "userInfo" + * "net", "addressLookup". The value "hostInfo" exists for + * compatibility and is the same as the combination of + * "socket,addressLookup,net" * New code can also piggy back on existing categories * * A SensitiveInfo contains the following components @@ -122,7 +126,9 @@ public boolean enhanced() { } /** - * Implementation should call output(boolean) + * Implementation should call output(boolean flag) + * where flag contains the boolean value of whether + * the category is enabled or not. */ public abstract String output(); diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index c2de3a63ef32a..610b095e1e523 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -1295,11 +1295,10 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # The property setting in this file can be overridden by a system property of # the same name, with the same syntax and possible values. # -#jdk.includeInExceptions=hostInfo,jar,userInfo +# If the property is not set or set to an empty string, then this is the most +# restricted setting with all categories disabled. The following is the default +# (out of the box) setting, meaning these categories are not restricted. # -# If the property is set to an empty string, then this is the most restricted -# setting with all categories disabled. The following is the default -# (out of the box) ssetting. jdk.includeInExceptions=addressLookup,net,userInfo # # Disabled mechanisms for the Simple Authentication and Security Layer (SASL) diff --git a/test/jdk/com/sun/net/httpserver/simpleserver/CommandLineNegativeTest.java b/test/jdk/com/sun/net/httpserver/simpleserver/CommandLineNegativeTest.java index fc1c6eda5f12f..160ff09f38ec7 100644 --- a/test/jdk/com/sun/net/httpserver/simpleserver/CommandLineNegativeTest.java +++ b/test/jdk/com/sun/net/httpserver/simpleserver/CommandLineNegativeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 From 41d1ef827fb60adf816317a164a1d5f70465a220 Mon Sep 17 00:00:00 2001 From: Michael McMahon <70538289+Michael-Mc-Mahon@users.noreply.github.com> Date: Thu, 6 Mar 2025 12:29:40 +0000 Subject: [PATCH 09/22] Apply suggestions from code review from turbanoff review Co-authored-by: Andrey Turbanov --- src/java.base/share/classes/jdk/internal/util/Exceptions.java | 4 ++-- test/jdk/sun/net/util/ExceptionsTest.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/util/Exceptions.java b/src/java.base/share/classes/jdk/internal/util/Exceptions.java index c49ef0ca57ec4..33b016401cf1e 100644 --- a/src/java.base/share/classes/jdk/internal/util/Exceptions.java +++ b/src/java.base/share/classes/jdk/internal/util/Exceptions.java @@ -100,7 +100,7 @@ private Exceptions() {} * However, if a replacement is set, then when enhance == false * the output is the replacement string. */ - public static abstract class SensitiveInfo { + public abstract static class SensitiveInfo { String info, suffix, prefix, replacement; boolean enhanced; @@ -335,7 +335,7 @@ public static void setup() { enhancedLookupExceptionText = SecurityProperties.includedInExceptions("addressLookup") | hostCompatFlag; enhancedUserExceptionText = SecurityProperties.includedInExceptions("userInfo"); - enhancedJarExceptionText = SecurityProperties.INCLUDE_JAR_NAME_IN_EXCEPTIONS; + enhancedJarExceptionText = SecurityProperties.INCLUDE_JAR_NAME_IN_EXCEPTIONS; initialized = true; } diff --git a/test/jdk/sun/net/util/ExceptionsTest.java b/test/jdk/sun/net/util/ExceptionsTest.java index 8cac3db70ee47..a539d6ccad0f0 100644 --- a/test/jdk/sun/net/util/ExceptionsTest.java +++ b/test/jdk/sun/net/util/ExceptionsTest.java @@ -44,12 +44,12 @@ public class ExceptionsTest { static boolean netEnabled() { - System.out.printf("netEnabled = %b\n", enhancedNetExceptions()); + System.out.printf("netEnabled = %b\n", enhancedNetExceptions()); return enhancedNetExceptions(); } static boolean dnsEnabled() { - System.out.printf("dnsEnabled = %b\n", enhancedLookupExceptions()); + System.out.printf("dnsEnabled = %b\n", enhancedLookupExceptions()); return enhancedLookupExceptions(); } From c41146b0d29c91584f729dd42b510faa3d8332cc Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Thu, 10 Apr 2025 22:22:13 +0100 Subject: [PATCH 10/22] update to minimise code changes --- .../share/classes/java/net/HostPortrange.java | 11 ++-- .../classes/java/net/Inet4AddressImpl.java | 4 +- .../share/classes/java/net/Inet6Address.java | 7 ++- .../share/classes/java/net/InetAddress.java | 62 +++++++++---------- .../classes/java/net/NetworkInterface.java | 6 +- .../share/classes/java/net/Proxy.java | 10 +-- .../classes/java/net/SocketPermission.java | 12 ++-- .../classes/java/net/SocksSocketImpl.java | 6 +- src/java.base/share/classes/java/net/URI.java | 9 +-- src/java.base/share/classes/java/net/URL.java | 4 +- .../classes/java/net/URLStreamHandler.java | 16 ++--- .../classes/jdk/internal/util/Exceptions.java | 61 +----------------- .../classes/sun/net/util/IPAddressUtil.java | 6 +- .../share/classes/sun/net/www/ParseUtil.java | 6 +- .../sun/net/www/protocol/jar/Handler.java | 19 +++--- .../net/www/protocol/jar/JarFileFactory.java | 6 +- .../www/protocol/jar/JarURLConnection.java | 18 +++--- .../sun/net/www/protocol/jmod/Handler.java | 6 +- .../sun/nio/ch/DatagramSocketAdaptor.java | 6 +- .../share/conf/security/java.security | 4 +- .../sun/nio/fs/UnixUserPrincipals.java | 8 +-- .../unix/native/libnet/net_util_md.c | 17 ++--- .../sun/nio/fs/WindowsSecurityDescriptor.java | 6 +- .../sun/nio/fs/WindowsUserPrincipals.java | 11 ++-- .../net/http/HttpRequestBuilderImpl.java | 6 +- .../net/http/websocket/OpeningHandshake.java | 12 ++-- 26 files changed, 147 insertions(+), 192 deletions(-) diff --git a/src/java.base/share/classes/java/net/HostPortrange.java b/src/java.base/share/classes/java/net/HostPortrange.java index fa08ffc318d4a..a2e008fc6c964 100644 --- a/src/java.base/share/classes/java/net/HostPortrange.java +++ b/src/java.base/share/classes/java/net/HostPortrange.java @@ -30,7 +30,7 @@ import sun.net.util.IPAddressUtil; import static jdk.internal.util.Exceptions.filterNetInfo; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; /** * Parses a string containing a host/domain name and port range @@ -80,8 +80,9 @@ public int hashCode() { if (rb != -1) { hoststr = str.substring(1, rb); } else { - throwException(IllegalArgumentException.class, "invalid IPv6 address%s", - filterNetInfo(str).prefixWith(": ")); + throw new IllegalArgumentException( + formatMsg("invalid IPv6 address%s", + filterNetInfo(str).prefixWith(": "))); } int sep = str.indexOf(':', rb + 1); if (sep != -1 && str.length() > sep) { @@ -160,8 +161,8 @@ public int hashCode() { try { portrange = parsePort(portstr); } catch (Exception e) { - throwException(IllegalArgumentException.class, "invalid port range%s", - filterNetInfo(portstr).prefixWith(": ")); + throw new IllegalArgumentException( + formatMsg("invalid port range%s", filterNetInfo(portstr).prefixWith(": "))); } } diff --git a/src/java.base/share/classes/java/net/Inet4AddressImpl.java b/src/java.base/share/classes/java/net/Inet4AddressImpl.java index 0872b1306c336..630f74edbda50 100644 --- a/src/java.base/share/classes/java/net/Inet4AddressImpl.java +++ b/src/java.base/share/classes/java/net/Inet4AddressImpl.java @@ -28,7 +28,7 @@ import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4; import static jdk.internal.util.Exceptions.filterLookupInfo; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; /* * Package private implementation of InetAddressImpl for IPv4. @@ -40,7 +40,7 @@ final class Inet4AddressImpl implements InetAddressImpl { public InetAddress[] lookupAllHostAddr(String hostname, LookupPolicy lookupPolicy) throws UnknownHostException { if ((lookupPolicy.characteristics() & IPV4) == 0) { - throwException(UnknownHostException.class, filterLookupInfo(hostname)); + throw new UnknownHostException(formatMsg("%s", filterLookupInfo(hostname))); } return lookupAllHostAddr(hostname); } diff --git a/src/java.base/share/classes/java/net/Inet6Address.java b/src/java.base/share/classes/java/net/Inet6Address.java index 96cf5ced3d0a0..e383c60ad31a5 100644 --- a/src/java.base/share/classes/java/net/Inet6Address.java +++ b/src/java.base/share/classes/java/net/Inet6Address.java @@ -36,7 +36,7 @@ import java.util.Arrays; import java.util.Objects; import static jdk.internal.util.Exceptions.filterLookupInfo; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; /** * This class represents an Internet Protocol version 6 (IPv6) address. @@ -583,8 +583,9 @@ static InetAddress parseAddressString(String addressLiteral, boolean removeSqBra if (addrBytes.length == Inet4Address.INADDRSZ) { if (numericZone != -1 || ifname != null) { // IPv4-mapped address must not contain zone-id - throwException(UnknownHostException.class, "%sinvalid IPv4-mapped address", - filterLookupInfo(addressLiteral).suffixWith(": ")); + throw new UnknownHostException( + formatMsg("%sinvalid IPv4-mapped address", + filterLookupInfo(addressLiteral).suffixWith(": "))); } return new Inet4Address(null, addrBytes); } diff --git a/src/java.base/share/classes/java/net/InetAddress.java b/src/java.base/share/classes/java/net/InetAddress.java index e055089d85286..f9f178b1cc977 100644 --- a/src/java.base/share/classes/java/net/InetAddress.java +++ b/src/java.base/share/classes/java/net/InetAddress.java @@ -69,9 +69,8 @@ import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4_FIRST; import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6; import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6_FIRST; -import static jdk.internal.util.Exceptions.exception; import static jdk.internal.util.Exceptions.filterLookupInfo; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; /** * This class represents an Internet Protocol (IP) address. @@ -907,7 +906,7 @@ private static class CachedLookup implements Addresses, Comparable @Override public InetAddress[] get() throws UnknownHostException { if (inetAddresses == null) { - throwException(UnknownHostException.class, filterLookupInfo(host)); + throw new UnknownHostException(formatMsg("%s", filterLookupInfo(host))); } return inetAddresses; } @@ -1100,11 +1099,9 @@ public InetAddress[] get() throws UnknownHostException { } } if (inetAddresses == null || inetAddresses.length == 0) { - if (ex == null) { - throwException(UnknownHostException.class, filterLookupInfo(host)); - } else { - throw ex; - } + throw ex == null + ? new UnknownHostException(formatMsg("%s", filterLookupInfo(host))) + : ex; } return inetAddresses; } @@ -1212,19 +1209,19 @@ public String lookupByAddress(byte[] addr) throws UnknownHostException { } } } catch (IOException e) { - throwException(UnknownHostException.class, - "Unable to resolve address %s as hosts file %s not found", - filterLookupInfo(Arrays.toString(addr)), - filterLookupInfo(hostsFile) - .replaceWith("from ${jdk.net.hosts.file} system property")); + throw new UnknownHostException( + formatMsg("Unable to resolve address %s as hosts file %s not found", + filterLookupInfo(Arrays.toString(addr)), + filterLookupInfo(hostsFile) + .replaceWith("from ${jdk.net.hosts.file} system property"))); } if ((host == null) || (host.isEmpty()) || (host.equals(" "))) { - throwException(UnknownHostException.class, - "Requested address %s resolves to an invalid entry in hosts file %s", - filterLookupInfo(Arrays.toString(addr)), - filterLookupInfo(hostsFile) - .replaceWith("from ${jdk.net.hosts.file} system property")); + throw new UnknownHostException( + formatMsg("Requested address %s resolves to an invalid entry in hosts file %s", + filterLookupInfo(Arrays.toString(addr)), + filterLookupInfo(hostsFile) + .replaceWith("from ${jdk.net.hosts.file} system property"))); } return host; } @@ -1285,10 +1282,10 @@ public Stream lookupByName(String host, LookupPolicy lookupPolicy) } } } catch (IOException e) { - throwException(UnknownHostException.class, - "Unable to resolve host %s as hosts file %s not found", - filterLookupInfo(host), filterLookupInfo(hostsFile) - .replaceWith("from ${jdk.net.hosts.file} system property")); + throw new UnknownHostException( + formatMsg("Unable to resolve host %s as hosts file %s not found", + filterLookupInfo(host), filterLookupInfo(hostsFile) + .replaceWith("from ${jdk.net.hosts.file} system property"))); } // Check if only IPv4 addresses are requested @@ -1320,9 +1317,10 @@ public Stream lookupByName(String host, LookupPolicy lookupPolicy) private void checkResultsList(List addressesList, String hostName) throws UnknownHostException { if (addressesList.isEmpty()) { - throwException(UnknownHostException.class, "Unable to resolve host %s in hosts file %s", - filterLookupInfo(hostName), filterLookupInfo(hostsFile) - .replaceWith("from ${jdk.net.hosts.file} system property")); + throw new UnknownHostException( + formatMsg("Unable to resolve host %s in hosts file %s", + filterLookupInfo(hostName), filterLookupInfo(hostsFile) + .replaceWith("from ${jdk.net.hosts.file} system property"))); } } @@ -1559,8 +1557,7 @@ public static InetAddress[] getAllByName(String host) // Here we check the address string for ambiguity only inetAddress = Inet4Address.parseAddressString(host, false); } catch (IllegalArgumentException iae) { - UnknownHostException uhe = exception(UnknownHostException.class, - filterLookupInfo(host)); + var uhe = new UnknownHostException(formatMsg("%s", filterLookupInfo(host))); uhe.initCause(iae); throw uhe; } @@ -1587,8 +1584,8 @@ public static InetAddress[] getAllByName(String host) private static UnknownHostException invalidIPv6LiteralException(String host, boolean wrapInBrackets) { String hostString = wrapInBrackets ? "[" + host + "]" : host; - return exception(UnknownHostException.class, "%sinvalid IPv6 address literal", - filterLookupInfo(hostString).suffixWith(": ")); + return new UnknownHostException(formatMsg("%sinvalid IPv6 address literal", + filterLookupInfo(hostString).suffixWith(": "))); } /** @@ -1726,7 +1723,7 @@ static InetAddress[] getAddressesFromNameService(String host) InetAddress[] result = addresses == null ? null : addresses.toArray(InetAddress[]::new); if (result == null || result.length == 0) { - throw ex == null ? exception(UnknownHostException.class, filterLookupInfo(host)) + throw ex == null ? new UnknownHostException(formatMsg("%s", filterLookupInfo(host))) : ex; } return result; @@ -1799,8 +1796,9 @@ public static InetAddress getLocalHost() throws UnknownHostException { localAddr = getAllByName0(local, false)[0]; } catch (UnknownHostException uhe) { // Rethrow with a more informative error message. - UnknownHostException uhe2 = exception(UnknownHostException.class, - filterLookupInfo(local).suffixWith(": ") + uhe.getMessage()); + UnknownHostException uhe2 = + new UnknownHostException(formatMsg(filterLookupInfo(local) + .suffixWith(": ") + uhe.getMessage())); uhe2.initCause(uhe); throw uhe2; } diff --git a/src/java.base/share/classes/java/net/NetworkInterface.java b/src/java.base/share/classes/java/net/NetworkInterface.java index f8e2a99f234b3..87dc35be98678 100644 --- a/src/java.base/share/classes/java/net/NetworkInterface.java +++ b/src/java.base/share/classes/java/net/NetworkInterface.java @@ -35,7 +35,7 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; import static jdk.internal.util.Exceptions.filterNetInfo; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; /** * This class represents a Network Interface. @@ -325,8 +325,8 @@ public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketE + addr.holder.family); } } else { - throwException(IllegalArgumentException.class, "invalid address type%s", - filterNetInfo(addr.toString()).prefixWith(": ")); + throw new IllegalArgumentException( + formatMsg("invalid address type%s", filterNetInfo(addr.toString()).prefixWith(": "))); } return getByInetAddress0(addr); } diff --git a/src/java.base/share/classes/java/net/Proxy.java b/src/java.base/share/classes/java/net/Proxy.java index 616207726046d..270445f323f0f 100644 --- a/src/java.base/share/classes/java/net/Proxy.java +++ b/src/java.base/share/classes/java/net/Proxy.java @@ -27,7 +27,7 @@ import java.util.Objects; import static jdk.internal.util.Exceptions.filterNetInfo; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; /** * This class represents a proxy setting, typically a type (http, socks) and @@ -96,10 +96,10 @@ private Proxy() { */ public Proxy(Type type, SocketAddress sa) { if ((type == Type.DIRECT) || !(sa instanceof InetSocketAddress)) { - throwException(IllegalArgumentException.class, - "type " + type + " is not compatible with address %s", - filterNetInfo(sa.toString()) - .replaceWith("type " + sa.getClass().toString())); + throw new IllegalArgumentException( + formatMsg("type " + type + " is not compatible with address %s", + filterNetInfo(sa.toString()) + .replaceWith("type " + sa.getClass().toString()))); } this.type = type; this.sa = sa; diff --git a/src/java.base/share/classes/java/net/SocketPermission.java b/src/java.base/share/classes/java/net/SocketPermission.java index 8fa17275f21e2..1754fddbbaf4a 100644 --- a/src/java.base/share/classes/java/net/SocketPermission.java +++ b/src/java.base/share/classes/java/net/SocketPermission.java @@ -47,7 +47,7 @@ import sun.security.util.Debug; import static jdk.internal.util.Exceptions.filterNetInfo; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; /** * This class represents access to a network via sockets. @@ -394,8 +394,8 @@ private void init(String host, int mask) { if (rb != -1) { host = host.substring(start, rb); } else { - throwException(IllegalArgumentException.class, - "invalid host/port%s", filterNetInfo(host).prefixWith(": ")); + throw new IllegalArgumentException( + formatMsg("invalid host/port%s", filterNetInfo(host).prefixWith(": "))); } sep = hostport.indexOf(':', rb+1); } else { @@ -412,8 +412,8 @@ private void init(String host, int mask) { try { portrange = parsePort(port); } catch (Exception e) { - throwException(IllegalArgumentException.class, - "invalid port range%s", filterNetInfo(port).prefixWith(": ")); + throw new IllegalArgumentException( + formatMsg("invalid port range%s", filterNetInfo(port).prefixWith(": "))); } } else { portrange = new int[] { PORT_MIN, PORT_MAX }; @@ -786,7 +786,7 @@ void getIP() throw uhe; } catch (IndexOutOfBoundsException iobe) { invalid = true; - throwException(UnknownHostException.class, filterNetInfo(getName())); + throw new UnknownHostException(formatMsg("%s", filterNetInfo(getName()))); } } diff --git a/src/java.base/share/classes/java/net/SocksSocketImpl.java b/src/java.base/share/classes/java/net/SocksSocketImpl.java index da939cc4b706f..71794d7a0a662 100644 --- a/src/java.base/share/classes/java/net/SocksSocketImpl.java +++ b/src/java.base/share/classes/java/net/SocksSocketImpl.java @@ -38,7 +38,7 @@ import static sun.net.util.IPAddressUtil.isIPv6LiteralAddress; import static jdk.internal.util.Exceptions.filterSocketInfo; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; /** * SOCKS (V4 & V5) TCP socket implementation (RFC 1928). @@ -332,7 +332,7 @@ protected void connect(SocketAddress endpoint, int timeout) throws IOException { // SOCKS Protocol version 4 doesn't know how to deal with // DOMAIN type of addresses (unresolved addresses here) if (epoint.isUnresolved()) - throwException(UnknownHostException.class, filterSocketInfo(epoint.toString())); + throw new UnknownHostException(formatMsg("%s", filterSocketInfo(epoint.toString()))); connectV4(in, out, epoint, deadlineMillis); return; } @@ -351,7 +351,7 @@ protected void connect(SocketAddress endpoint, int timeout) throws IOException { // SOCKS Protocol version 4 doesn't know how to deal with // DOMAIN type of addresses (unresolved addresses here) if (epoint.isUnresolved()) - throwException(UnknownHostException.class, filterSocketInfo(epoint.toString())); + throw new UnknownHostException(formatMsg("%s", filterSocketInfo(epoint.toString()))); connectV4(in, out, epoint, deadlineMillis); return; } diff --git a/src/java.base/share/classes/java/net/URI.java b/src/java.base/share/classes/java/net/URI.java index 4afa72fb8b95a..42288632e1565 100644 --- a/src/java.base/share/classes/java/net/URI.java +++ b/src/java.base/share/classes/java/net/URI.java @@ -46,7 +46,7 @@ import sun.nio.cs.UTF_8; import static jdk.internal.util.Exceptions.filterNetInfo; -import static jdk.internal.util.Exceptions.throwURISyntaxException; +import static jdk.internal.util.Exceptions.formatMsg; /** * Represents a Uniform Resource Identifier (URI) reference. @@ -2036,7 +2036,8 @@ private static void checkPath(String s, String scheme, String path) { if (scheme != null) { if (path != null && !path.isEmpty() && path.charAt(0) != '/') - throwURISyntaxException("%s", "Relative path in absolute URI", -1, filterNetInfo(s)); + throw new URISyntaxException(formatMsg("%s", filterNetInfo(s)), + "Relative path in absolute URI"); } } @@ -2992,14 +2993,14 @@ private class Parser { // -- Methods for throwing URISyntaxException in various ways -- private void fail(String reason) throws URISyntaxException { - throwURISyntaxException("%s", reason, -1, filterNetInfo(input)); + throw new URISyntaxException(formatMsg("%s", filterNetInfo(input)), reason); } private void fail(String reason, int p) throws URISyntaxException { if (!Exceptions.enhancedNetExceptions()) { p = -1; } - throwURISyntaxException("%s", reason, p, filterNetInfo(input)); + throw new URISyntaxException(formatMsg("%s", filterNetInfo(input)), reason, p); } private void failExpecting(String expected, int p) diff --git a/src/java.base/share/classes/java/net/URL.java b/src/java.base/share/classes/java/net/URL.java index 0c2057a178f62..996968da64407 100644 --- a/src/java.base/share/classes/java/net/URL.java +++ b/src/java.base/share/classes/java/net/URL.java @@ -44,8 +44,8 @@ import jdk.internal.misc.ThreadTracker; import jdk.internal.misc.VM; import sun.net.util.IPAddressUtil; -import static jdk.internal.util.Exceptions.throwURISyntaxException; import static jdk.internal.util.Exceptions.filterNetInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * Class {@code URL} represents a Uniform Resource @@ -1171,7 +1171,7 @@ public URI toURI() throws URISyntaxException { if (authority != null && isBuiltinStreamHandler(handler)) { String s = IPAddressUtil.checkAuthority(this); if (s != null) - throwURISyntaxException("%s", s, -1, filterNetInfo(authority)); + throw new URISyntaxException(formatMsg("%s", filterNetInfo(authority)), s); } return uri; } diff --git a/src/java.base/share/classes/java/net/URLStreamHandler.java b/src/java.base/share/classes/java/net/URLStreamHandler.java index 519f0f33a07f8..7a881e98b7b8a 100644 --- a/src/java.base/share/classes/java/net/URLStreamHandler.java +++ b/src/java.base/share/classes/java/net/URLStreamHandler.java @@ -30,7 +30,7 @@ import java.util.Objects; import sun.net.util.IPAddressUtil; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; import static jdk.internal.util.Exceptions.filterNetInfo; /** @@ -208,8 +208,8 @@ protected void parseURL(URL u, String spec, int start, int limit) { host = nhost.substring(0,ind+1); if (!IPAddressUtil. isIPv6LiteralAddress(host.substring(1, ind))) { - throwException(IllegalArgumentException.class, "Invalid host%s", - filterNetInfo(host).prefixWith(": ")); + throw new IllegalArgumentException( + formatMsg("Invalid host%s", filterNetInfo(host).prefixWith(": "))); } port = -1 ; @@ -222,13 +222,15 @@ protected void parseURL(URL u, String spec, int start, int limit) { nhost.length(), 10); } } else { - throwException(IllegalArgumentException.class, "Invalid authority field%s", - filterNetInfo(authority).prefixWith(": ")); + throw new IllegalArgumentException( + formatMsg("Invalid authority field%s", + filterNetInfo(authority).prefixWith(": "))); } } } else { - throwException(IllegalArgumentException.class, "Invalid authority field%s", - filterNetInfo(authority).prefixWith(": ")); + throw new IllegalArgumentException( + formatMsg("Invalid authority field%s", + filterNetInfo(authority).prefixWith(": "))); } } else { ind = host.indexOf(':'); diff --git a/src/java.base/share/classes/jdk/internal/util/Exceptions.java b/src/java.base/share/classes/jdk/internal/util/Exceptions.java index 33b016401cf1e..3ea59db6e1e82 100644 --- a/src/java.base/share/classes/jdk/internal/util/Exceptions.java +++ b/src/java.base/share/classes/jdk/internal/util/Exceptions.java @@ -42,11 +42,9 @@ * Contains static utility methods which can filter exception * message strings for sensitive information. * - * Code using this mechanism should use one of the static throwException - * methods below to generate and throw the exception in one method. - * exception() methods are also provided to generate an exception which - * then be modified before being thrown or used. Lastly, formatMsg() - * can generate a formatted (enhanced or restricted) string only. + * Code using this mechanism should use formatMsg() + * to generate a formatted (enhanced or restricted) string for exception + * messages. * * The methods above take variable numbers of SensitiveInfo objects * as parameters which contain the text that may have to be filtered. @@ -142,59 +140,6 @@ protected String output(boolean enhance) { } } - /** - * Throw an exception of the given class (which has a single arg (String) constructor - * with the given format string. For each %s in the format string, there must be a - * SensitiveInfo following that generates a message string in either enhanced or - * restricted mode. The entire string is then passed to the exception constructor - * Format specifiers other than %s are not supported, and will cause a runtime exception. - */ - public static void throwException(Class exClass, String format, - SensitiveInfo... infos) throws X - { - throw exception(exClass, format, infos); - } - - /** - * Simplified version of above with one SensitiveInfo and a "%s" format string - */ - public static void throwException(Class exClass, SensitiveInfo... infos) throws X - { - throwException(exClass, "%s", infos); - } - - /** - * Returns the exception without throwing it - */ - public static X exception(Class exClass, String format, - SensitiveInfo... infos) - { - try { - Constructor ctor = exClass.getConstructor(String.class); - String msg = formatMsg(format, infos); - return ctor.newInstance(msg); - } catch (ReflectiveOperationException e) { - throw new InternalError(); - } - } - - public static X exception(Class exClass, SensitiveInfo... infos) - { - return exception(exClass, "%s", infos); - } - - /** - * Special case for URISyntaxException (has two additional parameters) - */ - public static URISyntaxException throwURISyntaxException(String format, String arg2, - int index, SensitiveInfo... infos) - throws URISyntaxException - { - String msg = formatMsg(format, infos); - URISyntaxException ex = new URISyntaxException(msg, arg2, index); - throw ex; - } - static final class SocketInfo extends SensitiveInfo { public SocketInfo(String host) { super(host); diff --git a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java index d4021f85ffbd4..975a49da2ef32 100644 --- a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java +++ b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java @@ -37,7 +37,7 @@ import java.util.List; import java.util.concurrent.ConcurrentHashMap; -import static jdk.internal.util.Exceptions.exception; +import static jdk.internal.util.Exceptions.formatMsg; import static jdk.internal.util.Exceptions.filterNetInfo; public class IPAddressUtil { @@ -164,8 +164,8 @@ public static byte[] validateNumericFormatV4(String src, boolean throwIAE) { * @return an {@code IllegalArgumentException} instance */ public static IllegalArgumentException invalidIpAddressLiteral(String src) { - return exception(IllegalArgumentException.class, "Invalid IP address literal%s", - filterNetInfo(src).prefixWith(": ")); + return new IllegalArgumentException( + formatMsg("Invalid IP address literal%s", filterNetInfo(src).prefixWith(": "))); } /* diff --git a/src/java.base/share/classes/sun/net/www/ParseUtil.java b/src/java.base/share/classes/sun/net/www/ParseUtil.java index ac220d6a8cf66..74e7de24113c8 100644 --- a/src/java.base/share/classes/sun/net/www/ParseUtil.java +++ b/src/java.base/share/classes/sun/net/www/ParseUtil.java @@ -41,7 +41,7 @@ import sun.nio.cs.UTF_8; import static jdk.internal.util.Exceptions.filterNetInfo; -import static jdk.internal.util.Exceptions.throwURISyntaxException; +import static jdk.internal.util.Exceptions.formatMsg; /** * A class that contains useful routines common to sun.net.www @@ -504,8 +504,8 @@ private static void checkPath(String s, String scheme, String path) { if (scheme != null) { if (path != null && !path.isEmpty() && path.charAt(0) != '/') - throwURISyntaxException("%s", "Relative path in absolute URI", - -1, filterNetInfo(s)); + throw new URISyntaxException(formatMsg("%s", filterNetInfo(s)), + "Relative path in absolute URI"); } } diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java b/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java index de9fba4aacc73..655c55fe378c3 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java @@ -28,7 +28,7 @@ import java.io.IOException; import java.net.*; import static jdk.internal.util.Exceptions.filterJarName; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; /* * Jar URL Handler @@ -183,10 +183,11 @@ private String parseAbsoluteSpec(String spec) { String innerSpec = spec.substring(0, index - 1); newURL(innerSpec); } catch (MalformedURLException e) { - throwException(NullPointerException.class, "invalid url: %s %s", - filterJarName(spec), filterJarName(e.getMessage()) + throw new NullPointerException( + formatMsg("invalid url: %s %s", filterJarName(spec), + filterJarName(e.getMessage()) .prefixWith("(") - .suffixWith(")")); + .suffixWith(")"))); } return spec; } @@ -197,16 +198,18 @@ private String parseContextSpec(URL url, String spec) { if (spec.startsWith("/")) { int bangSlash = indexOfBangSlash(ctxFile); if (bangSlash == -1) { - throwException(NullPointerException.class, "malformed context url%s : no !/", - filterJarName(url.toString()).prefixWith(": ")); + throw new NullPointerException( + formatMsg("malformed context url%s : no !/", + filterJarName(url.toString()).prefixWith(": "))); } ctxFile = ctxFile.substring(0, bangSlash); } else { // chop up the last component int lastSlash = ctxFile.lastIndexOf('/'); if (lastSlash == -1) { - throwException(NullPointerException.class, "malformed context url%s", - filterJarName(url.toString()).prefixWith(": ")); + throw new NullPointerException( + formatMsg("malformed context url%s", + filterJarName(url.toString()).prefixWith(": "))); } else if (lastSlash < ctxFile.length() - 1) { ctxFile = ctxFile.substring(0, lastSlash + 1); } diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java b/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java index f546268803c37..741854349d7aa 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java @@ -36,7 +36,7 @@ import sun.net.util.URLUtil; import sun.net.www.ParseUtil; import static jdk.internal.util.Exceptions.filterJarName; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; /* A factory for cached JAR file. This class is used to both retrieve * and cache Jar files. @@ -110,7 +110,7 @@ JarFile getOrCreate(URL url, boolean useCaches) throws IOException { result = URLJarFile.getJarFile(patched, this); } if (result == null) - throwException(FileNotFoundException.class, filterJarName(url.toString())); + throw new FileNotFoundException(formatMsg("%s", filterJarName(url.toString()))); return result; } @@ -202,7 +202,7 @@ JarFile get(URL url, boolean useCaches) throws IOException { result = URLJarFile.getJarFile(url, this); } if (result == null) - throwException(FileNotFoundException.class, filterJarName(url.toString())); + throw new FileNotFoundException(formatMsg("%s", filterJarName(url.toString()))); return result; } diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java index e685e57e47628..9c5bfbc12691d 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java @@ -38,7 +38,7 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; import static jdk.internal.util.Exceptions.filterJarName; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; /** @@ -129,10 +129,10 @@ public void connect() throws IOException { factory.closeIfNotCached(url, jarFile); } catch (Exception e) { } - throwException(FileNotFoundException.class, - "JAR entry %s not found in jar file %s", - filterJarName(entryName), - filterJarName(jarFile.getName())); + throw new FileNotFoundException( + formatMsg("JAR entry %s not found in jar file %s", + filterJarName(entryName), + filterJarName(jarFile.getName()))); } } @@ -170,10 +170,10 @@ public InputStream getInputStream() throws IOException { throw new IOException("no entry name specified"); } else { if (jarEntry == null) { - throwException(FileNotFoundException.class, - "JAR entry %s not found in jar file %s", - filterJarName(entryName), - filterJarName(jarFile.getName())); + throw new FileNotFoundException( + formatMsg("JAR entry %s not found in jar file %s", + filterJarName(entryName), + filterJarName(jarFile.getName()))); } result = new JarURLInputStream (jarFile.getInputStream(jarEntry)); } diff --git a/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java b/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java index aa5f9e906d9a7..b097e0fdb9611 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java @@ -32,7 +32,7 @@ import java.io.IOException; import static jdk.internal.util.Exceptions.filterJarName; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; /** * Placeholder protocol handler for the jmod protocol. @@ -46,8 +46,8 @@ protected URLConnection openConnection(URL url) throws IOException { String s = url.toString(); int index = s.indexOf("!/"); if (index == -1) - throwException(MalformedURLException.class, "no !/ found in url spec%s", - filterJarName(s).prefixWith(": ")); + throw new MalformedURLException( + formatMsg("no !/ found in url spec%s", filterJarName(s).prefixWith(": "))); throw new IOException("Can't connect to jmod URL"); } diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java index aae88452ba0bf..c95824aa84986 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java @@ -53,7 +53,7 @@ import java.util.concurrent.locks.ReentrantLock; import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; import static jdk.internal.util.Exceptions.filterNetInfo; /** @@ -492,8 +492,8 @@ public void setInterface(InetAddress inf) throws SocketException { NetworkInterface ni = NetworkInterface.getByInetAddress(inf); if (ni == null) { String address = inf.getHostAddress(); - throwException(SocketException.class, "No network interface found with address %s", - filterNetInfo(address)); + throw new SocketException(formatMsg("No network interface found with address %s", + filterNetInfo(address))); } synchronized (outgoingInterfaceLock) { // set interface and update cached values diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index e2df94124de80..5785c3b3144e9 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -1309,7 +1309,7 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # (socket, addressLookup, net). This is provided for compatibility # with previous releases. # -# jar - enables more detailed information in the IOExceptions thrown +# jar - enables more detailed information in the IOExceptions thrown # by classes in the java.util.jar package # # userInfo - enables more detailed information in exceptions which may contain @@ -1318,7 +1318,7 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # The property setting in this file can be overridden by a system property of # the same name, with the same syntax and possible values. # -# If the property is not set or set to an empty string, then this is the most +# If the property is not set or set to an empty string, then this is the most # restricted setting with all categories disabled. The following is the default # (out of the box) setting, meaning these categories are not restricted. # diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java b/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java index 742d1f5da0841..b1e7b7cbcc409 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java @@ -30,7 +30,7 @@ import static sun.nio.fs.UnixNativeDispatcher.*; import static jdk.internal.util.Exceptions.filterUserName; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; /** * Unix implementation of java.nio.file.attribute.UserPrincipal @@ -139,15 +139,15 @@ private static int lookupName(String name, boolean isGroup) try { id = (isGroup) ? getgrnam(name) : getpwnam(name); } catch (UnixException x) { - throwException(IOException.class, "%s " + x.errorString(), - filterUserName(name).suffixWith(": ")); + throw new IOException(formatMsg("%s " + x.errorString(), + filterUserName(name).suffixWith(": "))); } if (id == -1) { // lookup failed, allow input to be uid or gid try { id = Integer.parseInt(name); } catch (NumberFormatException ignore) { - throwException(UserPrincipalNotFoundException.class, filterUserName(name)); + throw new UserPrincipalNotFoundException(formatMsg("%s", filterUserName(name))); } } return id; diff --git a/src/java.base/unix/native/libnet/net_util_md.c b/src/java.base/unix/native/libnet/net_util_md.c index 0d345fc2617a7..d50130d188bbd 100644 --- a/src/java.base/unix/native/libnet/net_util_md.c +++ b/src/java.base/unix/native/libnet/net_util_md.c @@ -199,18 +199,21 @@ void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, buf = (char *) malloc(size); if (buf) { jstring s; + int n; if (enhancedExceptions) { - snprintf(buf, size, "%s: %s", hostname, error_string); + n = snprintf(buf, size, "%s: %s", hostname, error_string); } else { - snprintf(buf, size, " %s", error_string); + n = snprintf(buf, size, " %s", error_string); } - s = JNU_NewStringPlatform(env, buf); - if (s != NULL) { - jobject x = JNU_NewObjectByName(env, + if (n >= 0) { + s = JNU_NewStringPlatform(env, buf); + if (s != NULL) { + jobject x = JNU_NewObjectByName(env, "java/net/UnknownHostException", "(Ljava/lang/String;)V", s); - if (x != NULL) - (*env)->Throw(env, x); + if (x != NULL) + (*env)->Throw(env, x); + } } free(buf); } diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java b/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java index 2c6563fb21db3..8c3dfa5546ef0 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java @@ -34,7 +34,7 @@ import static sun.nio.fs.WindowsNativeDispatcher.*; import static sun.nio.fs.WindowsConstants.*; import static jdk.internal.util.Exceptions.filterUserName; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; /** * A SecurityDescriptor for use when setting a file's ACL or creating a file @@ -138,8 +138,8 @@ private WindowsSecurityDescriptor(List acl) throws IOException { Math.max(SIZEOF_ACCESS_ALLOWED_ACE, SIZEOF_ACCESS_DENIED_ACE); } catch (WindowsException x) { - throwException(IOException.class, "Failed to get SID %s : " + x.errorString(), - filterUserName(user.getName()).prefixWith("for ")); + throw new IOException(formatMsg("Failed to get SID %s : " + x.errorString(), + filterUserName(user.getName()).prefixWith("for "))); } } diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java b/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java index 8a33043ffa464..0a4e2b9c9faca 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java @@ -29,7 +29,7 @@ import static sun.nio.fs.WindowsConstants.*; import static sun.nio.fs.WindowsNativeDispatcher.*; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; import static jdk.internal.util.Exceptions.filterUserName; class WindowsUserPrincipals { @@ -140,8 +140,8 @@ static UserPrincipal lookup(String name) throws IOException { } catch (WindowsException x) { if (x.lastError() == ERROR_NONE_MAPPED) throw new UserPrincipalNotFoundException(name); - throwException(IOException.class, "%s " + x.errorString(), - filterUserName(name).suffixWith(": ")); + throw new IOException(formatMsg("%s " + x.errorString(), + filterUserName(name).suffixWith(": "))); } assert size > 0; @@ -156,9 +156,8 @@ static UserPrincipal lookup(String name) throws IOException { // return user principal return fromSid(sidBuffer.address()); } catch (WindowsException x) { - throwException(IOException.class, "%s " + x.errorString(), - filterUserName(name).suffixWith(": ")); + throw new IOException(formatMsg("%s " + x.errorString(), + filterUserName(name).suffixWith(": "))); } - return null; // can't happen. Exception will be thrown } } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java index 5968bfb99de14..44688139533d4 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java @@ -40,7 +40,7 @@ import static jdk.internal.net.http.common.Utils.isValidValue; import static jdk.internal.net.http.common.Utils.newIAE; import static jdk.internal.util.Exceptions.filterNetInfo; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; public class HttpRequestBuilderImpl implements HttpRequest.Builder { @@ -84,8 +84,8 @@ static void checkURI(URI uri) { throw newIAE("invalid URI scheme %s", scheme); } if (uri.getHost() == null) { - throwException(IllegalArgumentException.class, "unsupported URI %s", - filterNetInfo(uri.toString())); + throw new IllegalArgumentException( + formatMsg("unsupported URI %s", filterNetInfo(uri.toString()))); } } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java index 017bc329bfb30..0144afa801ada 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java @@ -62,7 +62,7 @@ import static jdk.internal.net.http.common.Utils.isValidName; import static jdk.internal.net.http.common.Utils.stringOf; import static jdk.internal.util.Exceptions.filterNetInfo; -import static jdk.internal.util.Exceptions.throwException; +import static jdk.internal.util.Exceptions.formatMsg; public class OpeningHandshake { @@ -338,11 +338,13 @@ private static URI checkURI(URI uri) { if (!("ws".equalsIgnoreCase(scheme) || "wss".equalsIgnoreCase(scheme))) throw illegal("invalid URI scheme: " + scheme); if (uri.getHost() == null) - throwException(IllegalArgumentException.class, "URI must contain a host%s", - filterNetInfo(uri.toString()).prefixWith(": ")); + throw new IllegalArgumentException( + formatMsg("URI must contain a host%s", + filterNetInfo(uri.toString()).prefixWith(": "))); if (uri.getFragment() != null) - throwException(IllegalArgumentException.class, "URI must not contain a fragment%s", - filterNetInfo(uri.toString()).prefixWith(": ")); + throw new IllegalArgumentException( + formatMsg("URI must not contain a fragment%s", + filterNetInfo(uri.toString()).prefixWith(": "))); return uri; } From da33863ce61a08efb526ede9b00cb1e62b232189 Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Tue, 15 Apr 2025 15:31:31 +0100 Subject: [PATCH 11/22] review update --- src/java.base/share/classes/java/net/Proxy.java | 3 +-- src/java.base/share/classes/jdk/internal/util/Exceptions.java | 3 --- .../share/classes/sun/net/www/protocol/jar/Handler.java | 4 ++-- test/jdk/java/net/URI/Test.java | 2 +- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/java.base/share/classes/java/net/Proxy.java b/src/java.base/share/classes/java/net/Proxy.java index 270445f323f0f..f1319deef217f 100644 --- a/src/java.base/share/classes/java/net/Proxy.java +++ b/src/java.base/share/classes/java/net/Proxy.java @@ -98,8 +98,7 @@ public Proxy(Type type, SocketAddress sa) { if ((type == Type.DIRECT) || !(sa instanceof InetSocketAddress)) { throw new IllegalArgumentException( formatMsg("type " + type + " is not compatible with address %s", - filterNetInfo(sa.toString()) - .replaceWith("type " + sa.getClass().toString()))); + filterNetInfo(String.valueOf(sa)))); } this.type = type; this.sa = sa; diff --git a/src/java.base/share/classes/jdk/internal/util/Exceptions.java b/src/java.base/share/classes/jdk/internal/util/Exceptions.java index 3ea59db6e1e82..1fd639d6e21fb 100644 --- a/src/java.base/share/classes/jdk/internal/util/Exceptions.java +++ b/src/java.base/share/classes/jdk/internal/util/Exceptions.java @@ -250,12 +250,9 @@ public static String formatMsg(String format, SensitiveInfo... infos) { String[] args = new String[infos.length]; int i = 0; - boolean enhanced = true; for (SensitiveInfo info : infos) { args[i++] = info.output(); - if (!info.enhanced()) - enhanced = false; } return trim(String.format(format, (Object[])args)); } diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java b/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java index 655c55fe378c3..381d4244238e0 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java @@ -200,7 +200,7 @@ private String parseContextSpec(URL url, String spec) { if (bangSlash == -1) { throw new NullPointerException( formatMsg("malformed context url%s : no !/", - filterJarName(url.toString()).prefixWith(": "))); + filterJarName(String.valueOf(url)).prefixWith(": "))); } ctxFile = ctxFile.substring(0, bangSlash); } else { @@ -209,7 +209,7 @@ private String parseContextSpec(URL url, String spec) { if (lastSlash == -1) { throw new NullPointerException( formatMsg("malformed context url%s", - filterJarName(url.toString()).prefixWith(": "))); + filterJarName(String.valueOf(url)).prefixWith(": "))); } else if (lastSlash < ctxFile.length() - 1) { ctxFile = ctxFile.substring(0, lastSlash + 1); } diff --git a/test/jdk/java/net/URI/Test.java b/test/jdk/java/net/URI/Test.java index 1b97ca22d8d56..878c3e0d82aff 100644 --- a/test/jdk/java/net/URI/Test.java +++ b/test/jdk/java/net/URI/Test.java @@ -26,7 +26,7 @@ * @bug 4464135 4505046 4503239 4438319 4991359 4866303 7023363 7041800 * 7171415 6339649 6933879 8037396 8272072 8051627 8297687 * @author Mark Reinhold - * @run main/othervm -Djdk.includeInExceptions=hostInfo Test + * @run main/othervm Test */ import java.io.ByteArrayInputStream; From efabc48526c8eb875beced4777fc6c86ca7d321e Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Thu, 24 Apr 2025 17:38:55 +0100 Subject: [PATCH 12/22] Review update --- src/java.base/share/conf/security/java.security | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index 5785c3b3144e9..6beba909d7baf 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -1294,9 +1294,10 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # # The categories are: # -# socket - IOExceptions thrown by java.net.Socket and the socket types in the -# java.nio.channels package will contain enhanced exception -# message information +# socket - IOExceptions thrown by the java.net socket types (for example, Socket, +# ServerSocket, DatagramSocket) and the NetworkChannel types in the +# java.nio.channels package will contain enhanced exception message +# information # # addressLookup - UnknownHostExceptions and other exceptions thrown by the # java.net.InetAddress class From 3b7861b0d96da84793577667fb627c72edd6bca1 Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Fri, 16 May 2025 12:38:59 +0100 Subject: [PATCH 13/22] reduced number of new categories --- .../share/classes/java/net/HostPortrange.java | 6 +- .../classes/java/net/Inet4AddressImpl.java | 4 +- .../share/classes/java/net/Inet6Address.java | 4 +- .../share/classes/java/net/InetAddress.java | 26 ++++----- .../classes/java/net/NetworkInterface.java | 5 +- .../share/classes/java/net/Proxy.java | 4 +- .../classes/java/net/SocketPermission.java | 8 +-- src/java.base/share/classes/java/net/URI.java | 10 ++-- src/java.base/share/classes/java/net/URL.java | 4 +- .../classes/java/net/URLStreamHandler.java | 8 +-- .../classes/jdk/internal/util/Exceptions.java | 58 +++++-------------- .../classes/sun/net/util/IPAddressUtil.java | 4 +- .../share/classes/sun/net/www/ParseUtil.java | 4 +- .../sun/nio/ch/DatagramSocketAdaptor.java | 4 +- .../share/conf/security/java.security | 23 +++----- src/java.base/share/native/libnet/net_util.c | 2 +- .../net/http/HttpRequestBuilderImpl.java | 4 +- .../net/http/ResponseBodyHandlers.java | 2 +- .../net/http/websocket/OpeningHandshake.java | 6 +- .../TestJDKIncludeInExceptions.java | 4 +- test/jdk/sun/net/util/ExceptionsTest.java | 15 +++-- 21 files changed, 85 insertions(+), 120 deletions(-) diff --git a/src/java.base/share/classes/java/net/HostPortrange.java b/src/java.base/share/classes/java/net/HostPortrange.java index a2e008fc6c964..73386f56d7e70 100644 --- a/src/java.base/share/classes/java/net/HostPortrange.java +++ b/src/java.base/share/classes/java/net/HostPortrange.java @@ -29,7 +29,7 @@ import java.util.Locale; import sun.net.util.IPAddressUtil; -import static jdk.internal.util.Exceptions.filterNetInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; import static jdk.internal.util.Exceptions.formatMsg; /** @@ -82,7 +82,7 @@ public int hashCode() { } else { throw new IllegalArgumentException( formatMsg("invalid IPv6 address%s", - filterNetInfo(str).prefixWith(": "))); + filterNonSocketInfo(str).prefixWith(": "))); } int sep = str.indexOf(':', rb + 1); if (sep != -1 && str.length() > sep) { @@ -162,7 +162,7 @@ public int hashCode() { portrange = parsePort(portstr); } catch (Exception e) { throw new IllegalArgumentException( - formatMsg("invalid port range%s", filterNetInfo(portstr).prefixWith(": "))); + formatMsg("invalid port range%s", filterNonSocketInfo(portstr).prefixWith(": "))); } } diff --git a/src/java.base/share/classes/java/net/Inet4AddressImpl.java b/src/java.base/share/classes/java/net/Inet4AddressImpl.java index 630f74edbda50..3d8ea56d99fc8 100644 --- a/src/java.base/share/classes/java/net/Inet4AddressImpl.java +++ b/src/java.base/share/classes/java/net/Inet4AddressImpl.java @@ -27,7 +27,7 @@ import java.net.spi.InetAddressResolver.LookupPolicy; import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4; -import static jdk.internal.util.Exceptions.filterLookupInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; import static jdk.internal.util.Exceptions.formatMsg; /* @@ -40,7 +40,7 @@ final class Inet4AddressImpl implements InetAddressImpl { public InetAddress[] lookupAllHostAddr(String hostname, LookupPolicy lookupPolicy) throws UnknownHostException { if ((lookupPolicy.characteristics() & IPV4) == 0) { - throw new UnknownHostException(formatMsg("%s", filterLookupInfo(hostname))); + throw new UnknownHostException(formatMsg("%s", filterNonSocketInfo(hostname))); } return lookupAllHostAddr(hostname); } diff --git a/src/java.base/share/classes/java/net/Inet6Address.java b/src/java.base/share/classes/java/net/Inet6Address.java index e383c60ad31a5..f0f386a9d29ab 100644 --- a/src/java.base/share/classes/java/net/Inet6Address.java +++ b/src/java.base/share/classes/java/net/Inet6Address.java @@ -35,7 +35,7 @@ import java.util.Enumeration; import java.util.Arrays; import java.util.Objects; -import static jdk.internal.util.Exceptions.filterLookupInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; import static jdk.internal.util.Exceptions.formatMsg; /** @@ -585,7 +585,7 @@ static InetAddress parseAddressString(String addressLiteral, boolean removeSqBra // IPv4-mapped address must not contain zone-id throw new UnknownHostException( formatMsg("%sinvalid IPv4-mapped address", - filterLookupInfo(addressLiteral).suffixWith(": "))); + filterNonSocketInfo(addressLiteral).suffixWith(": "))); } return new Inet4Address(null, addrBytes); } diff --git a/src/java.base/share/classes/java/net/InetAddress.java b/src/java.base/share/classes/java/net/InetAddress.java index f9f178b1cc977..4d8a00249a99d 100644 --- a/src/java.base/share/classes/java/net/InetAddress.java +++ b/src/java.base/share/classes/java/net/InetAddress.java @@ -69,7 +69,7 @@ import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4_FIRST; import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6; import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6_FIRST; -import static jdk.internal.util.Exceptions.filterLookupInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; import static jdk.internal.util.Exceptions.formatMsg; /** @@ -906,7 +906,7 @@ private static class CachedLookup implements Addresses, Comparable @Override public InetAddress[] get() throws UnknownHostException { if (inetAddresses == null) { - throw new UnknownHostException(formatMsg("%s", filterLookupInfo(host))); + throw new UnknownHostException(formatMsg("%s", filterNonSocketInfo(host))); } return inetAddresses; } @@ -1100,7 +1100,7 @@ public InetAddress[] get() throws UnknownHostException { } if (inetAddresses == null || inetAddresses.length == 0) { throw ex == null - ? new UnknownHostException(formatMsg("%s", filterLookupInfo(host))) + ? new UnknownHostException(formatMsg("%s", filterNonSocketInfo(host))) : ex; } return inetAddresses; @@ -1211,16 +1211,16 @@ public String lookupByAddress(byte[] addr) throws UnknownHostException { } catch (IOException e) { throw new UnknownHostException( formatMsg("Unable to resolve address %s as hosts file %s not found", - filterLookupInfo(Arrays.toString(addr)), - filterLookupInfo(hostsFile) + filterNonSocketInfo(Arrays.toString(addr)), + filterNonSocketInfo(hostsFile) .replaceWith("from ${jdk.net.hosts.file} system property"))); } if ((host == null) || (host.isEmpty()) || (host.equals(" "))) { throw new UnknownHostException( formatMsg("Requested address %s resolves to an invalid entry in hosts file %s", - filterLookupInfo(Arrays.toString(addr)), - filterLookupInfo(hostsFile) + filterNonSocketInfo(Arrays.toString(addr)), + filterNonSocketInfo(hostsFile) .replaceWith("from ${jdk.net.hosts.file} system property"))); } return host; @@ -1284,7 +1284,7 @@ public Stream lookupByName(String host, LookupPolicy lookupPolicy) } catch (IOException e) { throw new UnknownHostException( formatMsg("Unable to resolve host %s as hosts file %s not found", - filterLookupInfo(host), filterLookupInfo(hostsFile) + filterNonSocketInfo(host), filterNonSocketInfo(hostsFile) .replaceWith("from ${jdk.net.hosts.file} system property"))); } @@ -1319,7 +1319,7 @@ private void checkResultsList(List addressesList, String hostName) if (addressesList.isEmpty()) { throw new UnknownHostException( formatMsg("Unable to resolve host %s in hosts file %s", - filterLookupInfo(hostName), filterLookupInfo(hostsFile) + filterNonSocketInfo(hostName), filterNonSocketInfo(hostsFile) .replaceWith("from ${jdk.net.hosts.file} system property"))); } } @@ -1557,7 +1557,7 @@ public static InetAddress[] getAllByName(String host) // Here we check the address string for ambiguity only inetAddress = Inet4Address.parseAddressString(host, false); } catch (IllegalArgumentException iae) { - var uhe = new UnknownHostException(formatMsg("%s", filterLookupInfo(host))); + var uhe = new UnknownHostException(formatMsg("%s", filterNonSocketInfo(host))); uhe.initCause(iae); throw uhe; } @@ -1585,7 +1585,7 @@ public static InetAddress[] getAllByName(String host) private static UnknownHostException invalidIPv6LiteralException(String host, boolean wrapInBrackets) { String hostString = wrapInBrackets ? "[" + host + "]" : host; return new UnknownHostException(formatMsg("%sinvalid IPv6 address literal", - filterLookupInfo(hostString).suffixWith(": "))); + filterNonSocketInfo(hostString).suffixWith(": "))); } /** @@ -1723,7 +1723,7 @@ static InetAddress[] getAddressesFromNameService(String host) InetAddress[] result = addresses == null ? null : addresses.toArray(InetAddress[]::new); if (result == null || result.length == 0) { - throw ex == null ? new UnknownHostException(formatMsg("%s", filterLookupInfo(host))) + throw ex == null ? new UnknownHostException(formatMsg("%s", filterNonSocketInfo(host))) : ex; } return result; @@ -1797,7 +1797,7 @@ public static InetAddress getLocalHost() throws UnknownHostException { } catch (UnknownHostException uhe) { // Rethrow with a more informative error message. UnknownHostException uhe2 = - new UnknownHostException(formatMsg(filterLookupInfo(local) + new UnknownHostException(formatMsg(filterNonSocketInfo(local) .suffixWith(": ") + uhe.getMessage())); uhe2.initCause(uhe); throw uhe2; diff --git a/src/java.base/share/classes/java/net/NetworkInterface.java b/src/java.base/share/classes/java/net/NetworkInterface.java index 87dc35be98678..f6f7d43886445 100644 --- a/src/java.base/share/classes/java/net/NetworkInterface.java +++ b/src/java.base/share/classes/java/net/NetworkInterface.java @@ -34,7 +34,7 @@ import java.util.Spliterators; import java.util.stream.Stream; import java.util.stream.StreamSupport; -import static jdk.internal.util.Exceptions.filterNetInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; import static jdk.internal.util.Exceptions.formatMsg; /** @@ -326,7 +326,8 @@ public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketE } } else { throw new IllegalArgumentException( - formatMsg("invalid address type%s", filterNetInfo(addr.toString()).prefixWith(": "))); + formatMsg("invalid address type%s", + filterNonSocketInfo(addr.toString()).prefixWith(": "))); } return getByInetAddress0(addr); } diff --git a/src/java.base/share/classes/java/net/Proxy.java b/src/java.base/share/classes/java/net/Proxy.java index f1319deef217f..4109c586058bb 100644 --- a/src/java.base/share/classes/java/net/Proxy.java +++ b/src/java.base/share/classes/java/net/Proxy.java @@ -26,7 +26,7 @@ package java.net; import java.util.Objects; -import static jdk.internal.util.Exceptions.filterNetInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; import static jdk.internal.util.Exceptions.formatMsg; /** @@ -98,7 +98,7 @@ public Proxy(Type type, SocketAddress sa) { if ((type == Type.DIRECT) || !(sa instanceof InetSocketAddress)) { throw new IllegalArgumentException( formatMsg("type " + type + " is not compatible with address %s", - filterNetInfo(String.valueOf(sa)))); + filterNonSocketInfo(String.valueOf(sa)))); } this.type = type; this.sa = sa; diff --git a/src/java.base/share/classes/java/net/SocketPermission.java b/src/java.base/share/classes/java/net/SocketPermission.java index 1754fddbbaf4a..eb14099f686c0 100644 --- a/src/java.base/share/classes/java/net/SocketPermission.java +++ b/src/java.base/share/classes/java/net/SocketPermission.java @@ -46,7 +46,7 @@ import sun.security.util.SecurityConstants; import sun.security.util.Debug; -import static jdk.internal.util.Exceptions.filterNetInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; import static jdk.internal.util.Exceptions.formatMsg; /** @@ -395,7 +395,7 @@ private void init(String host, int mask) { host = host.substring(start, rb); } else { throw new IllegalArgumentException( - formatMsg("invalid host/port%s", filterNetInfo(host).prefixWith(": "))); + formatMsg("invalid host/port%s", filterNonSocketInfo(host).prefixWith(": "))); } sep = hostport.indexOf(':', rb+1); } else { @@ -413,7 +413,7 @@ private void init(String host, int mask) { portrange = parsePort(port); } catch (Exception e) { throw new IllegalArgumentException( - formatMsg("invalid port range%s", filterNetInfo(port).prefixWith(": "))); + formatMsg("invalid port range%s", filterNonSocketInfo(port).prefixWith(": "))); } } else { portrange = new int[] { PORT_MIN, PORT_MAX }; @@ -786,7 +786,7 @@ void getIP() throw uhe; } catch (IndexOutOfBoundsException iobe) { invalid = true; - throw new UnknownHostException(formatMsg("%s", filterNetInfo(getName()))); + throw new UnknownHostException(formatMsg("%s", filterNonSocketInfo(getName()))); } } diff --git a/src/java.base/share/classes/java/net/URI.java b/src/java.base/share/classes/java/net/URI.java index 9b51bf64dfc2d..daf63d1903224 100644 --- a/src/java.base/share/classes/java/net/URI.java +++ b/src/java.base/share/classes/java/net/URI.java @@ -45,7 +45,7 @@ import jdk.internal.util.Exceptions; import sun.nio.cs.UTF_8; -import static jdk.internal.util.Exceptions.filterNetInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; import static jdk.internal.util.Exceptions.formatMsg; /** @@ -2036,7 +2036,7 @@ private static void checkPath(String s, String scheme, String path) { if (scheme != null) { if (path != null && !path.isEmpty() && path.charAt(0) != '/') - throw new URISyntaxException(formatMsg("%s", filterNetInfo(s)), + throw new URISyntaxException(formatMsg("%s", filterNonSocketInfo(s)), "Relative path in absolute URI"); } } @@ -2993,14 +2993,14 @@ private class Parser { // -- Methods for throwing URISyntaxException in various ways -- private void fail(String reason) throws URISyntaxException { - throw new URISyntaxException(formatMsg("%s", filterNetInfo(input)), reason); + throw new URISyntaxException(formatMsg("%s", filterNonSocketInfo(input)), reason); } private void fail(String reason, int p) throws URISyntaxException { - if (!Exceptions.enhancedNetExceptions()) { + if (!Exceptions.enhancedNonSocketExceptions()) { p = -1; } - throw new URISyntaxException(formatMsg("%s", filterNetInfo(input)), reason, p); + throw new URISyntaxException(formatMsg("%s", filterNonSocketInfo(input)), reason, p); } private void failExpecting(String expected, int p) diff --git a/src/java.base/share/classes/java/net/URL.java b/src/java.base/share/classes/java/net/URL.java index 996968da64407..9266b6c94f17e 100644 --- a/src/java.base/share/classes/java/net/URL.java +++ b/src/java.base/share/classes/java/net/URL.java @@ -44,7 +44,7 @@ import jdk.internal.misc.ThreadTracker; import jdk.internal.misc.VM; import sun.net.util.IPAddressUtil; -import static jdk.internal.util.Exceptions.filterNetInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; import static jdk.internal.util.Exceptions.formatMsg; /** @@ -1171,7 +1171,7 @@ public URI toURI() throws URISyntaxException { if (authority != null && isBuiltinStreamHandler(handler)) { String s = IPAddressUtil.checkAuthority(this); if (s != null) - throw new URISyntaxException(formatMsg("%s", filterNetInfo(authority)), s); + throw new URISyntaxException(formatMsg("%s", filterNonSocketInfo(authority)), s); } return uri; } diff --git a/src/java.base/share/classes/java/net/URLStreamHandler.java b/src/java.base/share/classes/java/net/URLStreamHandler.java index 7a881e98b7b8a..f66902a451e62 100644 --- a/src/java.base/share/classes/java/net/URLStreamHandler.java +++ b/src/java.base/share/classes/java/net/URLStreamHandler.java @@ -31,7 +31,7 @@ import sun.net.util.IPAddressUtil; import static jdk.internal.util.Exceptions.formatMsg; -import static jdk.internal.util.Exceptions.filterNetInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; /** * The abstract class {@code URLStreamHandler} is the common @@ -209,7 +209,7 @@ protected void parseURL(URL u, String spec, int start, int limit) { if (!IPAddressUtil. isIPv6LiteralAddress(host.substring(1, ind))) { throw new IllegalArgumentException( - formatMsg("Invalid host%s", filterNetInfo(host).prefixWith(": "))); + formatMsg("Invalid host%s", filterNonSocketInfo(host).prefixWith(": "))); } port = -1 ; @@ -224,13 +224,13 @@ protected void parseURL(URL u, String spec, int start, int limit) { } else { throw new IllegalArgumentException( formatMsg("Invalid authority field%s", - filterNetInfo(authority).prefixWith(": "))); + filterNonSocketInfo(authority).prefixWith(": "))); } } } else { throw new IllegalArgumentException( formatMsg("Invalid authority field%s", - filterNetInfo(authority).prefixWith(": "))); + filterNonSocketInfo(authority).prefixWith(": "))); } } else { ind = host.indexOf(':'); diff --git a/src/java.base/share/classes/jdk/internal/util/Exceptions.java b/src/java.base/share/classes/jdk/internal/util/Exceptions.java index 1fd639d6e21fb..5c1913b343425 100644 --- a/src/java.base/share/classes/jdk/internal/util/Exceptions.java +++ b/src/java.base/share/classes/jdk/internal/util/Exceptions.java @@ -50,9 +50,8 @@ * as parameters which contain the text that may have to be filtered. * * The SensitiveInfo objects should be generated with one of the following: - * public static SensitiveInfo filterLookupInfo(String host) * public static SensitiveInfo filterSocketInfo(String s) - * public static SensitiveInfo filterNetInfo(String s) + * public static SensitiveInfo filterNonSocketInfo(String s) * public static SensitiveInfo filterJarName(String name) * public static SensitiveInfo filterUserName(String name) */ @@ -60,8 +59,7 @@ public final class Exceptions { private Exceptions() {} private static volatile boolean enhancedSocketExceptionText; - private static volatile boolean enhancedNetExceptionText; - private static volatile boolean enhancedLookupExceptionText; + private static volatile boolean enhancedNonSocketExceptionText; private static volatile boolean enhancedUserExceptionText; private static volatile boolean enhancedJarExceptionText; private static volatile boolean initialized = false; @@ -78,9 +76,8 @@ private Exceptions() {} * controlled. Consider using a unique value for the * SecurityProperties.includedInExceptions(String value) mechanism * Current values defined are "socket", "jar", "userInfo" - * "net", "addressLookup". The value "hostInfo" exists for - * compatibility and is the same as the combination of - * "socket,addressLookup,net" + * "hostInfo", "hostInfoExclSocket". + * * New code can also piggy back on existing categories * * A SensitiveInfo contains the following components @@ -151,26 +148,14 @@ public String output() { } } - static final class NetInfo extends SensitiveInfo { - public NetInfo(String host) { - super(host); - } - @Override - public String output() { - setup(); - return super.output(enhancedNetExceptionText); - } - } - - - static final class LookupInfo extends SensitiveInfo { - public LookupInfo(String host) { + static final class NonSocketInfo extends SensitiveInfo { + public NonSocketInfo(String host) { super(host); } @Override public String output() { setup(); - return super.output(enhancedLookupExceptionText); + return super.output(enhancedNonSocketExceptionText); } } @@ -226,12 +211,8 @@ public static SensitiveInfo filterSocketInfo(String host) { return new SocketInfo(host); } - public static SensitiveInfo filterNetInfo(String host) { - return new NetInfo(host); - } - - public static SensitiveInfo filterLookupInfo(String host) { - return new LookupInfo(host); + public static SensitiveInfo filterNonSocketInfo(String host) { + return new NonSocketInfo(host); } public static SensitiveInfo filterJarName(String name) { @@ -268,22 +249,18 @@ private static String formatMsg(SensitiveInfo info) { public static void setup() { if (initialized || !VM.isBooted()) return; - // for compatibility - var hostCompatFlag = SecurityProperties.includedInExceptions("hostInfo"); - enhancedSocketExceptionText = SecurityProperties.includedInExceptions("socket") - | hostCompatFlag; - enhancedNetExceptionText = SecurityProperties.includedInExceptions("net") - | hostCompatFlag; - enhancedLookupExceptionText = SecurityProperties.includedInExceptions("addressLookup") - | hostCompatFlag; + enhancedSocketExceptionText = SecurityProperties.includedInExceptions("hostInfo"); + enhancedNonSocketExceptionText = SecurityProperties.includedInExceptions("hostInfoExclSocket") + | enhancedSocketExceptionText; + enhancedUserExceptionText = SecurityProperties.includedInExceptions("userInfo"); enhancedJarExceptionText = SecurityProperties.INCLUDE_JAR_NAME_IN_EXCEPTIONS; initialized = true; } - public static boolean enhancedNetExceptions() { + public static boolean enhancedNonSocketExceptions() { setup(); - return enhancedNetExceptionText; + return enhancedNonSocketExceptionText; } public static boolean enhancedSocketExceptions() { @@ -291,11 +268,6 @@ public static boolean enhancedSocketExceptions() { return enhancedSocketExceptionText; } - public static boolean enhancedLookupExceptions() { - setup(); - return enhancedLookupExceptionText; - } - /** * The enhanced message text is the socket address appended to * the original IOException message diff --git a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java index 975a49da2ef32..21bbc5ac45532 100644 --- a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java +++ b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java @@ -38,7 +38,7 @@ import java.util.concurrent.ConcurrentHashMap; import static jdk.internal.util.Exceptions.formatMsg; -import static jdk.internal.util.Exceptions.filterNetInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; public class IPAddressUtil { private static final int INADDR4SZ = 4; @@ -165,7 +165,7 @@ public static byte[] validateNumericFormatV4(String src, boolean throwIAE) { */ public static IllegalArgumentException invalidIpAddressLiteral(String src) { return new IllegalArgumentException( - formatMsg("Invalid IP address literal%s", filterNetInfo(src).prefixWith(": "))); + formatMsg("Invalid IP address literal%s", filterNonSocketInfo(src).prefixWith(": "))); } /* diff --git a/src/java.base/share/classes/sun/net/www/ParseUtil.java b/src/java.base/share/classes/sun/net/www/ParseUtil.java index 74e7de24113c8..cac32e53288c1 100644 --- a/src/java.base/share/classes/sun/net/www/ParseUtil.java +++ b/src/java.base/share/classes/sun/net/www/ParseUtil.java @@ -40,7 +40,7 @@ import java.util.HexFormat; import sun.nio.cs.UTF_8; -import static jdk.internal.util.Exceptions.filterNetInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; import static jdk.internal.util.Exceptions.formatMsg; /** @@ -504,7 +504,7 @@ private static void checkPath(String s, String scheme, String path) { if (scheme != null) { if (path != null && !path.isEmpty() && path.charAt(0) != '/') - throw new URISyntaxException(formatMsg("%s", filterNetInfo(s)), + throw new URISyntaxException(formatMsg("%s", filterNonSocketInfo(s)), "Relative path in absolute URI"); } } diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java index c95824aa84986..44b05f9747251 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java @@ -54,7 +54,7 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import static jdk.internal.util.Exceptions.formatMsg; -import static jdk.internal.util.Exceptions.filterNetInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; /** * A multicast datagram socket based on a datagram channel. @@ -493,7 +493,7 @@ public void setInterface(InetAddress inf) throws SocketException { if (ni == null) { String address = inf.getHostAddress(); throw new SocketException(formatMsg("No network interface found with address %s", - filterNetInfo(address))); + filterNonSocketInfo(address))); } synchronized (outgoingInterfaceLock) { // set interface and update cached values diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index 6beba909d7baf..f4eadb9e4438d 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -1294,21 +1294,13 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # # The categories are: # -# socket - IOExceptions thrown by the java.net socket types (for example, Socket, -# ServerSocket, DatagramSocket) and the NetworkChannel types in the -# java.nio.channels package will contain enhanced exception message -# information +# hostInfo - All networking related exceptions will contain enhanced +# exception message information. # -# addressLookup - UnknownHostExceptions and other exceptions thrown by the -# java.net.InetAddress class -# -# net - All other exceptions thrown in networking code not included -# in the categories above. This include URL/URI, NetworkInterface -# and URLConnection among others. -# -# hostInfo - Special value which signifies the three categories above combined -# (socket, addressLookup, net). This is provided for compatibility -# with previous releases. +# hostInfoExclSocket - The hostInfo category defined above, excluding +# IOExceptions thrown by java.net.Socket and the NetworkChannel +# types in the java.nio.channels package, will contain enhanced +# exception message information # # jar - enables more detailed information in the IOExceptions thrown # by classes in the java.util.jar package @@ -1323,7 +1315,8 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # restricted setting with all categories disabled. The following is the default # (out of the box) setting, meaning these categories are not restricted. # -jdk.includeInExceptions=addressLookup,net,userInfo +jdk.includeInExceptions=hostInfoExclSocket + # # Disabled mechanisms for the Simple Authentication and Security Layer (SASL) # diff --git a/src/java.base/share/native/libnet/net_util.c b/src/java.base/share/native/libnet/net_util.c index 0c47bfffe4b15..9c0f14b0d9007 100644 --- a/src/java.base/share/native/libnet/net_util.c +++ b/src/java.base/share/native/libnet/net_util.c @@ -109,7 +109,7 @@ int getEnhancedExceptionsAllowed(JNIEnv *env) { } cls = (*env)->FindClass(env, "jdk/internal/util/Exceptions"); CHECK_NULL_THROW_ERROR(cls); - fid = (*env)->GetStaticFieldID(env, cls, "enhancedLookupExceptionText", "Z"); + fid = (*env)->GetStaticFieldID(env, cls, "enhancedNonSocketExceptionText", "Z"); CHECK_NULL_THROW_ERROR(fid); enhancedExceptionsAllowed = (*env)->GetStaticBooleanField(env, cls, fid); enhancedExceptionsInitialized = 1; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java index 44688139533d4..a495fcce1eebb 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestBuilderImpl.java @@ -39,7 +39,7 @@ import static jdk.internal.net.http.common.Utils.isValidName; import static jdk.internal.net.http.common.Utils.isValidValue; import static jdk.internal.net.http.common.Utils.newIAE; -import static jdk.internal.util.Exceptions.filterNetInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; import static jdk.internal.util.Exceptions.formatMsg; public class HttpRequestBuilderImpl implements HttpRequest.Builder { @@ -85,7 +85,7 @@ static void checkURI(URI uri) { } if (uri.getHost() == null) { throw new IllegalArgumentException( - formatMsg("unsupported URI %s", filterNetInfo(uri.toString()))); + formatMsg("unsupported URI %s", filterNonSocketInfo(uri.toString()))); } } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java index c8e8f1f9d392e..a74c632c21854 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java @@ -192,7 +192,7 @@ static boolean allowedInToken(char c) { static final UncheckedIOException unchecked(ResponseInfo rinfo, String msg) { String s; - if (Exceptions.enhancedNetExceptions()) { + if (Exceptions.enhancedNonSocketExceptions()) { s = String.format("%s in response [%d, %s]", msg, rinfo.statusCode(), rinfo.headers()); } else { s = String.format("%s in response [%d]", msg, rinfo.statusCode()); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java index 0144afa801ada..6e76a272cd020 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java @@ -61,7 +61,7 @@ import static java.lang.String.format; import static jdk.internal.net.http.common.Utils.isValidName; import static jdk.internal.net.http.common.Utils.stringOf; -import static jdk.internal.util.Exceptions.filterNetInfo; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; import static jdk.internal.util.Exceptions.formatMsg; public class OpeningHandshake { @@ -340,11 +340,11 @@ private static URI checkURI(URI uri) { if (uri.getHost() == null) throw new IllegalArgumentException( formatMsg("URI must contain a host%s", - filterNetInfo(uri.toString()).prefixWith(": "))); + filterNonSocketInfo(uri.toString()).prefixWith(": "))); if (uri.getFragment() != null) throw new IllegalArgumentException( formatMsg("URI must not contain a fragment%s", - filterNetInfo(uri.toString()).prefixWith(": "))); + filterNonSocketInfo(uri.toString()).prefixWith(": "))); return uri; } diff --git a/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java b/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java index 67b15e80ba4fe..011fc6bbaf481 100644 --- a/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java +++ b/test/jdk/jdk/security/JavaDotSecurity/TestJDKIncludeInExceptions.java @@ -28,7 +28,7 @@ * @bug 8207846 8208691 * @summary Test the default setting of the jdk.net.includeInExceptions * security property - * @comment In OpenJDK, this property has value "addressLookup,net" by default + * @comment In OpenJDK, this property has value "hostInfoExclSocket" by default * This test assures the default is not changed. * @run main TestJDKIncludeInExceptions */ @@ -36,7 +36,7 @@ public class TestJDKIncludeInExceptions { public static void main(String args[]) throws Exception { String incInExc = Security.getProperty("jdk.includeInExceptions"); - if (incInExc == null || !incInExc.equals("addressLookup,net,userInfo")) { + if (incInExc == null || !incInExc.equals("hostInfoExclSocket")) { throw new RuntimeException("Test failed: default value of " + "jdk.includeInExceptions security property does not have expected value: " + incInExc); diff --git a/test/jdk/sun/net/util/ExceptionsTest.java b/test/jdk/sun/net/util/ExceptionsTest.java index a539d6ccad0f0..d6717763afbdc 100644 --- a/test/jdk/sun/net/util/ExceptionsTest.java +++ b/test/jdk/sun/net/util/ExceptionsTest.java @@ -26,9 +26,8 @@ import jdk.internal.util.Exceptions; import jdk.internal.util.Exceptions.SensitiveInfo; import static jdk.internal.util.Exceptions.formatMsg; -import static jdk.internal.util.Exceptions.filterNetInfo; -import static jdk.internal.util.Exceptions.enhancedLookupExceptions; -import static jdk.internal.util.Exceptions.enhancedNetExceptions; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.enhancedNonSocketExceptions; /* * @test @@ -44,13 +43,13 @@ public class ExceptionsTest { static boolean netEnabled() { - System.out.printf("netEnabled = %b\n", enhancedNetExceptions()); - return enhancedNetExceptions(); + System.out.printf("netEnabled = %b\n", enhancedNonSocketExceptions()); + return enhancedNonSocketExceptions(); } static boolean dnsEnabled() { - System.out.printf("dnsEnabled = %b\n", enhancedLookupExceptions()); - return enhancedLookupExceptions(); + System.out.printf("dnsEnabled = %b\n", enhancedNonSocketExceptions()); + return enhancedNonSocketExceptions(); } static boolean hostFileEnabled() { @@ -132,7 +131,7 @@ static SensitiveInfo[] getArgs(String[] args) { var repArg = s.substring(REP.length(), s.indexOf(')')); sa[index-1] = sa[index-1].replaceWith(repArg); } else { - sa[index++] = filterNetInfo(s); + sa[index++] = filterNonSocketInfo(s); } } return Arrays.copyOf(sa, index); From dea50804c6b48b27e76fad79942bd2658b3d674a Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Tue, 20 May 2025 10:21:05 +0100 Subject: [PATCH 14/22] update --- src/java.base/share/classes/jdk/internal/util/Exceptions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/jdk/internal/util/Exceptions.java b/src/java.base/share/classes/jdk/internal/util/Exceptions.java index 5c1913b343425..30699c3d61f3b 100644 --- a/src/java.base/share/classes/jdk/internal/util/Exceptions.java +++ b/src/java.base/share/classes/jdk/internal/util/Exceptions.java @@ -75,7 +75,7 @@ private Exceptions() {} * Sub-class for any new category that needs to be independently * controlled. Consider using a unique value for the * SecurityProperties.includedInExceptions(String value) mechanism - * Current values defined are "socket", "jar", "userInfo" + * Current values defined are "jar", "userInfo" * "hostInfo", "hostInfoExclSocket". * * New code can also piggy back on existing categories From 34f20c9a9abe75c6a0c03cd5ff2ec14a3cbb8f66 Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Thu, 29 May 2025 15:29:50 +0100 Subject: [PATCH 15/22] Additional callsites identified by Mark S. --- .../share/classes/java/net/HostPortrange.java | 28 ++++++++-------- .../classes/jdk/internal/util/Exceptions.java | 16 +++++----- src/java.base/share/classes/module-info.java | 2 ++ .../net/www/protocol/https/HttpsClient.java | 9 ++++-- .../classes/sun/nio/ch/NioSocketImpl.java | 5 ++- .../classes/sun/nio/ch/SocketAdaptor.java | 6 +++- .../classes/com/sun/jndi/ldap/LdapURL.java | 5 ++- .../classes/com/sun/jndi/toolkit/url/Uri.java | 32 +++++++++++-------- .../share/classes/java/rmi/Naming.java | 28 +++++++++------- 9 files changed, 79 insertions(+), 52 deletions(-) diff --git a/src/java.base/share/classes/java/net/HostPortrange.java b/src/java.base/share/classes/java/net/HostPortrange.java index 73386f56d7e70..dada6028ac506 100644 --- a/src/java.base/share/classes/java/net/HostPortrange.java +++ b/src/java.base/share/classes/java/net/HostPortrange.java @@ -59,7 +59,7 @@ public int hashCode() { return hostname.hashCode() + portrange[0] + portrange[1]; } - HostPortrange(String scheme, String str) { + HostPortrange(String scheme, String hostname) { // Parse the host name. A name has up to three components, the // hostname, a port number, or two numbers representing a port // range. "www.example.com:8080-9090" is a valid host name. @@ -74,19 +74,19 @@ public int hashCode() { this.scheme = scheme; // check for IPv6 address - if (str.charAt(0) == '[') { + if (hostname.charAt(0) == '[') { ipv6 = literal = true; - int rb = str.indexOf(']'); + int rb = hostname.indexOf(']'); if (rb != -1) { - hoststr = str.substring(1, rb); + hoststr = hostname.substring(1, rb); } else { throw new IllegalArgumentException( - formatMsg("invalid IPv6 address%s", - filterNonSocketInfo(str).prefixWith(": "))); + formatMsg("invalid IPv6 address%s", + filterNonSocketInfo(hostname).prefixWith(": "))); } - int sep = str.indexOf(':', rb + 1); - if (sep != -1 && str.length() > sep) { - portstr = str.substring(sep + 1); + int sep = hostname.indexOf(':', rb + 1); + if (sep != -1 && hostname.length() > sep) { + portstr = hostname.substring(sep + 1); } // need to normalize hoststr now byte[] ip = IPAddressUtil.textToNumericFormatV6(hoststr); @@ -103,12 +103,12 @@ public int hashCode() { } else { // not IPv6 therefore ':' is the port separator - int sep = str.indexOf(':'); - if (sep != -1 && str.length() > sep) { - hoststr = str.substring(0, sep); - portstr = str.substring(sep + 1); + int sep = hostname.indexOf(':'); + if (sep != -1 && hostname.length() > sep) { + hoststr = hostname.substring(0, sep); + portstr = hostname.substring(sep + 1); } else { - hoststr = sep == -1 ? str : str.substring(0, sep); + hoststr = sep == -1 ? hostname : hostname.substring(0, sep); } // is this a domain wildcard specification? if (hoststr.lastIndexOf('*') > 0) { diff --git a/src/java.base/share/classes/jdk/internal/util/Exceptions.java b/src/java.base/share/classes/jdk/internal/util/Exceptions.java index 30699c3d61f3b..6b061a6a4e779 100644 --- a/src/java.base/share/classes/jdk/internal/util/Exceptions.java +++ b/src/java.base/share/classes/jdk/internal/util/Exceptions.java @@ -86,8 +86,8 @@ private Exceptions() {} * prefix, the sensitive info itself, a suffix * and a replacement string. * - * The output(boolean enhance) method generates an enhanced - * string when enhance is true. + * The composeFilteredText(boolean enhance) method generates + * an enhanced string when enhance is true. * This comprises (enhance == true) * prefix + info + suffix * When (enhance == false), then by default the output is: @@ -121,13 +121,13 @@ public boolean enhanced() { } /** - * Implementation should call output(boolean flag) + * Implementation should call composeFilteredText(boolean flag) * where flag contains the boolean value of whether * the category is enabled or not. */ public abstract String output(); - protected String output(boolean enhance) { + protected String composeFilteredText(boolean enhance) { if (enhance) { this.enhanced = true; return prefix + info + suffix; @@ -144,7 +144,7 @@ public SocketInfo(String host) { @Override public String output() { setup(); - return super.output(enhancedSocketExceptionText); + return super.composeFilteredText(enhancedSocketExceptionText); } } @@ -155,7 +155,7 @@ public NonSocketInfo(String host) { @Override public String output() { setup(); - return super.output(enhancedNonSocketExceptionText); + return super.composeFilteredText(enhancedNonSocketExceptionText); } } @@ -166,7 +166,7 @@ public JarInfo(String name) { @Override public String output() { setup(); - return super.output(enhancedJarExceptionText); + return super.composeFilteredText(enhancedJarExceptionText); } } @@ -177,7 +177,7 @@ public UserInfo(String host) { @Override public String output() { setup(); - return super.output(enhancedUserExceptionText); + return super.composeFilteredText(enhancedUserExceptionText); } } diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 2c0d16ae04d93..07de3f2c57f6e 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -270,6 +270,8 @@ java.prefs, java.security.jgss, java.smartcardio, + java.naming, + java.rmi, java.net.http, jdk.charsets, jdk.incubator.vector, diff --git a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java index fb2dfe6fff311..a8472d490fca8 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java +++ b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java @@ -53,7 +53,8 @@ import sun.util.logging.PlatformLogger; import static sun.net.www.protocol.http.HttpURLConnection.TunnelState.*; - +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * This class provides HTTPS client URL support, building on the standard @@ -559,8 +560,10 @@ private void checkURLSpoofing(HostnameVerifier hostnameVerifier) serverSocket.close(); session.invalidate(); - throw new IOException("HTTPS hostname wrong: should be <" - + url.getHost() + ">"); + throw new IOException(formatMsg("HTTPS hostname wrong: %s", + filterNonSocketInfo(url.getHost()) + .prefixWith("should be <") + .suffixWith(">"))); } @Override diff --git a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java index 12f0b00d195cf..c0ecd1ad089b6 100644 --- a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java @@ -62,6 +62,8 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * NIO based SocketImpl. @@ -554,7 +556,8 @@ protected void connect(SocketAddress remote, int millis) throws IOException { throw new IOException("Unsupported address type"); InetSocketAddress isa = (InetSocketAddress) remote; if (isa.isUnresolved()) { - throw new UnknownHostException(isa.getHostName()); + throw new UnknownHostException( + formatMsg("%s", filterNonSocketInfo(isa.getHostName()))); } InetAddress address = isa.getAddress(); diff --git a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java index d8ed1cfb675e9..d109089ecd35e 100644 --- a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java @@ -40,6 +40,9 @@ import java.util.Set; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; + // Make a socket channel look like a socket. // @@ -92,7 +95,8 @@ public void connect(SocketAddress remote, int timeout) throws IOException { if (sc.isConnected()) throw new SocketException("Already connected"); close(); - throw new UnknownHostException(remote.toString()); + throw new UnknownHostException( + formatMsg("%s", filterNonSocketInfo(remote.toString()))); } if (timeout < 0) throw new IllegalArgumentException("connect: timeout can't be negative"); diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java index 140f025b779e0..2d574eb4638a5 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java @@ -33,6 +33,8 @@ import java.util.StringTokenizer; import com.sun.jndi.toolkit.url.Uri; import com.sun.jndi.toolkit.url.UrlUtil; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /* * Extract components of an LDAP URL. @@ -119,7 +121,8 @@ public LdapURL(String url) throws NamingException { @Override protected MalformedURLException newInvalidURISchemeException(String uri) { - return new MalformedURLException("Not an LDAP URL: " + uri); + return new MalformedURLException(formatMsg("Not an LDAP URL: %s", + filterNonSocketInfo(uri))); } @Override diff --git a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java index 10316b1ca6915..8156d257d7988 100644 --- a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java +++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java @@ -29,6 +29,8 @@ import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** @@ -232,6 +234,10 @@ private void parse(String uri, ParseMode mode) throws MalformedURLException { } } + private MalformedURLException newMalformedURLException(String prefix, String msg) { + return new MalformedURLException(formatMsg(prefix + " %s", filterNonSocketInfo(msg))); + } + /* * Parses a URI string and sets this object's fields accordingly. * Use java.net.URI to validate the uri string syntax @@ -241,7 +247,7 @@ private void parseStrict(String uri) throws MalformedURLException { if (!isSchemeOnly(uri)) { URI u = new URI(uri); scheme = u.getScheme(); - if (scheme == null) throw new MalformedURLException("Invalid URI: " + uri); + if (scheme == null) throw newMalformedURLException("Invalid URI:", uri); var auth = u.getRawAuthority(); hasAuthority = auth != null; if (hasAuthority) { @@ -253,7 +259,7 @@ private void parseStrict(String uri) throws MalformedURLException { + (port == -1 ? "" : (":" + port)); if (!hostport.equals(auth)) { // throw if we have user info or regname - throw new MalformedURLException("unsupported authority: " + auth); + throw newMalformedURLException("unsupported authority:", auth); } } path = u.getRawPath(); @@ -262,7 +268,7 @@ private void parseStrict(String uri) throws MalformedURLException { } if (u.getRawFragment() != null) { if (!acceptsFragment()) { - throw new MalformedURLException("URI fragments not supported: " + uri); + throw newMalformedURLException("URI fragments not supported:", uri); } fragment = "#" + u.getRawFragment(); } @@ -279,7 +285,7 @@ private void parseStrict(String uri) throws MalformedURLException { path = ""; } } catch (URISyntaxException e) { - var mue = new MalformedURLException(e.getMessage()); + var mue = newMalformedURLException("", e.getMessage()); mue.initCause(e); throw mue; } @@ -299,11 +305,11 @@ private void parseCompat(String uri) throws MalformedURLException { int qmark = uri.indexOf('?'); int fmark = uri.indexOf('#'); if (i < 0 || slash > 0 && i > slash || qmark > 0 && i > qmark || fmark > 0 && i > fmark) { - throw new MalformedURLException("Invalid URI: " + uri); + throw newMalformedURLException("Invalid URI:", uri); } if (fmark > -1) { if (!acceptsFragment()) { - throw new MalformedURLException("URI fragments not supported: " + uri); + throw newMalformedURLException("URI fragments not supported:", uri); } } if (i == uri.length() - 1) { @@ -349,26 +355,26 @@ private void parseCompat(String uri) throws MalformedURLException { String f = u.getRawFragment(); String ui = u.getRawUserInfo(); if (ui != null) { - throw new MalformedURLException("user info not supported in authority: " + ui); + throw newMalformedURLException("user info not supported in authority:", ui); } if (!"/".equals(p)) { - throw new MalformedURLException("invalid authority: " + auth); + throw newMalformedURLException("invalid authority:", auth); } if (q != null) { - throw new MalformedURLException("invalid trailing characters in authority: ?" + q); + throw newMalformedURLException("invalid trailing characters in authority: ?", q); } if (f != null) { - throw new MalformedURLException("invalid trailing characters in authority: #" + f); + throw newMalformedURLException("invalid trailing characters in authority: #", f); } String hostport = (host == null ? "" : host) + (port == -1?"":(":" + port)); if (!auth.equals(hostport)) { // throw if we have user info or regname - throw new MalformedURLException("Authority component is not server-based, " + - "or contains user info. Unsupported authority: " + auth); + throw newMalformedURLException("Authority component is not server-based, " + + "or contains user info. Unsupported authority:", auth); } } catch (URISyntaxException e) { - var mue = new MalformedURLException(e.getMessage()); + var mue = newMalformedURLException("", e.getMessage()); mue.initCause(e); throw mue; } diff --git a/src/java.rmi/share/classes/java/rmi/Naming.java b/src/java.rmi/share/classes/java/rmi/Naming.java index c467799177002..f46695c346a6b 100644 --- a/src/java.rmi/share/classes/java/rmi/Naming.java +++ b/src/java.rmi/share/classes/java/rmi/Naming.java @@ -28,6 +28,8 @@ import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; +import static jdk.internal.util.Exceptions.filterNonSocketInfo; +import static jdk.internal.util.Exceptions.formatMsg; /** * The Naming class provides methods for storing and obtaining @@ -221,6 +223,10 @@ private static Registry getRegistry(ParsedNamingURL parsed) return LocateRegistry.getRegistry(parsed.host, parsed.port); } + private static MalformedURLException newMalformedURLException(String prefix, String msg) { + return new MalformedURLException(formatMsg(prefix + " %s", filterNonSocketInfo(msg))); + } + /** * Dissect Naming URL strings to obtain referenced host, port and * object name. @@ -240,8 +246,8 @@ private static ParsedNamingURL parseURL(String str) * '//:' forms will result in a URI syntax exception * Convert the authority to a localhost: form */ - MalformedURLException mue = new MalformedURLException( - "invalid URL String: " + str); + MalformedURLException mue = newMalformedURLException( + "invalid URL String:", str); mue.initCause(ex); int indexSchemeEnd = str.indexOf(':'); int indexAuthorityBegin = str.indexOf("//:"); @@ -272,22 +278,22 @@ private static ParsedNamingURL intParseURL(String str) { URI uri = new URI(str); if (uri.isOpaque()) { - throw new MalformedURLException( - "not a hierarchical URL: " + str); + throw newMalformedURLException( + "not a hierarchical URL:", str); } if (uri.getFragment() != null) { - throw new MalformedURLException( - "invalid character, '#', in URL name: " + str); + throw newMalformedURLException( + "invalid character, '#', in URL name:", str); } else if (uri.getQuery() != null) { - throw new MalformedURLException( - "invalid character, '?', in URL name: " + str); + throw newMalformedURLException( + "invalid character, '?', in URL name:", str); } else if (uri.getUserInfo() != null) { - throw new MalformedURLException( - "invalid character, '@', in URL host: " + str); + throw newMalformedURLException( + "invalid character, '@', in URL host:", str); } String scheme = uri.getScheme(); if (scheme != null && !scheme.equals("rmi")) { - throw new MalformedURLException("invalid URL scheme: " + str); + throw newMalformedURLException("invalid URL scheme:", str); } String name = uri.getPath(); From cf5233c14c7db68dde77b8a2abbe9accc58be733 Mon Sep 17 00:00:00 2001 From: Michael McMahon <70538289+Michael-Mc-Mahon@users.noreply.github.com> Date: Fri, 30 May 2025 09:56:54 +0100 Subject: [PATCH 16/22] Apply suggestions from code review Co-authored-by: Daniel Fuchs <67001856+dfuch@users.noreply.github.com> --- .../net/www/protocol/https/HttpsClient.java | 4 ++-- .../classes/sun/nio/ch/NioSocketImpl.java | 2 +- .../classes/sun/nio/ch/SocketAdaptor.java | 2 +- .../classes/com/sun/jndi/ldap/LdapURL.java | 4 ++-- .../classes/com/sun/jndi/toolkit/url/Uri.java | 18 +++++++++--------- .../share/classes/java/rmi/Naming.java | 12 ++++++------ 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java index a8472d490fca8..2f011f5805b43 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java +++ b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java @@ -560,9 +560,9 @@ private void checkURLSpoofing(HostnameVerifier hostnameVerifier) serverSocket.close(); session.invalidate(); - throw new IOException(formatMsg("HTTPS hostname wrong: %s", + throw new IOException(formatMsg("Wrong HTTPS hostname%s", filterNonSocketInfo(url.getHost()) - .prefixWith("should be <") + .prefixWith(": should be <") .suffixWith(">"))); } diff --git a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java index c0ecd1ad089b6..6705134648df4 100644 --- a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java @@ -557,7 +557,7 @@ protected void connect(SocketAddress remote, int millis) throws IOException { InetSocketAddress isa = (InetSocketAddress) remote; if (isa.isUnresolved()) { throw new UnknownHostException( - formatMsg("%s", filterNonSocketInfo(isa.getHostName()))); + formatMsg(filterNonSocketInfo(isa.getHostName()))); } InetAddress address = isa.getAddress(); diff --git a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java index d109089ecd35e..bf777ed23e4a7 100644 --- a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java @@ -96,7 +96,7 @@ public void connect(SocketAddress remote, int timeout) throws IOException { throw new SocketException("Already connected"); close(); throw new UnknownHostException( - formatMsg("%s", filterNonSocketInfo(remote.toString()))); + formatMsg(filterNonSocketInfo(remote.toString()))); } if (timeout < 0) throw new IllegalArgumentException("connect: timeout can't be negative"); diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java index 2d574eb4638a5..d931981880114 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java @@ -121,8 +121,8 @@ public LdapURL(String url) throws NamingException { @Override protected MalformedURLException newInvalidURISchemeException(String uri) { - return new MalformedURLException(formatMsg("Not an LDAP URL: %s", - filterNonSocketInfo(uri))); + return new MalformedURLException(formatMsg("Not an LDAP URL%s", + filterNonSocketInfo(uri).prefixWith(": "))); } @Override diff --git a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java index 8156d257d7988..05779bdfe6fda 100644 --- a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java +++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java @@ -235,7 +235,7 @@ private void parse(String uri, ParseMode mode) throws MalformedURLException { } private MalformedURLException newMalformedURLException(String prefix, String msg) { - return new MalformedURLException(formatMsg(prefix + " %s", filterNonSocketInfo(msg))); + return new MalformedURLException(prefix + formatMsg(filterNonSocketInfo(msg).withPrefix(prefix.isEmpty()? "" : ": ")); } /* @@ -247,7 +247,7 @@ private void parseStrict(String uri) throws MalformedURLException { if (!isSchemeOnly(uri)) { URI u = new URI(uri); scheme = u.getScheme(); - if (scheme == null) throw newMalformedURLException("Invalid URI:", uri); + if (scheme == null) throw newMalformedURLException("Invalid URI", uri); var auth = u.getRawAuthority(); hasAuthority = auth != null; if (hasAuthority) { @@ -259,7 +259,7 @@ private void parseStrict(String uri) throws MalformedURLException { + (port == -1 ? "" : (":" + port)); if (!hostport.equals(auth)) { // throw if we have user info or regname - throw newMalformedURLException("unsupported authority:", auth); + throw newMalformedURLException("unsupported authority", auth); } } path = u.getRawPath(); @@ -268,7 +268,7 @@ private void parseStrict(String uri) throws MalformedURLException { } if (u.getRawFragment() != null) { if (!acceptsFragment()) { - throw newMalformedURLException("URI fragments not supported:", uri); + throw newMalformedURLException("URI fragments not supported", uri); } fragment = "#" + u.getRawFragment(); } @@ -305,11 +305,11 @@ private void parseCompat(String uri) throws MalformedURLException { int qmark = uri.indexOf('?'); int fmark = uri.indexOf('#'); if (i < 0 || slash > 0 && i > slash || qmark > 0 && i > qmark || fmark > 0 && i > fmark) { - throw newMalformedURLException("Invalid URI:", uri); + throw newMalformedURLException("Invalid URI", uri); } if (fmark > -1) { if (!acceptsFragment()) { - throw newMalformedURLException("URI fragments not supported:", uri); + throw newMalformedURLException("URI fragments not supported", uri); } } if (i == uri.length() - 1) { @@ -355,10 +355,10 @@ private void parseCompat(String uri) throws MalformedURLException { String f = u.getRawFragment(); String ui = u.getRawUserInfo(); if (ui != null) { - throw newMalformedURLException("user info not supported in authority:", ui); + throw newMalformedURLException("user info not supported in authority", ui); } if (!"/".equals(p)) { - throw newMalformedURLException("invalid authority:", auth); + throw newMalformedURLException("invalid authority", auth); } if (q != null) { throw newMalformedURLException("invalid trailing characters in authority: ?", q); @@ -371,7 +371,7 @@ private void parseCompat(String uri) throws MalformedURLException { if (!auth.equals(hostport)) { // throw if we have user info or regname throw newMalformedURLException("Authority component is not server-based, " + - "or contains user info. Unsupported authority:", auth); + "or contains user info. Unsupported authority", auth); } } catch (URISyntaxException e) { var mue = newMalformedURLException("", e.getMessage()); diff --git a/src/java.rmi/share/classes/java/rmi/Naming.java b/src/java.rmi/share/classes/java/rmi/Naming.java index f46695c346a6b..b7c646acd2645 100644 --- a/src/java.rmi/share/classes/java/rmi/Naming.java +++ b/src/java.rmi/share/classes/java/rmi/Naming.java @@ -224,7 +224,7 @@ private static Registry getRegistry(ParsedNamingURL parsed) } private static MalformedURLException newMalformedURLException(String prefix, String msg) { - return new MalformedURLException(formatMsg(prefix + " %s", filterNonSocketInfo(msg))); + return new MalformedURLException(prefix + formatMsg(filterNonSocketInfo(msg).prefixWith(": ")); } /** @@ -247,7 +247,7 @@ private static ParsedNamingURL parseURL(String str) * Convert the authority to a localhost: form */ MalformedURLException mue = newMalformedURLException( - "invalid URL String:", str); + "invalid URL String", str); mue.initCause(ex); int indexSchemeEnd = str.indexOf(':'); int indexAuthorityBegin = str.indexOf("//:"); @@ -279,17 +279,17 @@ private static ParsedNamingURL intParseURL(String str) URI uri = new URI(str); if (uri.isOpaque()) { throw newMalformedURLException( - "not a hierarchical URL:", str); + "not a hierarchical URL", str); } if (uri.getFragment() != null) { throw newMalformedURLException( - "invalid character, '#', in URL name:", str); + "invalid character, '#', in URL name", str); } else if (uri.getQuery() != null) { throw newMalformedURLException( - "invalid character, '?', in URL name:", str); + "invalid character, '?', in URL name", str); } else if (uri.getUserInfo() != null) { throw newMalformedURLException( - "invalid character, '@', in URL host:", str); + "invalid character, '@', in URL host", str); } String scheme = uri.getScheme(); if (scheme != null && !scheme.equals("rmi")) { From 462ee0118d2ff312865f1070c8f9d6ec0a0ae2e2 Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Fri, 30 May 2025 10:35:20 +0100 Subject: [PATCH 17/22] typo in suggestions and other issues --- .../share/classes/jdk/internal/util/Exceptions.java | 2 +- .../share/classes/com/sun/jndi/toolkit/url/Uri.java | 4 +++- src/java.rmi/share/classes/java/rmi/Naming.java | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/util/Exceptions.java b/src/java.base/share/classes/jdk/internal/util/Exceptions.java index 6b061a6a4e779..eb4286cd1af9d 100644 --- a/src/java.base/share/classes/jdk/internal/util/Exceptions.java +++ b/src/java.base/share/classes/jdk/internal/util/Exceptions.java @@ -242,7 +242,7 @@ public static String formatMsg(String format, SensitiveInfo... infos) { * Simplification of above. Equivalent to: * formatMsg("%s", SensitiveInfo[1]); // ie with one arg */ - private static String formatMsg(SensitiveInfo info) { + public static String formatMsg(SensitiveInfo info) { return trim(info.output()); } diff --git a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java index 05779bdfe6fda..04c572429772c 100644 --- a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java +++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java @@ -235,7 +235,9 @@ private void parse(String uri, ParseMode mode) throws MalformedURLException { } private MalformedURLException newMalformedURLException(String prefix, String msg) { - return new MalformedURLException(prefix + formatMsg(filterNonSocketInfo(msg).withPrefix(prefix.isEmpty()? "" : ": ")); + return new MalformedURLException(prefix + + formatMsg(filterNonSocketInfo(msg) + .prefixWith(prefix.isEmpty()? "" : ": "))); } /* diff --git a/src/java.rmi/share/classes/java/rmi/Naming.java b/src/java.rmi/share/classes/java/rmi/Naming.java index b7c646acd2645..cb8766564a9af 100644 --- a/src/java.rmi/share/classes/java/rmi/Naming.java +++ b/src/java.rmi/share/classes/java/rmi/Naming.java @@ -224,7 +224,8 @@ private static Registry getRegistry(ParsedNamingURL parsed) } private static MalformedURLException newMalformedURLException(String prefix, String msg) { - return new MalformedURLException(prefix + formatMsg(filterNonSocketInfo(msg).prefixWith(": ")); + return new MalformedURLException( + prefix + formatMsg(filterNonSocketInfo(msg).prefixWith(": "))); } /** @@ -293,7 +294,7 @@ private static ParsedNamingURL intParseURL(String str) } String scheme = uri.getScheme(); if (scheme != null && !scheme.equals("rmi")) { - throw newMalformedURLException("invalid URL scheme:", str); + throw newMalformedURLException("invalid URL scheme", str); } String name = uri.getPath(); From 3eec6c034f7cac0333367dc11fa10ddc22ef563a Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Fri, 30 May 2025 11:41:04 +0100 Subject: [PATCH 18/22] Fixed problem with j.n.HostPortRange --- .../share/classes/java/net/HostPortrange.java | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/java.base/share/classes/java/net/HostPortrange.java b/src/java.base/share/classes/java/net/HostPortrange.java index dada6028ac506..289846841c916 100644 --- a/src/java.base/share/classes/java/net/HostPortrange.java +++ b/src/java.base/share/classes/java/net/HostPortrange.java @@ -59,7 +59,7 @@ public int hashCode() { return hostname.hashCode() + portrange[0] + portrange[1]; } - HostPortrange(String scheme, String hostname) { + HostPortrange(String scheme, String host) { // Parse the host name. A name has up to three components, the // hostname, a port number, or two numbers representing a port // range. "www.example.com:8080-9090" is a valid host name. @@ -74,19 +74,19 @@ public int hashCode() { this.scheme = scheme; // check for IPv6 address - if (hostname.charAt(0) == '[') { + if (host.charAt(0) == '[') { ipv6 = literal = true; - int rb = hostname.indexOf(']'); + int rb = host.indexOf(']'); if (rb != -1) { - hoststr = hostname.substring(1, rb); + hoststr = host.substring(1, rb); } else { throw new IllegalArgumentException( formatMsg("invalid IPv6 address%s", - filterNonSocketInfo(hostname).prefixWith(": "))); + filterNonSocketInfo(host).prefixWith(": "))); } - int sep = hostname.indexOf(':', rb + 1); - if (sep != -1 && hostname.length() > sep) { - portstr = hostname.substring(sep + 1); + int sep = host.indexOf(':', rb + 1); + if (sep != -1 && host.length() > sep) { + portstr = host.substring(sep + 1); } // need to normalize hoststr now byte[] ip = IPAddressUtil.textToNumericFormatV6(hoststr); @@ -99,16 +99,16 @@ public int hashCode() { + "%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7], ip[8], ip[9], ip[10], ip[11], ip[12], ip[13], ip[14], ip[15]); - hostname = sb.toString(); + this.hostname = sb.toString(); } else { // not IPv6 therefore ':' is the port separator - int sep = hostname.indexOf(':'); - if (sep != -1 && hostname.length() > sep) { - hoststr = hostname.substring(0, sep); - portstr = hostname.substring(sep + 1); + int sep = host.indexOf(':'); + if (sep != -1 && host.length() > sep) { + hoststr = host.substring(0, sep); + portstr = host.substring(sep + 1); } else { - hoststr = sep == -1 ? hostname : hostname.substring(0, sep); + hoststr = sep == -1 ? host : host.substring(0, sep); } // is this a domain wildcard specification? if (hoststr.lastIndexOf('*') > 0) { @@ -155,7 +155,7 @@ public int hashCode() { } } } - hostname = hoststr; + this.hostname = hoststr; } try { From 5970c2b348a2f86c32718d3e689619fbe30c9caa Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Fri, 30 May 2025 21:46:51 +0100 Subject: [PATCH 19/22] doc update to java.security --- src/java.base/share/conf/security/java.security | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index ecf463046ee26..e344f43b840da 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -1280,6 +1280,8 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # Exception messages may include potentially sensitive information such as file # names, host names, or port numbers. By default, socket related exceptions # have this information restricted (meaning the sensitive details are removed). +# Exception messages relating to Jar files and exceptions containing user +# identity information are also restricted by default. # This property can be used to relax this restriction or to place further # restrictions on other categories, defined below. The property # accepts one or more comma separated values, each of which represents a @@ -1571,4 +1573,4 @@ jdk.tls.alpnCharset=ISO_8859_1 # java.security.PEMEncoder when configured for encryption with the # withEncryption method. # -jdk.epkcs8.defaultAlgorithm=PBEWithHmacSHA256AndAES_128 \ No newline at end of file +jdk.epkcs8.defaultAlgorithm=PBEWithHmacSHA256AndAES_128 From b582a0f2bf7bf695e31805015d604954d9faea69 Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Fri, 30 May 2025 21:54:01 +0100 Subject: [PATCH 20/22] removed jmod/Handler change --- .../share/classes/sun/net/www/protocol/jmod/Handler.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java b/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java index b097e0fdb9611..51a88cb229d08 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jmod/Handler.java @@ -31,9 +31,6 @@ import java.net.MalformedURLException; import java.io.IOException; -import static jdk.internal.util.Exceptions.filterJarName; -import static jdk.internal.util.Exceptions.formatMsg; - /** * Placeholder protocol handler for the jmod protocol. */ @@ -46,8 +43,7 @@ protected URLConnection openConnection(URL url) throws IOException { String s = url.toString(); int index = s.indexOf("!/"); if (index == -1) - throw new MalformedURLException( - formatMsg("no !/ found in url spec%s", filterJarName(s).prefixWith(": "))); + throw new MalformedURLException("no !/ found in url spec:" + s); throw new IOException("Can't connect to jmod URL"); } From 4aad0141de9e69023cf55ecc9399d270864f906c Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Fri, 30 May 2025 21:55:17 +0100 Subject: [PATCH 21/22] doc update to java.security --- src/java.base/share/conf/security/java.security | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index e344f43b840da..61e8aaaf6d11c 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -1280,7 +1280,7 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # Exception messages may include potentially sensitive information such as file # names, host names, or port numbers. By default, socket related exceptions # have this information restricted (meaning the sensitive details are removed). -# Exception messages relating to Jar files and exceptions containing user +# Exception messages relating to JAR files and exceptions containing user # identity information are also restricted by default. # This property can be used to relax this restriction or to place further # restrictions on other categories, defined below. The property From 1a6f5af2e4061df5baf9e2b6029419cd64fdd240 Mon Sep 17 00:00:00 2001 From: Michael-Mc-Mahon Date: Tue, 3 Jun 2025 15:20:46 +0100 Subject: [PATCH 22/22] uodate to JNDI --- .../share/classes/com/sun/jndi/toolkit/url/Uri.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java index 04c572429772c..a4db62868b068 100644 --- a/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java +++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/url/Uri.java @@ -363,10 +363,10 @@ private void parseCompat(String uri) throws MalformedURLException { throw newMalformedURLException("invalid authority", auth); } if (q != null) { - throw newMalformedURLException("invalid trailing characters in authority: ?", q); + throw newMalformedURLException("invalid trailing characters in authority '?'", "?" + q); } if (f != null) { - throw newMalformedURLException("invalid trailing characters in authority: #", f); + throw newMalformedURLException("invalid trailing characters in authority: '#'", "#" + f); } String hostport = (host == null ? "" : host) + (port == -1?"":(":" + port));