Index: src/main/java/common/org/apache/harmony/security/fortress/DefaultPolicyParser.java =================================================================== --- src/main/java/common/org/apache/harmony/security/fortress/DefaultPolicyParser.java (revision 548376) +++ 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,14 +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()) { - 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 548376) +++ 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,49 @@ 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 { + return filePathToURI(new File(codebase.getFile()) + .getAbsolutePath()).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); + } else if (path.startsWith("//")) { //$NON-NLS-1$ + return new URI("file", path, null); // UNC path //$NON-NLS-1$ + } + 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 +628,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 548376) +++ 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, @@ -68,7 +69,27 @@ * imply() method. */ public boolean impliesCodeSource(CodeSource codeSource) { - return (cs == null) ? true : cs.implies(codeSource); + if (cs == null) { + return true; + } + + if (codeSource == null) { + return false; + } + + URL codeSourceURL = PolicyUtils.normalizeURL(codeSource.getLocation()); + if (codeSourceURL != codeSource.getLocation()) { + // URL was normalized - recreate codeSource with new URL + CodeSigner[] signers = codeSource.getCodeSigners(); + if (signers == null) { + codeSource = new CodeSource(codeSourceURL, codeSource + .getCertificates()); + } else { + codeSource = new CodeSource(codeSourceURL, signers); + } + } + + return cs.implies(codeSource); } /**