Index: src/main/java/common/org/apache/harmony/security/fortress/DefaultPolicyParser.java =================================================================== --- src/main/java/common/org/apache/harmony/security/fortress/DefaultPolicyParser.java (revision 549613) +++ src/main/java/common/org/apache/harmony/security/fortress/DefaultPolicyParser.java (working copy) @@ -25,7 +25,6 @@ import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.File; import java.io.Reader; import java.net.URL; import java.security.cert.Certificate; @@ -194,23 +193,7 @@ if (ge.codebase != null) { codebase = new URL(resolve ? PolicyUtils.expandURL(ge.codebase, system) : ge.codebase); - //Fix HARMONY-1963 - if ("file".equals(codebase.getProtocol())) { //$NON-NLS-1$ - File codeFile = new File(codebase.getFile()); - if (codeFile.isAbsolute()) { - String absolutePath = codeFile.getAbsolutePath(); - //Fix HARMONY-4184 - //Unix style file path. - if (absolutePath.startsWith("/")) { - codebase = new URL("file://" + //$NON-NLS-1$ - codeFile.getAbsolutePath()); - } else { - //Windows style file path. - codebase = new URL("file:/" + //$NON-NLS-1$ - codeFile.getAbsolutePath()); - } - } - } + codebase = PolicyUtils.normalizeURL(codebase); } if (ge.signers != null) { if (resolve) { Index: src/main/java/common/org/apache/harmony/security/fortress/PolicyUtils.java =================================================================== --- src/main/java/common/org/apache/harmony/security/fortress/PolicyUtils.java (revision 549613) +++ src/main/java/common/org/apache/harmony/security/fortress/PolicyUtils.java (working copy) @@ -25,6 +25,8 @@ import java.io.File; import java.io.InputStream; import java.lang.reflect.Constructor; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.security.AccessController; import java.security.Permission; @@ -282,8 +284,58 @@ throws ExpansionFailedException { return expand(str, properties).replace(File.separatorChar, '/'); } + + /** + * Normalizes URLs to standard ones, eliminating pathname symbols. + * + * @param codebase - + * the original URL. + * @return - the normalized URL. + */ + public static URL normalizeURL(URL codebase) { + if (codebase != null && "file".equals(codebase.getProtocol())) { //$NON-NLS-1$ + try { + if (codebase.getHost().length() == 0) { + String path = codebase.getFile(); + if (path.length() == 0) { + // codebase is "file:" + path = "*"; + } + return filePathToURI(new File(path) + .getAbsolutePath()).normalize().toURL(); + } else { + // codebase is "file://" + return codebase.toURI().normalize().toURL(); + } + } catch (Exception e) { + // Ignore + } + } + return codebase; + } + /** + * Converts a file path to URI without accessing file system + * (like {File#toURI()} does). + * + * @param path - + * file path. + * @return - the resulting URI. + * @throw URISyntaxException + */ + public static URI filePathToURI(String path) throws URISyntaxException { + path = path.replace(File.separatorChar, '/'); + + if (!path.startsWith("/")) { //$NON-NLS-1$ + return new URI("file", null, //$NON-NLS-1$ + new StringBuilder(path.length() + 1).append('/') + .append(path).toString(), null, null); + } + return new URI("file", null, path, null, null); //$NON-NLS-1$ + } + + /** * Instances of this interface are intended for resolving * generalized expansion expressions, of the form ${{protocol:data}}. * Such functionality is applicable to security policy files, for example. @@ -585,4 +637,4 @@ } return true; } -} \ No newline at end of file +} Index: src/main/java/common/org/apache/harmony/security/PolicyEntry.java =================================================================== --- src/main/java/common/org/apache/harmony/security/PolicyEntry.java (revision 549613) +++ src/main/java/common/org/apache/harmony/security/PolicyEntry.java (working copy) @@ -22,6 +22,8 @@ package org.apache.harmony.security; +import java.net.URL; +import java.security.CodeSigner; import java.security.CodeSource; import java.security.Permission; import java.security.Principal; @@ -30,7 +32,6 @@ import org.apache.harmony.security.fortress.PolicyUtils; - /** * This class represents an elementary block of a security policy. It associates * a CodeSource of an executable code, Principals allowed to execute the code, @@ -55,7 +56,7 @@ */ public PolicyEntry(CodeSource cs, Collection prs, Collection permissions) { - this.cs = cs; + this.cs = (cs != null) ? normalizeCodeSource(cs) : null; this.principals = (prs == null || prs.isEmpty()) ? null : (Principal[]) prs.toArray(new Principal[prs.size()]); this.permissions = (permissions == null || permissions.isEmpty()) ? null @@ -68,9 +69,33 @@ * imply() method. */ public boolean impliesCodeSource(CodeSource codeSource) { - return (cs == null) ? true : cs.implies(codeSource); + if (cs == null) { + return true; + } + + if (codeSource == null) { + return false; + } + return cs.implies(normalizeCodeSource(codeSource)); } + private CodeSource normalizeCodeSource(CodeSource codeSource) { + URL codeSourceURL = PolicyUtils.normalizeURL(codeSource.getLocation()); + CodeSource result = codeSource; + + if (codeSourceURL != codeSource.getLocation()) { + // URL was normalized - recreate codeSource with new URL + CodeSigner[] signers = codeSource.getCodeSigners(); + if (signers == null) { + result = new CodeSource(codeSourceURL, codeSource + .getCertificates()); + } else { + result = new CodeSource(codeSourceURL, signers); + } + } + return result; + } + /** * Checks if specified Principals match this PolicyEntry. Null or empty set * of Principals of PolicyEntry implies any Principals; otherwise specified