7152564: Improve CodeSource.matchLocation(CodeSource) performance
7155693: CodeSource.matchLocation getPort test can be improved
Reviewed-by: chegar
--- a/jdk/src/share/classes/java/security/CodeSource.java Tue Apr 03 12:57:47 2012 -0700
+++ b/jdk/src/share/classes/java/security/CodeSource.java Fri Apr 13 09:46:25 2012 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -114,7 +114,7 @@
*
* @return a hash code value for this object.
*/
-
+ @Override
public int hashCode() {
if (location != null)
return location.hashCode();
@@ -133,6 +133,7 @@
*
* @return true if the objects are considered equal, false otherwise.
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this)
return true;
@@ -231,10 +232,10 @@
/**
* Returns true if this CodeSource object "implies" the specified CodeSource.
- * <P>
- * More specifically, this method makes the following checks, in order.
+ * <p>
+ * More specifically, this method makes the following checks.
* If any fail, it returns false. If they all succeed, it returns true.<p>
- * <ol>
+ * <ul>
* <li> <i>codesource</i> must not be null.
* <li> If this object's certificates are not null, then all
* of this object's certificates must be present in <i>codesource</i>'s
@@ -242,14 +243,14 @@
* <li> If this object's location (getLocation()) is not null, then the
* following checks are made against this object's location and
* <i>codesource</i>'s:<p>
- * <ol>
+ * <ul>
* <li> <i>codesource</i>'s location must not be null.
*
* <li> If this object's location
* equals <i>codesource</i>'s location, then return true.
*
* <li> This object's protocol (getLocation().getProtocol()) must be
- * equal to <i>codesource</i>'s protocol.
+ * equal to <i>codesource</i>'s protocol, ignoring case.
*
* <li> If this object's host (getLocation().getHost()) is not null,
* then the SocketPermission
@@ -258,7 +259,8 @@
*
* <li> If this object's port (getLocation().getPort()) is not
* equal to -1 (that is, if a port is specified), it must equal
- * <i>codesource</i>'s port.
+ * <i>codesource</i>'s port or default port
+ * (codesource.getLocation().getDefaultPort()).
*
* <li> If this object's file (getLocation().getFile()) doesn't equal
* <i>codesource</i>'s file, then the following checks are made:
@@ -275,8 +277,8 @@
* <li> If this object's reference (getLocation().getRef()) is
* not null, it must equal <i>codesource</i>'s reference.
*
- * </ol>
- * </ol>
+ * </ul>
+ * </ul>
* <p>
* For example, the codesource objects with the following locations
* and null certificates all imply
@@ -369,85 +371,88 @@
*
* @param that CodeSource to compare against
*/
- private boolean matchLocation(CodeSource that)
- {
- if (location == null) {
- return true;
- }
+ private boolean matchLocation(CodeSource that) {
+ if (location == null)
+ return true;
- if ((that == null) || (that.location == null))
- return false;
+ if ((that == null) || (that.location == null))
+ return false;
+
+ if (location.equals(that.location))
+ return true;
- if (location.equals(that.location))
- return true;
+ if (!location.getProtocol().equalsIgnoreCase(that.location.getProtocol()))
+ return false;
- if (!location.getProtocol().equals(that.location.getProtocol()))
+ int thisPort = location.getPort();
+ if (thisPort != -1) {
+ int thatPort = that.location.getPort();
+ int port = thatPort != -1 ? thatPort
+ : that.location.getDefaultPort();
+ if (thisPort != port)
return false;
-
- String thisHost = location.getHost();
- String thatHost = that.location.getHost();
+ }
- if (thisHost != null) {
- if (("".equals(thisHost) || "localhost".equals(thisHost)) &&
- ("".equals(thatHost) || "localhost".equals(thatHost))) {
- // ok
- } else if (!thisHost.equals(thatHost)) {
- if (thatHost == null) {
- return false;
- }
- if (this.sp == null) {
- this.sp = new SocketPermission(thisHost, "resolve");
- }
- if (that.sp == null) {
- that.sp = new SocketPermission(thatHost, "resolve");
- }
- if (!this.sp.implies(that.sp)) {
- return false;
- }
- }
+ if (location.getFile().endsWith("/-")) {
+ // Matches the directory and (recursively) all files
+ // and subdirectories contained in that directory.
+ // For example, "/a/b/-" implies anything that starts with
+ // "/a/b/"
+ String thisPath = location.getFile().substring(0,
+ location.getFile().length()-1);
+ if (!that.location.getFile().startsWith(thisPath))
+ return false;
+ } else if (location.getFile().endsWith("/*")) {
+ // Matches the directory and all the files contained in that
+ // directory.
+ // For example, "/a/b/*" implies anything that starts with
+ // "/a/b/" but has no further slashes
+ int last = that.location.getFile().lastIndexOf('/');
+ if (last == -1)
+ return false;
+ String thisPath = location.getFile().substring(0,
+ location.getFile().length()-1);
+ String thatPath = that.location.getFile().substring(0, last+1);
+ if (!thatPath.equals(thisPath))
+ return false;
+ } else {
+ // Exact matches only.
+ // For example, "/a/b" and "/a/b/" both imply "/a/b/"
+ if ((!that.location.getFile().equals(location.getFile()))
+ && (!that.location.getFile().equals(location.getFile()+"/"))) {
+ return false;
}
-
- if (location.getPort() != -1) {
- if (location.getPort() != that.location.getPort())
- return false;
- }
+ }
- if (location.getFile().endsWith("/-")) {
- // Matches the directory and (recursively) all files
- // and subdirectories contained in that directory.
- // For example, "/a/b/-" implies anything that starts with
- // "/a/b/"
- String thisPath = location.getFile().substring(0,
- location.getFile().length()-1);
- if (!that.location.getFile().startsWith(thisPath))
+ if (location.getRef() != null
+ && !location.getRef().equals(that.location.getRef())) {
+ return false;
+ }
+
+ String thisHost = location.getHost();
+ String thatHost = that.location.getHost();
+ if (thisHost != null) {
+ if (("".equals(thisHost) || "localhost".equals(thisHost)) &&
+ ("".equals(thatHost) || "localhost".equals(thatHost))) {
+ // ok
+ } else if (!thisHost.equals(thatHost)) {
+ if (thatHost == null) {
return false;
- } else if (location.getFile().endsWith("/*")) {
- // Matches the directory and all the files contained in that
- // directory.
- // For example, "/a/b/*" implies anything that starts with
- // "/a/b/" but has no further slashes
- int last = that.location.getFile().lastIndexOf('/');
- if (last == -1)
- return false;
- String thisPath = location.getFile().substring(0,
- location.getFile().length()-1);
- String thatPath = that.location.getFile().substring(0, last+1);
- if (!thatPath.equals(thisPath))
- return false;
- } else {
- // Exact matches only.
- // For example, "/a/b" and "/a/b/" both imply "/a/b/"
- if ((!that.location.getFile().equals(location.getFile()))
- && (!that.location.getFile().equals(location.getFile()+"/"))) {
+ }
+ if (this.sp == null) {
+ this.sp = new SocketPermission(thisHost, "resolve");
+ }
+ if (that.sp == null) {
+ that.sp = new SocketPermission(thatHost, "resolve");
+ }
+ if (!this.sp.implies(that.sp)) {
return false;
}
}
-
- if (location.getRef() == null)
- return true;
- else
- return location.getRef().equals(that.location.getRef());
}
+ // everything matches
+ return true;
+ }
/**
* Returns a string describing this CodeSource, telling its
@@ -455,6 +460,7 @@
*
* @return information about this CodeSource.
*/
+ @Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("(");
--- a/jdk/test/java/security/CodeSource/Implies.java Tue Apr 03 12:57:47 2012 -0700
+++ b/jdk/test/java/security/CodeSource/Implies.java Fri Apr 13 09:46:25 2012 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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,25 +23,42 @@
/*
* @test
- * @bug 4866847
- * @summary NullPointerException from CodeSource.matchLocation
+ * @bug 4866847 7152564 7155693
+ * @summary various CodeSource.implies tests
*/
import java.security.CodeSource;
-import java.net.*;
+import java.net.URL;
public class Implies {
public static void main(String[] args) throws Exception {
URL thisURL = new URL("http", "localhost", "file");
URL thatURL = new URL("http", null, "file");
+ // should not throw NullPointerException
+ testImplies(thisURL, thatURL, false);
+
+ thisURL = new URL("http", "localhost", "dir/-");
+ thatURL = new URL("HTTP", "localhost", "dir/file");
+ // protocol check should ignore case
+ testImplies(thisURL, thatURL, true);
+
+ thisURL = new URL("http", "localhost", 80, "dir/-");
+ thatURL = new URL("HTTP", "localhost", "dir/file");
+ // port check should match default port of thatURL
+ testImplies(thisURL, thatURL, true);
+
+ System.out.println("test passed");
+ }
+
+ private static void testImplies(URL thisURL, URL thatURL, boolean result)
+ throws SecurityException
+ {
CodeSource thisCs =
new CodeSource(thisURL, (java.security.cert.Certificate[]) null);
CodeSource thatCs =
new CodeSource(thatURL, (java.security.cert.Certificate[]) null);
-
- if (thisCs.implies(thatCs)) {
+ if (thisCs.implies(thatCs) != result) {
throw new SecurityException("test failed");
}
- System.out.println("test passed");
}
}