提交 0a32a940 编写于 作者: M mullan

7152564: Improve CodeSource.matchLocation(CodeSource) performance

7155693: CodeSource.matchLocation getPort test can be improved
Reviewed-by: chegar
上级 0230a043
/* /*
* 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. * 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
...@@ -114,7 +114,7 @@ public class CodeSource implements java.io.Serializable { ...@@ -114,7 +114,7 @@ public class CodeSource implements java.io.Serializable {
* *
* @return a hash code value for this object. * @return a hash code value for this object.
*/ */
@Override
public int hashCode() { public int hashCode() {
if (location != null) if (location != null)
return location.hashCode(); return location.hashCode();
...@@ -133,6 +133,7 @@ public class CodeSource implements java.io.Serializable { ...@@ -133,6 +133,7 @@ public class CodeSource implements java.io.Serializable {
* *
* @return true if the objects are considered equal, false otherwise. * @return true if the objects are considered equal, false otherwise.
*/ */
@Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj == this) if (obj == this)
return true; return true;
...@@ -231,10 +232,10 @@ public class CodeSource implements java.io.Serializable { ...@@ -231,10 +232,10 @@ public class CodeSource implements java.io.Serializable {
/** /**
* Returns true if this CodeSource object "implies" the specified CodeSource. * Returns true if this CodeSource object "implies" the specified CodeSource.
* <P> * <p>
* More specifically, this method makes the following checks, in order. * More specifically, this method makes the following checks.
* If any fail, it returns false. If they all succeed, it returns true.<p> * 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> <i>codesource</i> must not be null.
* <li> If this object's certificates are not null, then all * <li> If this object's certificates are not null, then all
* of this object's certificates must be present in <i>codesource</i>'s * of this object's certificates must be present in <i>codesource</i>'s
...@@ -242,14 +243,14 @@ public class CodeSource implements java.io.Serializable { ...@@ -242,14 +243,14 @@ public class CodeSource implements java.io.Serializable {
* <li> If this object's location (getLocation()) is not null, then the * <li> If this object's location (getLocation()) is not null, then the
* following checks are made against this object's location and * following checks are made against this object's location and
* <i>codesource</i>'s:<p> * <i>codesource</i>'s:<p>
* <ol> * <ul>
* <li> <i>codesource</i>'s location must not be null. * <li> <i>codesource</i>'s location must not be null.
* *
* <li> If this object's location * <li> If this object's location
* equals <i>codesource</i>'s location, then return true. * equals <i>codesource</i>'s location, then return true.
* *
* <li> This object's protocol (getLocation().getProtocol()) must be * <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, * <li> If this object's host (getLocation().getHost()) is not null,
* then the SocketPermission * then the SocketPermission
...@@ -258,7 +259,8 @@ public class CodeSource implements java.io.Serializable { ...@@ -258,7 +259,8 @@ public class CodeSource implements java.io.Serializable {
* *
* <li> If this object's port (getLocation().getPort()) is not * <li> If this object's port (getLocation().getPort()) is not
* equal to -1 (that is, if a port is specified), it must equal * 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 * <li> If this object's file (getLocation().getFile()) doesn't equal
* <i>codesource</i>'s file, then the following checks are made: * <i>codesource</i>'s file, then the following checks are made:
...@@ -275,8 +277,8 @@ public class CodeSource implements java.io.Serializable { ...@@ -275,8 +277,8 @@ public class CodeSource implements java.io.Serializable {
* <li> If this object's reference (getLocation().getRef()) is * <li> If this object's reference (getLocation().getRef()) is
* not null, it must equal <i>codesource</i>'s reference. * not null, it must equal <i>codesource</i>'s reference.
* *
* </ol> * </ul>
* </ol> * </ul>
* <p> * <p>
* For example, the codesource objects with the following locations * For example, the codesource objects with the following locations
* and null certificates all imply * and null certificates all imply
...@@ -369,85 +371,88 @@ public class CodeSource implements java.io.Serializable { ...@@ -369,85 +371,88 @@ public class CodeSource implements java.io.Serializable {
* *
* @param that CodeSource to compare against * @param that CodeSource to compare against
*/ */
private boolean matchLocation(CodeSource that) private boolean matchLocation(CodeSource that) {
{ if (location == null)
if (location == null) { return true;
return true;
}
if ((that == null) || (that.location == null)) if ((that == null) || (that.location == null))
return false; return false;
if (location.equals(that.location)) if (location.equals(that.location))
return true; return true;
if (!location.getProtocol().equals(that.location.getProtocol())) if (!location.getProtocol().equalsIgnoreCase(that.location.getProtocol()))
return false; return false;
String thisHost = location.getHost(); int thisPort = location.getPort();
String thatHost = that.location.getHost(); if (thisPort != -1) {
int thatPort = that.location.getPort();
int port = thatPort != -1 ? thatPort
: that.location.getDefaultPort();
if (thisPort != port)
return false;
}
if (thisHost != null) { if (location.getFile().endsWith("/-")) {
if (("".equals(thisHost) || "localhost".equals(thisHost)) && // Matches the directory and (recursively) all files
("".equals(thatHost) || "localhost".equals(thatHost))) { // and subdirectories contained in that directory.
// ok // For example, "/a/b/-" implies anything that starts with
} else if (!thisHost.equals(thatHost)) { // "/a/b/"
if (thatHost == null) { String thisPath = location.getFile().substring(0,
return false; location.getFile().length()-1);
} if (!that.location.getFile().startsWith(thisPath))
if (this.sp == null) { return false;
this.sp = new SocketPermission(thisHost, "resolve"); } else if (location.getFile().endsWith("/*")) {
} // Matches the directory and all the files contained in that
if (that.sp == null) { // directory.
that.sp = new SocketPermission(thatHost, "resolve"); // For example, "/a/b/*" implies anything that starts with
} // "/a/b/" but has no further slashes
if (!this.sp.implies(that.sp)) { int last = that.location.getFile().lastIndexOf('/');
return false; 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.getRef() != null
if (location.getPort() != that.location.getPort()) && !location.getRef().equals(that.location.getRef())) {
return false; return false;
} }
if (location.getFile().endsWith("/-")) { String thisHost = location.getHost();
// Matches the directory and (recursively) all files String thatHost = that.location.getHost();
// and subdirectories contained in that directory. if (thisHost != null) {
// For example, "/a/b/-" implies anything that starts with if (("".equals(thisHost) || "localhost".equals(thisHost)) &&
// "/a/b/" ("".equals(thatHost) || "localhost".equals(thatHost))) {
String thisPath = location.getFile().substring(0, // ok
location.getFile().length()-1); } else if (!thisHost.equals(thatHost)) {
if (!that.location.getFile().startsWith(thisPath)) 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; return false;
String thisPath = location.getFile().substring(0, }
location.getFile().length()-1); if (this.sp == null) {
String thatPath = that.location.getFile().substring(0, last+1); this.sp = new SocketPermission(thisHost, "resolve");
if (!thatPath.equals(thisPath)) }
return false; if (that.sp == null) {
} else { that.sp = new SocketPermission(thatHost, "resolve");
// Exact matches only. }
// For example, "/a/b" and "/a/b/" both imply "/a/b/" if (!this.sp.implies(that.sp)) {
if ((!that.location.getFile().equals(location.getFile()))
&& (!that.location.getFile().equals(location.getFile()+"/"))) {
return false; 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 * Returns a string describing this CodeSource, telling its
...@@ -455,6 +460,7 @@ public class CodeSource implements java.io.Serializable { ...@@ -455,6 +460,7 @@ public class CodeSource implements java.io.Serializable {
* *
* @return information about this CodeSource. * @return information about this CodeSource.
*/ */
@Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("("); sb.append("(");
......
/* /*
* 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. * 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
...@@ -23,25 +23,42 @@ ...@@ -23,25 +23,42 @@
/* /*
* @test * @test
* @bug 4866847 * @bug 4866847 7152564 7155693
* @summary NullPointerException from CodeSource.matchLocation * @summary various CodeSource.implies tests
*/ */
import java.security.CodeSource; import java.security.CodeSource;
import java.net.*; import java.net.URL;
public class Implies { public class Implies {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
URL thisURL = new URL("http", "localhost", "file"); URL thisURL = new URL("http", "localhost", "file");
URL thatURL = new URL("http", null, "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 = CodeSource thisCs =
new CodeSource(thisURL, (java.security.cert.Certificate[]) null); new CodeSource(thisURL, (java.security.cert.Certificate[]) null);
CodeSource thatCs = CodeSource thatCs =
new CodeSource(thatURL, (java.security.cert.Certificate[]) null); new CodeSource(thatURL, (java.security.cert.Certificate[]) null);
if (thisCs.implies(thatCs) != result) {
if (thisCs.implies(thatCs)) {
throw new SecurityException("test failed"); throw new SecurityException("test failed");
} }
System.out.println("test passed");
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册