8344299: SM cleanup in javax.naming modules

Reviewed-by: alanb, dfuchs
This commit is contained in:
Aleksei Efimov 2024-11-28 17:43:27 +00:00
parent 43000a34d5
commit 959fa4a1a3
24 changed files with 88 additions and 382 deletions

View file

@ -96,10 +96,6 @@ public final class SecurityConstants {
public static final RuntimePermission GET_PD_PERMISSION = public static final RuntimePermission GET_PD_PERMISSION =
new RuntimePermission("getProtectionDomain"); new RuntimePermission("getProtectionDomain");
// java.lang.Class, java.lang.ClassLoader, java.lang.Thread
public static final RuntimePermission GET_CLASSLOADER_PERMISSION =
new RuntimePermission("getClassLoader");
// java.lang.Thread // java.lang.Thread
public static final RuntimePermission GET_STACK_TRACE_PERMISSION = public static final RuntimePermission GET_STACK_TRACE_PERMISSION =
new RuntimePermission("getStackTrace"); new RuntimePermission("getStackTrace");

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -84,8 +84,8 @@ class ClientId {
if ((socketFactory != null) && if ((socketFactory != null) &&
!socketFactory.equals(LdapCtx.DEFAULT_SSL_FACTORY)) { !socketFactory.equals(LdapCtx.DEFAULT_SSL_FACTORY)) {
try { try {
Class<?> socketFactoryClass = Class<?> socketFactoryClass = Class.forName(socketFactory,
Obj.helper.loadClass(socketFactory); true, Thread.currentThread().getContextClassLoader());
this.sockComparator = socketFactoryClass.getMethod( this.sockComparator = socketFactoryClass.getMethod(
"compare", new Class<?>[]{Object.class, Object.class}); "compare", new Class<?>[]{Object.class, Object.class});
Method getDefault = socketFactoryClass.getMethod( Method getDefault = socketFactoryClass.getMethod(

View file

@ -44,8 +44,6 @@ import javax.naming.ldap.Control;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.Arrays; import java.util.Arrays;
@ -183,10 +181,8 @@ public final class Connection implements Runnable {
= hostnameVerificationDisabledValue(); = hostnameVerificationDisabledValue();
private static boolean hostnameVerificationDisabledValue() { private static boolean hostnameVerificationDisabledValue() {
PrivilegedAction<String> act = () -> System.getProperty( String prop = System.getProperty(
"com.sun.jndi.ldap.object.disableEndpointIdentification"); "com.sun.jndi.ldap.object.disableEndpointIdentification");
@SuppressWarnings("removal")
String prop = AccessController.doPrivileged(act);
if (prop == null) { if (prop == null) {
return false; return false;
} }
@ -259,7 +255,7 @@ public final class Connection implements Runnable {
throw ce; throw ce;
} }
worker = Obj.helper.createThread(this); worker = new Thread(this);
worker.setDaemon(true); worker.setDaemon(true);
worker.start(); worker.start();
} }
@ -313,7 +309,8 @@ public final class Connection implements Runnable {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Class<? extends SocketFactory> socketFactoryClass = Class<? extends SocketFactory> socketFactoryClass =
(Class<? extends SocketFactory>) Obj.helper.loadClass(socketFactoryName); (Class<? extends SocketFactory>) Class.forName(socketFactoryName,
true, Thread.currentThread().getContextClassLoader());
Method getDefault = Method getDefault =
socketFactoryClass.getMethod("getDefault"); socketFactoryClass.getMethod("getDefault");
SocketFactory factory = (SocketFactory) getDefault.invoke(null, new Object[]{}); SocketFactory factory = (SocketFactory) getDefault.invoke(null, new Object[]{});

View file

@ -71,7 +71,7 @@ final class EventQueue implements Runnable {
// package private // package private
EventQueue() { EventQueue() {
qThread = Obj.helper.createThread(this); qThread = new Thread(this);
qThread.setDaemon(true); // not a user thread qThread.setDaemon(true); // not a user thread
qThread.start(); qThread.start();
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,10 +25,6 @@
package com.sun.jndi.ldap; package com.sun.jndi.ldap;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Vector; import java.util.Vector;
import javax.naming.*; import javax.naming.*;
import javax.naming.directory.*; import javax.naming.directory.*;
@ -41,16 +37,12 @@ import com.sun.naming.internal.ObjectFactoriesFilter;
final class LdapBindingEnumeration final class LdapBindingEnumeration
extends AbstractLdapNamingEnumeration<Binding> { extends AbstractLdapNamingEnumeration<Binding> {
@SuppressWarnings("removal")
private final AccessControlContext acc = AccessController.getContext();
LdapBindingEnumeration(LdapCtx homeCtx, LdapResult answer, Name remain, LdapBindingEnumeration(LdapCtx homeCtx, LdapResult answer, Name remain,
Continuation cont) throws NamingException Continuation cont) throws NamingException
{ {
super(homeCtx, answer, remain, cont); super(homeCtx, answer, remain, cont);
} }
@SuppressWarnings("removal")
@Override @Override
protected Binding protected Binding
createItem(String dn, Attributes attrs, Vector<Control> respCtls) createItem(String dn, Attributes attrs, Vector<Control> respCtls)
@ -61,12 +53,7 @@ final class LdapBindingEnumeration
if (attrs.get(Obj.JAVA_ATTRIBUTES[Obj.CLASSNAME]) != null) { if (attrs.get(Obj.JAVA_ATTRIBUTES[Obj.CLASSNAME]) != null) {
// serialized object or object reference // serialized object or object reference
try { obj = Obj.decodeObject(attrs);
PrivilegedExceptionAction<Object> pa = () -> Obj.decodeObject(attrs);
obj = AccessController.doPrivileged(pa, acc);
} catch (PrivilegedActionException e) {
throw (NamingException)e.getException();
}
} }
if (obj == null) { if (obj == null) {
// DirContext object // DirContext object

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -32,8 +32,6 @@ import javax.naming.ldap.*;
import javax.naming.ldap.LdapName; import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn; import javax.naming.ldap.Rdn;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Locale; import java.util.Locale;
@ -220,7 +218,7 @@ public final class LdapCtx extends ComponentDirContext
// System property value // System property value
private static final String ALLOWED_MECHS_SP_VALUE = private static final String ALLOWED_MECHS_SP_VALUE =
getMechsAllowedToSendCredentials(); System.getProperty(ALLOWED_MECHS_SP);
// Set of authentication mechanisms allowed by the system property // Set of authentication mechanisms allowed by the system property
private static final Set<String> MECHS_ALLOWED_BY_SP = private static final Set<String> MECHS_ALLOWED_BY_SP =
@ -2706,13 +2704,6 @@ public final class LdapCtx extends ComponentDirContext
ensureOpen(); // open or reauthenticated ensureOpen(); // open or reauthenticated
} }
// Load 'mechsAllowedToSendCredentials' system property value
@SuppressWarnings("removal")
private static String getMechsAllowedToSendCredentials() {
PrivilegedAction<String> pa = () -> System.getProperty(ALLOWED_MECHS_SP);
return System.getSecurityManager() == null ? pa.run() : AccessController.doPrivileged(pa);
}
// Get set of allowed authentication mechanism names from the property value // Get set of allowed authentication mechanism names from the property value
private static Set<String> getMechsFromPropertyValue(String propValue) { private static Set<String> getMechsFromPropertyValue(String propValue) {
if (propValue == null || propValue.isBlank()) { if (propValue == null || propValue.isBlank()) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,14 +25,11 @@
package com.sun.jndi.ldap; package com.sun.jndi.ldap;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*; import java.util.*;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import javax.naming.NamingException; import javax.naming.NamingException;
import javax.naming.ldap.spi.LdapDnsProvider; import javax.naming.ldap.spi.LdapDnsProvider;
import javax.naming.ldap.spi.LdapDnsProviderResult; import javax.naming.ldap.spi.LdapDnsProviderResult;
import sun.security.util.SecurityConstants;
/** /**
* The {@code LdapDnsProviderService} is responsible for creating and providing * The {@code LdapDnsProviderService} is responsible for creating and providing
@ -50,25 +47,10 @@ final class LdapDnsProviderService {
/** /**
* Creates a new instance of LdapDnsProviderService * Creates a new instance of LdapDnsProviderService
*/ */
@SuppressWarnings("removal")
private LdapDnsProviderService() { private LdapDnsProviderService() {
SecurityManager sm = System.getSecurityManager(); providers = ServiceLoader.load(
if (sm == null) { LdapDnsProvider.class,
providers = ServiceLoader.load( ClassLoader.getSystemClassLoader());
LdapDnsProvider.class,
ClassLoader.getSystemClassLoader());
} else {
final PrivilegedAction<ServiceLoader<LdapDnsProvider>> pa =
() -> ServiceLoader.load(
LdapDnsProvider.class,
ClassLoader.getSystemClassLoader());
providers = AccessController.doPrivileged(
pa,
null,
new RuntimePermission("ldapDnsProvider"),
SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
} }
/** /**

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -34,8 +34,6 @@ import java.util.StringTokenizer;
import javax.naming.ldap.Control; import javax.naming.ldap.Control;
import javax.naming.NamingException; import javax.naming.NamingException;
import javax.naming.CommunicationException; import javax.naming.CommunicationException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import com.sun.jndi.ldap.pool.PoolCleaner; import com.sun.jndi.ldap.pool.PoolCleaner;
import com.sun.jndi.ldap.pool.Pool; import com.sun.jndi.ldap.pool.Pool;
@ -60,10 +58,10 @@ public final class LdapPoolManager {
"com.sun.jndi.ldap.connect.pool.debug"; "com.sun.jndi.ldap.connect.pool.debug";
public static final boolean debug = public static final boolean debug =
"all".equalsIgnoreCase(getProperty(DEBUG, null)); "all".equalsIgnoreCase(System.getProperty(DEBUG));
public static final boolean trace = debug || public static final boolean trace = debug ||
"fine".equalsIgnoreCase(getProperty(DEBUG, null)); "fine".equalsIgnoreCase(System.getProperty(DEBUG));
// ---------- System properties for connection pooling // ---------- System properties for connection pooling
@ -120,16 +118,16 @@ public final class LdapPoolManager {
private static final Pool[] pools = new Pool[3]; private static final Pool[] pools = new Pool[3];
static { static {
maxSize = getInteger(MAX_POOL_SIZE, DEFAULT_MAX_POOL_SIZE); maxSize = Integer.getInteger(MAX_POOL_SIZE, DEFAULT_MAX_POOL_SIZE);
prefSize = getInteger(PREF_POOL_SIZE, DEFAULT_PREF_POOL_SIZE); prefSize = Integer.getInteger(PREF_POOL_SIZE, DEFAULT_PREF_POOL_SIZE);
initSize = getInteger(INIT_POOL_SIZE, DEFAULT_INIT_POOL_SIZE); initSize = Integer.getInteger(INIT_POOL_SIZE, DEFAULT_INIT_POOL_SIZE);
idleTimeout = getLong(POOL_TIMEOUT, DEFAULT_TIMEOUT); idleTimeout = Long.getLong(POOL_TIMEOUT, DEFAULT_TIMEOUT);
// Determine supported authentication mechanisms // Determine supported authentication mechanisms
String str = getProperty(POOL_AUTH, DEFAULT_AUTH_MECHS); String str = System.getProperty(POOL_AUTH, DEFAULT_AUTH_MECHS);
StringTokenizer parser = new StringTokenizer(str); StringTokenizer parser = new StringTokenizer(str);
int count = parser.countTokens(); int count = parser.countTokens();
String mech; String mech;
@ -147,7 +145,7 @@ public final class LdapPoolManager {
} }
// Determine supported protocols // Determine supported protocols
str= getProperty(POOL_PROTOCOL, DEFAULT_PROTOCOLS); str = System.getProperty(POOL_PROTOCOL, DEFAULT_PROTOCOLS);
parser = new StringTokenizer(str); parser = new StringTokenizer(str);
count = parser.countTokens(); count = parser.countTokens();
String proto; String proto;
@ -171,20 +169,15 @@ public final class LdapPoolManager {
} }
} }
@SuppressWarnings("removal")
private static void startCleanerThread() { private static void startCleanerThread() {
// Create cleaner to expire idle connections // Create cleaner to expire idle connections
PrivilegedAction<Void> pa = new PrivilegedAction<Void>() { Thread t = InnocuousThread.newSystemThread(
public Void run() { "LDAP PoolCleaner",
Thread t = InnocuousThread.newSystemThread( new PoolCleaner(idleTimeout, pools));
"LDAP PoolCleaner", assert t.getContextClassLoader() == null;
new PoolCleaner(idleTimeout, pools)); t.setDaemon(true);
assert t.getContextClassLoader() == null; t.start();
t.setDaemon(true);
t.start();
return null;
}};
AccessController.doPrivileged(pa);
} }
// Cannot instantiate one of these // Cannot instantiate one of these
@ -252,7 +245,8 @@ public final class LdapPoolManager {
if ((socketFactory != null) && if ((socketFactory != null) &&
!socketFactory.equals(LdapCtx.DEFAULT_SSL_FACTORY)) { !socketFactory.equals(LdapCtx.DEFAULT_SSL_FACTORY)) {
try { try {
Class<?> socketFactoryClass = Obj.helper.loadClass(socketFactory); Class<?> socketFactoryClass = Class.forName(socketFactory, true,
Thread.currentThread().getContextClassLoader());
Class<?>[] interfaces = socketFactoryClass.getInterfaces(); Class<?>[] interfaces = socketFactoryClass.getInterfaces();
for (int i = 0; i < interfaces.length; i++) { for (int i = 0; i < interfaces.length; i++) {
if (interfaces[i].getCanonicalName().equals(COMPARATOR)) { if (interfaces[i].getCanonicalName().equals(COMPARATOR)) {
@ -399,22 +393,4 @@ public final class LdapPoolManager {
System.err.println("LdapPoolManager: " + msg + o); System.err.println("LdapPoolManager: " + msg + o);
} }
} }
@SuppressWarnings("removal")
private static final String getProperty(final String propName, final String defVal) {
PrivilegedAction<String> pa = () -> System.getProperty(propName, defVal);
return AccessController.doPrivileged(pa);
}
@SuppressWarnings("removal")
private static final int getInteger(final String propName, final int defVal) {
PrivilegedAction<Integer> pa = () -> Integer.getInteger(propName, defVal);
return AccessController.doPrivileged(pa);
}
@SuppressWarnings("removal")
private static final long getLong(final String propName, final long defVal) {
PrivilegedAction<Long> pa = () -> Long.getLong(propName, defVal);
return AccessController.doPrivileged(pa);
}
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,10 +25,6 @@
package com.sun.jndi.ldap; package com.sun.jndi.ldap;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Vector; import java.util.Vector;
import javax.naming.*; import javax.naming.*;
import javax.naming.directory.*; import javax.naming.directory.*;
@ -45,9 +41,6 @@ final class LdapSearchEnumeration
private Name startName; // prefix of names of search results private Name startName; // prefix of names of search results
private LdapCtx.SearchArgs searchArgs = null; private LdapCtx.SearchArgs searchArgs = null;
@SuppressWarnings("removal")
private final AccessControlContext acc = AccessController.getContext();
LdapSearchEnumeration(LdapCtx homeCtx, LdapResult search_results, LdapSearchEnumeration(LdapCtx homeCtx, LdapResult search_results,
String starter, LdapCtx.SearchArgs args, Continuation cont) String starter, LdapCtx.SearchArgs args, Continuation cont)
throws NamingException { throws NamingException {
@ -61,7 +54,6 @@ final class LdapSearchEnumeration
searchArgs = args; searchArgs = args;
} }
@SuppressWarnings("removal")
@Override @Override
protected SearchResult createItem(String dn, Attributes attrs, protected SearchResult createItem(String dn, Attributes attrs,
Vector<Control> respCtls) Vector<Control> respCtls)
@ -121,12 +113,7 @@ final class LdapSearchEnumeration
if (attrs.get(Obj.JAVA_ATTRIBUTES[Obj.CLASSNAME]) != null) { if (attrs.get(Obj.JAVA_ATTRIBUTES[Obj.CLASSNAME]) != null) {
// Entry contains Java-object attributes (ser/ref object) // Entry contains Java-object attributes (ser/ref object)
// serialized object or object reference // serialized object or object reference
try { obj = Obj.decodeObject(attrs);
PrivilegedExceptionAction<Object> pea = () -> Obj.decodeObject(attrs);
obj = AccessController.doPrivileged(pea, acc);
} catch (PrivilegedActionException e) {
throw (NamingException)e.getException();
}
} }
if (obj == null) { if (obj == null) {
obj = new LdapCtx(homeCtx, dn); obj = new LdapCtx(homeCtx, dn);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,8 +29,6 @@ import javax.naming.*;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URI; import java.net.URI;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Locale; import java.util.Locale;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import com.sun.jndi.toolkit.url.Uri; import com.sun.jndi.toolkit.url.Uri;
@ -73,12 +71,9 @@ public final class LdapURL extends Uri {
public static final ParseMode PARSE_MODE; public static final ParseMode PARSE_MODE;
static { static {
PrivilegedAction<String> action = () ->
System.getProperty(PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString());
ParseMode parseMode = DEFAULT_PARSE_MODE; ParseMode parseMode = DEFAULT_PARSE_MODE;
try { try {
@SuppressWarnings("removal") String mode = System.getProperty(PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString());
String mode = AccessController.doPrivileged(action);
parseMode = ParseMode.valueOf(mode.toUpperCase(Locale.ROOT)); parseMode = ParseMode.valueOf(mode.toUpperCase(Locale.ROOT));
} catch (Throwable t) { } catch (Throwable t) {
parseMode = DEFAULT_PARSE_MODE; parseMode = DEFAULT_PARSE_MODE;

View file

@ -86,7 +86,7 @@ final class NamingEventNotifier implements Runnable {
namingListeners = new Vector<>(); namingListeners = new Vector<>();
namingListeners.addElement(firstListener); namingListeners.addElement(firstListener);
worker = Obj.helper.createThread(this); worker = new Thread(this);
worker.setDaemon(true); // not a user thread worker.setDaemon(true); // not a user thread
worker.start(); worker.start();
} }

View file

@ -57,8 +57,19 @@ final class Obj {
private Obj () {}; // Make sure no one can create one private Obj () {}; // Make sure no one can create one
// package private; used by Connection /**
static VersionHelper helper = VersionHelper.getVersionHelper(); * Determines whether objects may be deserialized or reconstructed from a content of
* 'javaSerializedData', 'javaRemoteLocation' or 'javaReferenceAddress' LDAP attributes.
*/
private static final boolean trustSerialData;
static {
// System property to control whether classes are allowed to be loaded from
// 'javaSerializedData', 'javaRemoteLocation' or 'javaReferenceAddress' attributes.
String trustSerialDataSp = System.getProperty(
"com.sun.jndi.ldap.object.trustSerialData", "false");
trustSerialData = "true".equalsIgnoreCase(trustSerialDataSp);
}
// LDAP attributes used to support Java objects. // LDAP attributes used to support Java objects.
static final String[] JAVA_ATTRIBUTES = { static final String[] JAVA_ATTRIBUTES = {
@ -233,14 +244,14 @@ final class Obj {
String[] codebases = getCodebases(attrs.get(JAVA_ATTRIBUTES[CODEBASE])); String[] codebases = getCodebases(attrs.get(JAVA_ATTRIBUTES[CODEBASE]));
try { try {
if ((attr = attrs.get(JAVA_ATTRIBUTES[SERIALIZED_DATA])) != null) { if ((attr = attrs.get(JAVA_ATTRIBUTES[SERIALIZED_DATA])) != null) {
if (!VersionHelper.isSerialDataAllowed()) { if (!trustSerialData) {
throw new NamingException("Object deserialization is not allowed"); throw new NamingException("Object deserialization is not allowed");
} }
ClassLoader cl = Thread.currentThread().getContextClassLoader(); ClassLoader cl = Thread.currentThread().getContextClassLoader();
return deserializeObject((byte[])attr.get(), cl); return deserializeObject((byte[])attr.get(), cl);
} else if ((attr = attrs.get(JAVA_ATTRIBUTES[REMOTE_LOC])) != null) { } else if ((attr = attrs.get(JAVA_ATTRIBUTES[REMOTE_LOC])) != null) {
// javaRemoteLocation attribute (RMI stub will be created) // javaRemoteLocation attribute (RMI stub will be created)
if (!VersionHelper.isSerialDataAllowed()) { if (!trustSerialData) {
throw new NamingException("Object deserialization is not allowed"); throw new NamingException("Object deserialization is not allowed");
} }
// For backward compatibility only // For backward compatibility only
@ -471,7 +482,7 @@ final class Obj {
} else if (val.charAt(start) == separator) { } else if (val.charAt(start) == separator) {
// Check if deserialization of binary RefAddr is allowed from // Check if deserialization of binary RefAddr is allowed from
// 'javaReferenceAddress' LDAP attribute. // 'javaReferenceAddress' LDAP attribute.
if (!VersionHelper.isSerialDataAllowed()) { if (!trustSerialData) {
throw new NamingException("Object deserialization is not allowed"); throw new NamingException("Object deserialization is not allowed");
} }

View file

@ -1,72 +0,0 @@
/*
* Copyright (c) 1999, 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 com.sun.jndi.ldap;
public final class VersionHelper {
private static final VersionHelper helper = new VersionHelper();
/**
* Determines whether objects may be deserialized or reconstructed from a content of
* 'javaSerializedData', 'javaRemoteLocation' or 'javaReferenceAddress' LDAP attributes.
*/
private static final boolean trustSerialData;
static {
// System property to control whether classes are allowed to be loaded from
// 'javaSerializedData', 'javaRemoteLocation' or 'javaReferenceAddress' attributes.
String trustSerialDataSp = System.getProperty(
"com.sun.jndi.ldap.object.trustSerialData", "false");
trustSerialData = "true".equalsIgnoreCase(trustSerialDataSp);
}
private VersionHelper() {
}
static VersionHelper getVersionHelper() {
return helper;
}
/**
* Returns true if deserialization or reconstruction of objects from
* 'javaSerializedData', 'javaRemoteLocation' and 'javaReferenceAddress'
* LDAP attributes is allowed.
*
* @return true if deserialization is allowed; false - otherwise
*/
public static boolean isSerialDataAllowed() {
return trustSerialData;
}
Class<?> loadClass(String className) throws ClassNotFoundException {
return Class.forName(className, true,
Thread.currentThread().getContextClassLoader());
}
Thread createThread(Runnable r) {
return new Thread(r);
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,13 +26,10 @@
package javax.naming.ldap; package javax.naming.ldap;
import java.util.Iterator; import java.util.Iterator;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import javax.naming.NamingException; import javax.naming.NamingException;
import com.sun.naming.internal.VersionHelper; import com.sun.naming.internal.VersionHelper;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.ServiceConfigurationError;
/** /**
* This class implements the LDAPv3 Extended Request for StartTLS as * This class implements the LDAPv3 Extended Request for StartTLS as
@ -181,10 +178,10 @@ public class StartTlsRequest implements ExtendedRequest {
StartTlsResponse resp = null; StartTlsResponse resp = null;
ServiceLoader<StartTlsResponse> sl = ServiceLoader.load( ServiceLoader<StartTlsResponse> sl = ServiceLoader.load(
StartTlsResponse.class, getContextClassLoader()); StartTlsResponse.class, Thread.currentThread().getContextClassLoader());
Iterator<StartTlsResponse> iter = sl.iterator(); Iterator<StartTlsResponse> iter = sl.iterator();
while (resp == null && privilegedHasNext(iter)) { while (resp == null && iter.hasNext()) {
resp = iter.next(); resp = iter.next();
} }
if (resp != null) { if (resp != null) {
@ -216,20 +213,5 @@ public class StartTlsRequest implements ExtendedRequest {
return ce; return ce;
} }
/*
* Acquire the class loader associated with this thread.
*/
@SuppressWarnings("removal")
private final ClassLoader getContextClassLoader() {
PrivilegedAction<ClassLoader> pa = Thread.currentThread()::getContextClassLoader;
return AccessController.doPrivileged(pa);
}
@SuppressWarnings("removal")
private static final boolean privilegedHasNext(final Iterator<StartTlsResponse> iter) {
PrivilegedAction<Boolean> pa = iter::hasNext;
return AccessController.doPrivileged(pa);
}
private static final long serialVersionUID = 4441679576360753397L; private static final long serialVersionUID = 4441679576360753397L;
} }

View file

@ -53,29 +53,10 @@ import java.util.Optional;
*/ */
public abstract class LdapDnsProvider { public abstract class LdapDnsProvider {
// The {@code RuntimePermission("ldapDnsProvider")} is
// necessary to subclass and instantiate the {@code LdapDnsProvider} class.
private static final RuntimePermission DNSPROVIDER_PERMISSION =
new RuntimePermission("ldapDnsProvider");
/** /**
* Creates a new instance of {@code LdapDnsProvider}. * Creates a new instance of {@code LdapDnsProvider}.
*/ */
protected LdapDnsProvider() { protected LdapDnsProvider() {
this(checkPermission());
}
private LdapDnsProvider(Void unused) {
// nothing to do.
}
private static Void checkPermission() {
@SuppressWarnings("removal")
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(DNSPROVIDER_PERMISSION);
}
return null;
} }
/** /**

View file

@ -25,8 +25,6 @@
package javax.naming.spi; package javax.naming.spi;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*; import java.util.*;
import javax.naming.*; import javax.naming.*;
@ -471,7 +469,6 @@ public class NamingManager {
* @see javax.naming.InitialContext * @see javax.naming.InitialContext
* @see javax.naming.directory.InitialDirContext * @see javax.naming.directory.InitialDirContext
*/ */
@SuppressWarnings("removal")
public static Context getInitialContext(Hashtable<?,?> env) public static Context getInitialContext(Hashtable<?,?> env)
throws NamingException { throws NamingException {
ClassLoader loader; ClassLoader loader;
@ -492,16 +489,8 @@ public class NamingManager {
throw ne; throw ne;
} }
if (System.getSecurityManager() == null) { loader = Thread.currentThread().getContextClassLoader();
loader = Thread.currentThread().getContextClassLoader(); if (loader == null) loader = ClassLoader.getSystemClassLoader();
if (loader == null) loader = ClassLoader.getSystemClassLoader();
} else {
PrivilegedAction<ClassLoader> pa = () -> {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
return (cl == null) ? ClassLoader.getSystemClassLoader() : cl;
};
loader = AccessController.doPrivileged(pa);
}
var key = FACTORIES_CACHE.sub(className); var key = FACTORIES_CACHE.sub(className);
try { try {
@ -570,12 +559,6 @@ public class NamingManager {
if (initctx_factory_builder != null) if (initctx_factory_builder != null)
throw new IllegalStateException( throw new IllegalStateException(
"InitialContextFactoryBuilder already set"); "InitialContextFactoryBuilder already set");
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkSetFactory();
}
initctx_factory_builder = builder; initctx_factory_builder = builder;
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -69,25 +69,20 @@ public final class JdkLDAP extends Provider {
} }
} }
@SuppressWarnings("removal")
public JdkLDAP() { public JdkLDAP() {
super("JdkLDAP", PROVIDER_VER, "JdkLDAP Provider (implements LDAP CertStore)"); super("JdkLDAP", PROVIDER_VER, "JdkLDAP Provider (implements LDAP CertStore)");
final Provider p = this; final Provider p = this;
PrivilegedAction<Void> pa = () -> { HashMap<String, String> attrs = new HashMap<>(2);
HashMap<String, String> attrs = new HashMap<>(2); attrs.put("LDAPSchema", "RFC2587");
attrs.put("LDAPSchema", "RFC2587"); attrs.put("ImplementedIn", "Software");
attrs.put("ImplementedIn", "Software");
/* /*
* CertStore * CertStore
* attrs: LDAPSchema, ImplementedIn * attrs: LDAPSchema, ImplementedIn
*/ */
putService(new ProviderService(p, "CertStore", putService(new ProviderService(p, "CertStore",
"LDAP", "sun.security.provider.certpath.ldap.LDAPCertStore", "LDAP", "sun.security.provider.certpath.ldap.LDAPCertStore",
null, attrs)); null, attrs));
return null;
};
AccessController.doPrivileged(pa);
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -136,12 +136,6 @@ public final class LDAPCertStore extends CertStoreSpi {
+ params.getClass().getName() + " passed"); + params.getClass().getName() + " passed");
} }
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkConnect(serverName, port);
}
Key k = new Key(serverName, port); Key k = new Key(serverName, port);
LDAPCertStoreImpl lci = certStoreCache.get(k); LDAPCertStoreImpl lci = certStoreCache.get(k);
if (lci == null) { if (lci == null) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -97,9 +97,7 @@ final class LDAPCertStoreImpl {
"sun.security.certpath.ldap.disable.app.resource.files"; "sun.security.certpath.ldap.disable.app.resource.files";
static { static {
@SuppressWarnings("removal") String s = System.getProperty(PROP_LIFETIME);
String s = AccessController.doPrivileged(
(PrivilegedAction<String>) () -> System.getProperty(PROP_LIFETIME));
if (s != null) { if (s != null) {
LIFETIME = Integer.parseInt(s); // throws NumberFormatException LIFETIME = Integer.parseInt(s); // throws NumberFormatException
} else { } else {
@ -172,9 +170,8 @@ final class LDAPCertStoreImpl {
env.put(Context.PROVIDER_URL, url); env.put(Context.PROVIDER_URL, url);
// If property is set to true, disable application resource file lookup. // If property is set to true, disable application resource file lookup.
@SuppressWarnings("removal") boolean disableAppResourceFiles =
boolean disableAppResourceFiles = AccessController.doPrivileged( Boolean.getBoolean(PROP_DISABLE_APP_RESOURCE_FILES);
(PrivilegedAction<Boolean>) () -> Boolean.getBoolean(PROP_DISABLE_APP_RESOURCE_FILES));
if (disableAppResourceFiles) { if (disableAppResourceFiles) {
if (debug != null) { if (debug != null) {
debug.println("LDAPCertStore disabling app resource files"); debug.println("LDAPCertStore disabling app resource files");

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,8 +29,6 @@ import java.net.DatagramSocket;
import java.net.ProtocolFamily; import java.net.ProtocolFamily;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.nio.channels.DatagramChannel; import java.nio.channels.DatagramChannel;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.Objects; import java.util.Objects;
import java.util.Random; import java.util.Random;
@ -52,11 +50,9 @@ class DNSDatagramChannelFactory {
} }
private static int findFirstFreePort() { private static int findFirstFreePort() {
PrivilegedExceptionAction<DatagramSocket> action = () -> new DatagramSocket(0);
int port; int port;
try { try {
@SuppressWarnings({"deprecated", "removal"}) DatagramSocket ds = new DatagramSocket(0);
DatagramSocket ds = AccessController.doPrivileged(action);
try (DatagramSocket ds1 = ds) { try (DatagramSocket ds1 = ds) {
port = ds1.getLocalPort(); port = ds1.getLocalPort();
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -90,9 +90,8 @@ public class DnsContextFactory implements InitialContextFactory {
* Public for use by product test suite. * Public for use by product test suite.
*/ */
public static boolean platformServersAvailable() { public static boolean platformServersAvailable() {
return !filterNameServers( return !ResolverConfiguration
ResolverConfiguration.open().nameservers(), true .open().nameservers().isEmpty();
).isEmpty();
} }
private static Context urlToContext(String url, Hashtable<?,?> env) private static Context urlToContext(String url, Hashtable<?,?> env)
@ -145,8 +144,8 @@ public class DnsContextFactory implements InitialContextFactory {
// No server or port given, so look to underlying platform. // No server or port given, so look to underlying platform.
// ResolverConfiguration does some limited caching, so the // ResolverConfiguration does some limited caching, so the
// following is reasonably efficient even if called rapid-fire. // following is reasonably efficient even if called rapid-fire.
List<String> platformServers = filterNameServers( List<String> platformServers =
ResolverConfiguration.open().nameservers(), false); ResolverConfiguration.open().nameservers();
if (!platformServers.isEmpty()) { if (!platformServers.isEmpty()) {
servers.addAll(platformServers); servers.addAll(platformServers);
continue; // on to next URL (if any, which is unlikely) continue; // on to next URL (if any, which is unlikely)
@ -216,42 +215,4 @@ public class DnsContextFactory implements InitialContextFactory {
String url = (String) env.get(Context.PROVIDER_URL); String url = (String) env.get(Context.PROVIDER_URL);
return ((url != null) ? url : DEFAULT_URL); return ((url != null) ? url : DEFAULT_URL);
} }
/**
* Removes any DNS server that's not permitted to access
* @param input the input server[:port] list, must not be null
* @param oneIsEnough return output once there exists one ok
* @return the filtered list, all non-permitted input removed
*/
private static List<String> filterNameServers(List<String> input, boolean oneIsEnough) {
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security == null || input == null || input.isEmpty()) {
return input;
} else {
List<String> output = new ArrayList<>();
for (String platformServer: input) {
int colon = platformServer.indexOf(':',
platformServer.indexOf(']') + 1);
int p = (colon < 0)
? DEFAULT_PORT
: Integer.parseInt(
platformServer.substring(colon + 1));
String s = (colon < 0)
? platformServer
: platformServer.substring(0, colon);
try {
security.checkConnect(s, p);
output.add(platformServer);
if (oneIsEnough) {
return output;
}
} catch (SecurityException se) {
continue;
}
}
return output;
}
}
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,8 +29,6 @@ package com.sun.jndi.dns;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Locale; import java.util.Locale;
import java.util.StringTokenizer; import java.util.StringTokenizer;
@ -65,12 +63,10 @@ public class DnsUrl extends Uri {
public static final ParseMode PARSE_MODE; public static final ParseMode PARSE_MODE;
static { static {
PrivilegedAction<String> action = () ->
System.getProperty(PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString());
ParseMode parseMode = DEFAULT_PARSE_MODE; ParseMode parseMode = DEFAULT_PARSE_MODE;
try { try {
@SuppressWarnings("removal") String mode = System.getProperty(
String mode = AccessController.doPrivileged(action); PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString());
parseMode = ParseMode.valueOf(mode.toUpperCase(Locale.ROOT)); parseMode = ParseMode.valueOf(mode.toUpperCase(Locale.ROOT));
} catch (Throwable t) { } catch (Throwable t) {
parseMode = DEFAULT_PARSE_MODE; parseMode = DEFAULT_PARSE_MODE;

View file

@ -58,11 +58,6 @@ public class RegistryContext implements Context, Referenceable {
Reference reference = null; // ref used to create this context, if any Reference reference = null; // ref used to create this context, if any
// Environment property that, if set, indicates that a security
// manager should be installed (if none is already in place).
public static final String SECURITY_MGR =
"java.naming.rmi.security.manager";
/** /**
* Returns a context for the registry at a given host and port. * Returns a context for the registry at a given host and port.
* If "host" is null, uses default host. * If "host" is null, uses default host.
@ -77,9 +72,6 @@ public class RegistryContext implements Context, Referenceable {
environment = (env == null) environment = (env == null)
? new Hashtable<String, Object>(5) ? new Hashtable<String, Object>(5)
: (Hashtable<String, Object>) env; : (Hashtable<String, Object>) env;
if (environment.get(SECURITY_MGR) != null) {
installSecurityMgr();
}
// chop off '[' and ']' in an IPv6 literal address // chop off '[' and ']' in an IPv6 literal address
if ((host != null) && (host.charAt(0) == '[')) { if ((host != null) && (host.charAt(0) == '[')) {
@ -295,9 +287,6 @@ public class RegistryContext implements Context, Referenceable {
public Object addToEnvironment(String propName, Object propVal) public Object addToEnvironment(String propName, Object propVal)
throws NamingException throws NamingException
{ {
if (propName.equals(SECURITY_MGR)) {
installSecurityMgr();
}
return environment.put(propName, propVal); return environment.put(propName, propVal);
} }
@ -412,19 +401,6 @@ public class RegistryContext implements Context, Referenceable {
} }
} }
/**
* Attempts to install a security manager if none is currently in
* place.
*/
@SuppressWarnings("removal")
private static void installSecurityMgr() {
try {
System.setSecurityManager(new SecurityManager());
} catch (Exception e) {
}
}
/** /**
* Encodes an object prior to binding it in the registry. First, * Encodes an object prior to binding it in the registry. First,
* NamingManager.getStateToBind() is invoked. If the resulting * NamingManager.getStateToBind() is invoked. If the resulting

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,8 +26,6 @@
package com.sun.jndi.url.rmi; package com.sun.jndi.url.rmi;
import java.net.URI; import java.net.URI;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Locale; import java.util.Locale;
@ -57,12 +55,9 @@ public class rmiURLContext extends GenericURLContext {
public static final ParseMode PARSE_MODE; public static final ParseMode PARSE_MODE;
static { static {
PrivilegedAction<String> action = () ->
System.getProperty(PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString());
ParseMode parseMode = DEFAULT_PARSE_MODE; ParseMode parseMode = DEFAULT_PARSE_MODE;
try { try {
@SuppressWarnings("removal") String mode = System.getProperty(PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString());
String mode = AccessController.doPrivileged(action);
parseMode = ParseMode.valueOf(mode.toUpperCase(Locale.ROOT)); parseMode = ParseMode.valueOf(mode.toUpperCase(Locale.ROOT));
} catch (Throwable t) { } catch (Throwable t) {
parseMode = DEFAULT_PARSE_MODE; parseMode = DEFAULT_PARSE_MODE;