< prev index next >

src/java.base/share/classes/java/net/SocketPermission.java

Print this page
rev 52898 : 8231785: Improved socket permissions
Reviewed-by: ahgross, chegar, mullan, rhalade

@@ -35,16 +35,16 @@
 import java.security.Permission;
 import java.security.PermissionCollection;
 import java.security.PrivilegedAction;
 import java.security.Security;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.Enumeration;
-import java.util.Vector;
+import java.util.Map;
 import java.util.StringJoiner;
 import java.util.StringTokenizer;
-import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.Vector;
+import java.util.concurrent.ConcurrentHashMap;
 import sun.net.util.IPAddressUtil;
 import sun.net.PortConfig;
 import sun.security.util.RegisteredDomain;
 import sun.security.util.SecurityConstants;
 import sun.security.util.Debug;

@@ -1338,20 +1338,17 @@
 
 final class SocketPermissionCollection extends PermissionCollection
     implements Serializable
 {
     // Not serialized; see serialization section at end of class
-    // A ConcurrentSkipListMap is used to preserve order, so that most
-    // recently added permissions are checked first (see JDK-4301064).
-    private transient ConcurrentSkipListMap<String, SocketPermission> perms;
+    private transient Map<String, SocketPermission> perms;
 
     /**
-     * Create an empty SocketPermissions object.
-     *
+     * Create an empty SocketPermissionCollection object.
      */
     public SocketPermissionCollection() {
-        perms = new ConcurrentSkipListMap<>(new SPCComparator());
+        perms = new ConcurrentHashMap<>();
     }
 
     /**
      * Adds a permission to the SocketPermissions. The key for the hash is
      * the name in the case of wildcards, or all the IP addresses.

@@ -1420,10 +1417,22 @@
 
         int desired = np.getMask();
         int effective = 0;
         int needed = desired;
 
+        var hit = perms.get(np.getName());
+        if (hit != null) {
+            // fastpath, if the host was explicitly listed
+            if (((needed & hit.getMask()) != 0) && hit.impliesIgnoreMask(np)) {
+                effective |= hit.getMask();
+                if ((effective & desired) == desired) {
+                    return true;
+                }
+                needed = (desired & ~effective);
+            }
+        }
+
         //System.out.println("implies "+np);
         for (SocketPermission x : perms.values()) {
             //System.out.println("  trying "+x);
             if (((needed & x.getMask()) != 0) && x.impliesIgnoreMask(np)) {
                 effective |=  x.getMask();

@@ -1497,24 +1506,11 @@
         ObjectInputStream.GetField gfields = in.readFields();
 
         // Get the one we want
         @SuppressWarnings("unchecked")
         Vector<SocketPermission> permissions = (Vector<SocketPermission>)gfields.get("permissions", null);
-        perms = new ConcurrentSkipListMap<>(new SPCComparator());
+        perms = new ConcurrentHashMap<>(permissions.size());
         for (SocketPermission sp : permissions) {
             perms.put(sp.getName(), sp);
         }
     }
-
-    /**
-     * A simple comparator that orders new non-equal entries at the beginning.
-     */
-    private static class SPCComparator implements Comparator<String> {
-        @Override
-        public int compare(String s1, String s2) {
-            if (s1.equals(s2)) {
-                return 0;
-            }
-            return -1;
-        }
-    }
 }
< prev index next >