RFR (JAXP) JDK-8067170: Enable security manager on JAXP unit tests
Joe Wang
huizhe.wang at oracle.com
Wed Jul 27 20:05:22 UTC 2016
On 7/27/16, 2:27 AM, Frank Yuan wrote:
> Hi Daniel
>
> Would you like to have a look at the following changes before I finish all rework?
> It shows runWithAllPerm, and the handling for user.dir property in FilePolicy.java. The code like runWithTmpPermission is still
> kept, please ignore them, I will remove them finally.
>
> diff -r 1bfe60e61bad test/javax/xml/jaxp/libs/jaxp/library/FilePolicy.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/test/javax/xml/jaxp/libs/jaxp/library/FilePolicy.java Wed Jul 27 02:23:58 2016 -0700
> @@ -0,0 +1,44 @@
> +/*
> + * Copyright (c) 2016, 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.
> + */
> +package jaxp.library;
> +
> +import static jaxp.library.JAXPTestUtilities.getSystemProperty;
> +
> +import java.io.FilePermission;
> +
> +import org.testng.ITestContext;
> +
> +/**
> + * This policy can access local XML files.
> + */
> +public class FilePolicy extends BasePolicy {
> +
> + @Override
> + public void onStart(ITestContext arg0) {
> + JAXPPolicyManager policyManager = JAXPPolicyManager.getJAXPPolicyManager(true);
> + String userdir = getSystemProperty("user.dir");
> + policyManager.addPermission(new FilePermission(userdir + "/-", "read, write, delete"));
> + policyManager.addPermission(new FilePermission(System.getProperty("test.src") + "/-", "read"));
> + policyManager.addPermission(new FilePermission(userdir, "read"));
> + }
> +}
> diff -r 1bfe60e61bad test/javax/xml/jaxp/libs/jaxp/library/JAXPPolicyManager.java
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/test/javax/xml/jaxp/libs/jaxp/library/JAXPPolicyManager.java Wed Jul 27 02:23:58 2016 -0700
> @@ -0,0 +1,312 @@
> +/*
> + * Copyright (c) 2015, 2016, 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.
> + */
> +package jaxp.library;
> +
> +
> +import java.lang.reflect.ReflectPermission;
> +import java.security.CodeSource;
> +import java.security.Permission;
> +import java.security.PermissionCollection;
> +import java.security.Permissions;
> +import java.security.Policy;
> +import java.security.ProtectionDomain;
> +import java.security.SecurityPermission;
> +import java.util.ArrayList;
> +import java.util.Enumeration;
> +import java.util.List;
> +import java.util.PropertyPermission;
> +import java.util.StringJoiner;
> +
> +
> +/*
> + * This is a base class that every test class must extend if it needs to be run
> + * with security mode.
> + */
> +public class JAXPPolicyManager {
> + /*
> + * Backing up policy.
> + */
> + private Policy policyBackup;
> +
> + /*
> + * Backing up security manager.
> + */
> + private SecurityManager smBackup;
> +
> + /*
> + * Current policy.
> + */
> + private TestPolicy policy = new TestPolicy();
> +
> + /*
> + * JAXPPolicyManager singleton.
> + */
> + private static JAXPPolicyManager policyManager = null;
> +
> + /*
> + * Install a SecurityManager along with a default Policy to allow testNG to
> + * run when there is a security manager.
> + */
> + private JAXPPolicyManager() {
> + // Backing up policy and security manager for restore
> + policyBackup = Policy.getPolicy();
> + smBackup = System.getSecurityManager();
> +
> + // Set customized policy
> + setDefaultPermissions();
> + Policy.setPolicy(policy);
> + System.setSecurityManager(new SecurityManager());
> + }
Will the test suite be configured to run with and without
SecurityManager? It seems to me, with a TestNG test listener, a
SecurityManager is always installed. I don't seem to see it checks
whether the test shall run with a SecurityManager.
-Joe
> +
> + static synchronized JAXPPolicyManager getJAXPPolicyManager(boolean createIfNone) {
> + if (policyManager == null& createIfNone)
> + policyManager = new JAXPPolicyManager();
> + return policyManager;
> + }
> +
> + private void teardown() throws Exception {
> + System.setSecurityManager(smBackup);
> + Policy.setPolicy(policyBackup);
> + }
> +
> + /*
> + * Restore the original Policy and SecurityManager.
> + */
> + static synchronized void teardownPolicyManager() throws Exception {
> + if (policyManager != null) {
> + policyManager.teardown();
> + policyManager = null;
> + }
> + }
> +
> + /*
> + * Set default permissions, sub-class of JAXPBaseTest should override this
> + * method.
> + */
> + private void setDefaultPermissions() {
> + //Permissions to set security manager and policy
> + addPermission(new SecurityPermission("getPolicy"));
> + addPermission(new SecurityPermission("setPolicy"));
> + addPermission(new RuntimePermission("setSecurityManager"));
> + //Properties that jtreg and TestNG require
> + addPermission(new PropertyPermission("testng.show.stack.frames", "read"));
> + addPermission(new PropertyPermission("test.src", "read"));
> + addPermission(new PropertyPermission("test.classes", "read"));
> + addPermission(new PropertyPermission("dataproviderthreadcount", "read"));
> + addPermission(new PropertyPermission("experimental", "read"));
> +
> + //addPermission(new PropertyPermission("fileStringBuffer", "read"));
> + /*
> + addPermission(new RuntimePermission("getClassLoader"));
> + addPermission(new RuntimePermission("createClassLoader"));
> + addPermission(new RuntimePermission("createSecurityManager"));
> + addPermission(new RuntimePermission("modifyThread"));
> + addPermission(new PropertyPermission("*", "read, write"));
> + addPermission(new ReflectPermission("suppressAccessChecks"));
> + addPermission(new RuntimePermission("setIO"));
> + addPermission(new RuntimePermission("setContextClassLoader"));
> + addPermission(new RuntimePermission("accessDeclaredMembers"));*/
> + }
> +
> + /*
> + * Add permission to the TestPolicy.
> + *
> + * @param permission to be added.
> + */
> + void addPermission(Permission p) {
> + policy.addPermission(p);
> + }
> +
> + /*
> + * Add a temporary permission in current thread context. This won't impact
> + * global policy and doesn't support permission combination.
> + *
> + * @param permission
> + * to add.
> + * @return index of the added permission.
> + */
> + int addTmpPermission(Permission p) {
> + return policy.addTmpPermission(p);
> + }
> +
> + /*
> + * set allowAll in current thread context.
> + */
> + void setAllowAll(boolean allow) {
> + policy.setAllowAll(allow);
> + }
> +
> + /*
> + * Remove a temporary permission from current thread context.
> + *
> + * @param index to remove.
> + *
> + * @throws RuntimeException if no temporary permission list in current
> + * thread context or no permission correlated to the index.
> + */
> + void removeTmpPermission(int index) {
> + policy.removeTmpPermission(index);
> + }
> +
> +
> +}
> +
> +/*
> + * Simple Policy class that supports the required Permissions to validate the
> + * JAXP concrete classes.
> + */
> +class TestPolicy extends Policy {
> + private final PermissionCollection permissions = new Permissions();
> +
> + private ThreadLocal<List<Permission>> transientPermissions = new ThreadLocal<>();
> + private ThreadLocal<Boolean> allowAll = new ThreadLocal<>();
> +
> + private static Policy defaultPolicy = Policy.getPolicy();
> +
> + /*
> + * Add permission to this policy.
> + *
> + * @param permission to be added.
> + */
> + void addPermission(Permission p) {
> + permissions.add(p);
> + }
> +
> + /*
> + * Set all permissions. Caution: this should not called carefully unless
> + * it's really needed.
> + *
> + * private void setAllPermissions() { permissions.add(new AllPermission());
> + * }
> + */
> +
> + /*
> + * Overloaded methods from the Policy class.
> + */
> + @Override
> + public String toString() {
> + StringJoiner sj = new StringJoiner("\n", "policy: ", "");
> + Enumeration<Permission> perms = permissions.elements();
> + while (perms.hasMoreElements()) {
> + sj.add(perms.nextElement().toString());
> + }
> + return sj.toString();
> +
> + }
> +
> + @Override
> + public PermissionCollection getPermissions(ProtectionDomain domain) {
> + return permissions;
> + }
> +
> + @Override
> + public PermissionCollection getPermissions(CodeSource codesource) {
> + return permissions;
> + }
> +
> + @Override
> + public boolean implies(ProtectionDomain domain, Permission perm) {
> + if (allowAll())
> + return true;
> +
> + if (defaultPolicy.implies(domain, perm))
> + return true;
> +
> + if (permissions.implies(perm))
> + return true;
> + else
> + return tmpImplies(perm);
> + }
> +
> + /*
> + * Add a temporary permission in current thread context. This won't impact
> + * global policy and doesn't support permission combination.
> + *
> + * @param permission to add.
> + * @return index of the added permission.
> + */
> + int addTmpPermission(Permission p) {
> + List<Permission> tmpPermissions = transientPermissions.get();
> + if (tmpPermissions == null)
> + tmpPermissions = new ArrayList<>();
> +
> + tmpPermissions.add(p);
> + transientPermissions.set(tmpPermissions);
> + return tmpPermissions.size() - 1;
> + }
> +
> + /*
> + * Remove a temporary permission from current thread context.
> + *
> + * @param index to remove.
> + *
> + * @throws RuntimeException if no temporary permission list in current
> + * thread context or no permission correlated to the index.
> + */
> + void removeTmpPermission(int index) {
> + try {
> + List<Permission> tmpPermissions = transientPermissions.get();
> + tmpPermissions.remove(index);
> + } catch (NullPointerException | IndexOutOfBoundsException e) {
> + throw new RuntimeException("Tried to delete a non-existent temporary permission", e);
> + }
> + }
> +
> + /*
> + * Checks to see if the specified permission is implied by temporary
> + * permission list in current thread context.
> + *
> + * @param permission the Permission object to compare.
> + *
> + * @return true if "permission" is implied by any permission in the
> + * temporary permission list, false if not.
> + */
> + private boolean tmpImplies(Permission perm) {
> + List<Permission> tmpPermissions = transientPermissions.get();
> + if (tmpPermissions != null) {
> + for (Permission p : tmpPermissions) {
> + if (p.implies(perm))
> + return true;
> + }
> + }
> + return false;
> + }
> +
> + /*
> + * Checks to see if allow all permission requests in current thread context.
> + */
> + private boolean allowAll() {
> + Boolean allow = allowAll.get();
> + if (allow != null) {
> + return allow;
> + }
> + return false;
> + }
> +
> + /*
> + * set allowAll in current thread context.
> + */
> + void setAllowAll(boolean allow) {
> + allowAll.set(allow);
> + }
> +}
> diff -r 1bfe60e61bad test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java
> --- a/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java Mon Apr 04 14:54:38 2016 -0700
> +++ b/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java Wed Jul 27 02:23:58 2016 -0700
> @@ -1,5 +1,5 @@
> /*
> - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2014, 2016, 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
> @@ -22,6 +22,8 @@
> */
> package jaxp.library;
>
> +import static org.testng.Assert.fail;
> +
> import java.io.ByteArrayInputStream;
> import java.io.File;
> import java.io.IOException;
> @@ -34,12 +36,18 @@
> import java.nio.charset.UnsupportedCharsetException;
> import java.nio.file.Files;
> import java.nio.file.Paths;
> +import java.security.Permission;
> +import java.util.ArrayList;
> import java.util.HashMap;
> import java.util.List;
> import java.util.Map;
> +import java.util.Optional;
> import java.util.concurrent.ConcurrentHashMap;
> +import java.util.function.Supplier;
> import java.util.regex.Pattern;
> import java.util.stream.Collectors;
> +import java.util.stream.Stream;
> +
> import javax.xml.parsers.DocumentBuilder;
> import javax.xml.parsers.DocumentBuilderFactory;
> import javax.xml.parsers.ParserConfigurationException;
> @@ -48,7 +56,7 @@
> import javax.xml.transform.TransformerFactory;
> import javax.xml.transform.dom.DOMSource;
> import javax.xml.transform.stream.StreamResult;
> -import static org.testng.Assert.fail;
> +
> import org.w3c.dom.Document;
> import org.w3c.dom.Node;
> import org.xml.sax.SAXException;
> @@ -74,12 +82,6 @@
> public static final String FILE_SEP = "/";
>
> /**
> - * Current test directory.
> - */
> - public static final String USER_DIR =
> - System.getProperty("user.dir", ".") + FILE_SEP;;
> -
> - /**
> * A map storing every test's current test file pointer. File number should
> * be incremental and it's a thread-safe reading on this file number.
> */
> @@ -89,7 +91,7 @@
> /**
> * BOM table for storing BOM header.
> */
> - private final static Map<String, byte[]> bom = new HashMap<>();
> + private final static Map<String, byte[]> bom = new HashMap();
>
> /**
> * Initialize all BOM headers.
> @@ -130,8 +132,15 @@
> */
> public static boolean compareWithGold(String goldfile, String outputfile,
> Charset cs) throws IOException {
> - return Files.readAllLines(Paths.get(goldfile)).
> + boolean isSame = Files.readAllLines(Paths.get(goldfile)).
> equals(Files.readAllLines(Paths.get(outputfile), cs));
> + if (!isSame) {
> + System.err.println("Golden file " + goldfile + " :");
> + Files.readAllLines(Paths.get(goldfile)).forEach(System.err::println);
> + System.err.println("Output file " + outputfile + " :");
> + Files.readAllLines(Paths.get(outputfile), cs).forEach(System.err::println);
> + }
> + return isSame;
> }
>
> /**
> @@ -308,10 +317,10 @@
> int nextNumber = currentFileNumber.contains(clazz)
> ? currentFileNumber.get(clazz) + 1 : 1;
> Integer i = currentFileNumber.putIfAbsent(clazz, nextNumber);
> - if (i != null&& i != nextNumber) {
> + if (i != null) {
> do {
> nextNumber = currentFileNumber.get(clazz) + 1;
> - } while (currentFileNumber.replace(clazz, nextNumber -1, nextNumber));
> + } while (!currentFileNumber.replace(clazz, nextNumber - 1, nextNumber));
> }
> return USER_DIR + clazz.getName() + nextNumber + ".out";
> }
> @@ -332,4 +341,146 @@
> toAbsolutePath().toString();
> return normalizedPath.replace("\\", FILE_SEP) + FILE_SEP;
> }
> +
> +
> + /**
> + * Run the RunnableWithException with creating a JAXPPolicyManager and
> + * assigning temporary permissions. It's not thread-safe to use this
> + * function.
> + *
> + * @param r
> + * RunnableWithException to execute
> + * @param ps
> + * assigning permissions to add.
> + */
> + public static void tryRunWithPolicyManager(RunnableWithException r, Permission... ps) throws Exception {
> + JAXPPolicyManager policyManager = JAXPPolicyManager.getJAXPPolicyManager(true);
> + if (policyManager != null)
> + Stream.of(ps).forEach(p -> policyManager.addTmpPermission(p));
> + try {
> + r.run();
> + } finally {
> + JAXPPolicyManager.teardownPolicyManager();
> + }
> + }
> +
> + /**
> + * Run the runnable with assigning temporary permissions. This won't impact
> + * global policy.
> + *
> + * @param r
> + * Runnable to run
> + * @param ps
> + * assigning permissions to add.
> + */
> + public static void runWithTmpPermission(Runnable r, Permission... ps) {
> + JAXPPolicyManager policyManager = JAXPPolicyManager.getJAXPPolicyManager(false);
> + List<Integer> tmpPermissionIndexes = new ArrayList();
> + if (policyManager != null)
> + Stream.of(ps).forEach(p -> tmpPermissionIndexes.add(policyManager.addTmpPermission(p)));
> + try {
> + r.run();
> + } finally {
> + tmpPermissionIndexes.forEach(index -> policyManager.removeTmpPermission(index));
> + }
> + }
> +
> + /**
> + * Run the supplier with all permissions. This won't impact global policy.
> + *
> + * @param s
> + * Supplier to run
> + */
> + public static<T> T runWithAllPerm(Supplier<T> s) {
> + Optional<JAXPPolicyManager> policyManager = Optional.ofNullable(JAXPPolicyManager
> + .getJAXPPolicyManager(false));
> + policyManager.ifPresent(manager -> manager.setAllowAll(true));
> + try {
> + return s.get();
> + } finally {
> + policyManager.ifPresent(manager -> manager.setAllowAll(false));
> + }
> + }
> +
> + /**
> + * Run the Runnable with all permissions. This won't impact global policy.
> + *
> + * @param s
> + * Supplier to run
> + */
> + public static void runWithAllPerm(Runnable r) {
> + Optional<JAXPPolicyManager> policyManager = Optional.ofNullable(JAXPPolicyManager
> + .getJAXPPolicyManager(false));
> + policyManager.ifPresent(manager -> manager.setAllowAll(true));
> + try {
> + r.run();
> + } finally {
> + policyManager.ifPresent(manager -> manager.setAllowAll(false));
> + }
> + }
> +
> + /**
> + * Acquire a system property.
> + *
> + * @param name
> + * System property name to be acquired.
> + * @return property value
> + */
> + public static String getSystemProperty(String name) {
> + return runWithAllPerm(() -> System.getProperty(name));
> + }
> +
> + /**
> + * Set a system property by given system value.
> + *
> + * @param name
> + * System property name to be set.
> + * @param value
> + * System property value to be set.
> + */
> + public static void setSystemProperty(String name, String value) {
> + runWithAllPerm(() -> System.setProperty(name, value));
> + }
> +
> + /**
> + * Clear a system property.
> + *
> + * @param name
> + * System property name to be cleared.
> + */
> + public static void clearSystemProperty(String name) {
> + runWithAllPerm(() -> clearSystemProperty(name));
> + }
> +
> + /**
> + * Run the RunnableWithException with assigning temporary permissions. This
> + * won't impact global policy.
> + *
> + * @param r
> + * RunnableWithException to execute
> + * @param ps
> + * assigning permissions to add.
> + */
> + public static void tryRunWithTmpPermission(RunnableWithException r, Permission... ps) throws Exception {
> + JAXPPolicyManager policyManager = JAXPPolicyManager.getJAXPPolicyManager(false);
> + List<Integer> tmpPermissionIndexes = new ArrayList();
> + if (policyManager != null)
> + Stream.of(ps).forEach(p -> tmpPermissionIndexes.add(policyManager.addTmpPermission(p)));
> + try {
> + r.run();
> + } finally {
> + tmpPermissionIndexes.forEach(index -> policyManager.removeTmpPermission(index));
> + }
> + }
> +
> + @FunctionalInterface
> + public interface RunnableWithException {
> + void run() throws Exception;
> + }
> +
> + /**
> + * Current test directory.
> + */
> + public static final String USER_DIR = getSystemProperty("user.dir") + FILE_SEP;;
> +
> }
>
>
> diff -r 1bfe60e61bad test/javax/xml/jaxp/unittest/transform/Bug6490921.java
> --- a/test/javax/xml/jaxp/unittest/transform/Bug6490921.java Mon Apr 04 14:54:38 2016 -0700
> +++ b/test/javax/xml/jaxp/unittest/transform/Bug6490921.java Wed Jul 27 02:22:40 2016 -0700
> @@ -1,5 +1,5 @@
> /*
> - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
> * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
> *
> * This code is free software; you can redistribute it and/or modify it
> @@ -23,6 +23,8 @@
>
> package transform;
>
> +import static jaxp.library.JAXPTestUtilities.setSystemProperty;
> +
> import java.io.IOException;
> import java.io.StringReader;
> import java.io.StringWriter;
> @@ -37,6 +39,7 @@
> import javax.xml.transform.stream.StreamResult;
>
> import org.testng.Assert;
> +import org.testng.annotations.Listeners;
> import org.testng.annotations.Test;
> import org.xml.sax.InputSource;
> import org.xml.sax.SAXException;
> @@ -46,6 +49,7 @@
> * @bug 6490921
> * @summary Test property org.xml.sax.driver is always applied in transformer API.
> */
> + at Listeners({jaxp.library.BasePolicy.class})
> public class Bug6490921 {
>
> public static class ReaderStub extends XMLFilterImpl {
> @@ -71,7 +75,7 @@
> public void test01() {
> String xml = "<?xml version='1.0'?><root/>";
> ReaderStub.used = false;
> - System.setProperty("org.xml.sax.driver", "");
> + setSystemProperty("org.xml.sax.driver", "");
>
> // Don't set 'org.xml.sax.driver' here, just use default
> try {
> @@ -91,7 +95,7 @@
> public void test02() {
> String xml = "<?xml version='1.0'?><root/>";
> ReaderStub.used = false;
> - System.setProperty("org.xml.sax.driver", ReaderStub.class.getName());
> + setSystemProperty("org.xml.sax.driver", ReaderStub.class.getName());
> try {
> TransformerFactory transFactory = TransformerFactory.newInstance();
> Transformer transformer = transFactory.newTransformer();
> @@ -111,7 +115,7 @@
> + "<xsl:template match='/'>Hello World!</xsl:template>\n" + "</xsl:stylesheet>\n";
>
> ReaderStub.used = false;
> - System.setProperty("org.xml.sax.driver", ReaderStub.class.getName());
> + setSystemProperty("org.xml.sax.driver", ReaderStub.class.getName());
> try {
> TransformerFactory transFactory = TransformerFactory.newInstance();
> if (transFactory.getFeature(SAXTransformerFactory.FEATURE) == false) {
>
> Thanks
> Frank
>
> -----Original Message-----
> From: Daniel Fuchs [mailto:daniel.fuchs at oracle.com]
> Sent: Tuesday, July 26, 2016 3:46 PM
> To: Frank Yuan; 'huizhe wang'
> Cc: 'Amy Lu'; 'core-libs-dev'
> Subject: Re: RFR (JAXP) JDK-8067170: Enable security manager on JAXP unit tests
>
> On 26/07/16 04:24, Frank Yuan wrote:
>> Thank you very much for your suggestions! Now I fully understand the rule(at least I think so :P)
>> I will use a runWithAllPerm block surrounding the user setup code as Daniel's way. Btw, Daniel, ThreadLocal should not need Atomic
>> any more, correct?
>>
> Hi Frank,
>
> runWithAllPerm is another way to do it.
> It uses a ThreadLocal<Permissions>, right?
>
> I agree it's adequate. Just be careful of what might
> happen if you run runWithAllPerm inside runWithPermissions,
> or runWithPermissions(runnable, a,b,c) with a runnable that
> later calls runWithPermission(runnable2, a, d, e) further down
> the road.
>
> At the moment I'm not sure whether your code will work correctly
> in the presence of such nested invocation (maybe it does),
> but because it seems to be index based it's not immediately
> obvious (I'm not asking you to change it - just to verify and
> confirm that it's something you have taken into account, and
> that you're confident that it works).
>
>
> Best regards,
>
> -- daniel
>
More information about the core-libs-dev
mailing list