提交 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -114,7 +114,7 @@ public class CodeSource implements java.io.Serializable {
*
* @return a hash code value for this object.
*/
@Override
public int hashCode() {
if (location != null)
return location.hashCode();
......@@ -133,6 +133,7 @@ public class CodeSource implements java.io.Serializable {
*
* @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 @@ public class CodeSource implements java.io.Serializable {
/**
* 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 @@ public class CodeSource implements java.io.Serializable {
* <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 @@ public class CodeSource implements java.io.Serializable {
*
* <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 @@ public class CodeSource implements java.io.Serializable {
* <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 @@ public class CodeSource implements java.io.Serializable {
*
* @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().equals(that.location.getProtocol()))
return false;
if (!location.getProtocol().equalsIgnoreCase(that.location.getProtocol()))
return false;
String thisHost = location.getHost();
String thatHost = that.location.getHost();
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;
}
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.getRef() != null
&& !location.getRef().equals(that.location.getRef())) {
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)
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;
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 @@ public class CodeSource implements java.io.Serializable {
*
* @return information about this CodeSource.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
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.
*
* 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");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册