OpenJDK / jdk / jdk
changeset 9277:92ecd6edb959
7030649: URL.equals() fails to compare jar urls
Reviewed-by: michaelm
author | chegar |
---|---|
date | Mon, 18 Apr 2011 11:14:28 +0100 |
parents | 645e1a5c72f6 |
children | f4672926fe4c |
files | jdk/src/share/classes/sun/net/www/protocol/jar/Handler.java jdk/test/java/net/URL/Equals.java |
diffstat | 2 files changed, 150 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/src/share/classes/sun/net/www/protocol/jar/Handler.java Sun Apr 17 22:52:26 2011 -0700 +++ b/jdk/src/share/classes/sun/net/www/protocol/jar/Handler.java Mon Apr 18 11:14:28 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, 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 @@ -25,9 +25,8 @@ package sun.net.www.protocol.jar; -import java.io.*; +import java.io.IOException; import java.net.*; -import java.util.*; import sun.net.www.ParseUtil; /* @@ -42,7 +41,7 @@ return new JarURLConnection(u, this); } - private int indexOfBangSlash(String spec) { + private static int indexOfBangSlash(String spec) { int indexOfBang = spec.length(); while((indexOfBang = spec.lastIndexOf('!', indexOfBang)) != -1) { if ((indexOfBang != (spec.length() - 1)) && @@ -55,6 +54,75 @@ return -1; } + /** + * Compare two jar URLs + */ + @Override + protected boolean sameFile(URL u1, URL u2) { + if (!u1.getProtocol().equals("jar") || !u2.getProtocol().equals("jar")) + return false; + + String file1 = u1.getFile(); + String file2 = u2.getFile(); + int sep1 = file1.indexOf(separator); + int sep2 = file2.indexOf(separator); + + if (sep1 == -1 || sep2 == -1) { + return super.sameFile(u1, u2); + } + + String entry1 = file1.substring(sep1 + 2); + String entry2 = file2.substring(sep2 + 2); + + if (!entry1.equals(entry2)) + return false; + + URL enclosedURL1 = null, enclosedURL2 = null; + try { + enclosedURL1 = new URL(file1.substring(0, sep1)); + enclosedURL2 = new URL(file2.substring(0, sep2)); + } catch (MalformedURLException unused) { + return super.sameFile(u1, u2); + } + + if (!super.sameFile(enclosedURL1, enclosedURL2)) { + return false; + } + + return true; + } + + @Override + protected int hashCode(URL u) { + int h = 0; + + String protocol = u.getProtocol(); + if (protocol != null) + h += protocol.hashCode(); + + String file = u.getFile(); + int sep = file.indexOf(separator); + + if (sep == -1) + return h + file.hashCode(); + + URL enclosedURL = null; + String fileWithoutEntry = file.substring(0, sep); + try { + enclosedURL = new URL(fileWithoutEntry); + h += enclosedURL.hashCode(); + } catch (MalformedURLException unused) { + h += fileWithoutEntry.hashCode(); + } + + String entry = file.substring(sep + 2); + h += entry.hashCode(); + + return h; + } + + + @Override protected void parseURL(URL url, String spec, int start, int limit) { String file = null;
--- a/jdk/test/java/net/URL/Equals.java Sun Apr 17 22:52:26 2011 -0700 +++ b/jdk/test/java/net/URL/Equals.java Mon Apr 18 11:14:28 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2011, 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,16 +23,19 @@ /* * @test - * @bug 4052976 - * @summary Test URL.equals involving anchors - * + * @bug 4052976 7030649 + * @summary Test URL.equals with anchors, and jar URLs */ import java.net.*; public class Equals { + public static void main(String[] args) throws Exception { + anchors(); + jarURLs(); + } - public static void main(String[] args) throws Exception { + static void anchors() throws Exception { URL url1, url2; url1 = new URL(null, "http://JavaSoft/Test#bar"); @@ -45,4 +48,74 @@ if (url1.equals(null)) throw new RuntimeException("URL.equals fails given null"); } + + static final String HTTP_URL1A = "http://localhost/xyz"; + static final String HTTP_URL1B = "http://LOCALHOST/xyz"; + static final String FILE_URL1A = "file:///c:/foo/xyz"; + static final String FILE_URL1B = "file:/c:/foo/xyz"; + + static void jarURLs() throws Exception { + int failed = 0; + failed = compareJarURLS(HTTP_URL1A, HTTP_URL1A, "!/abc", "!/abc", true); + failed = compareJarURLS(HTTP_URL1A, HTTP_URL1B, "!/abc", "!/abc", true); + failed = compareJarURLS(HTTP_URL1B, HTTP_URL1A, "!/", "!/", true); + failed = compareJarURLS(HTTP_URL1A, HTTP_URL1B, "!/abc", "!/", false); + failed = compareJarURLS(HTTP_URL1A, HTTP_URL1B, "!/abc", "!/xy", false); + failed = compareJarURLS(FILE_URL1A, FILE_URL1A, "!/abc", "!/abc", true); + failed = compareJarURLS(FILE_URL1A, FILE_URL1B, "!/abc", "!/abc", true); + failed = compareJarURLS(FILE_URL1A, FILE_URL1B, "!/", "!/", true); + failed = compareJarURLS(FILE_URL1A, FILE_URL1B, "!/abc", "!/", false); + failed = compareJarURLS(FILE_URL1A, FILE_URL1B, "!/abc", "!/xy", false); + + failed = (new URL("jar:file://xzy!/abc")).equals( + new URL("file://xzy!/abc")) ? 1 : 0; + + if (failed > 0) + throw new RuntimeException("Some jar URL tests failed. Check output"); + } + + static int compareJarURLS(String urlStr1, String urlStr2, + String entry1, String entry2, + boolean expectEqual) throws Exception { + int failed = 0; + + URL url1 = new URL(urlStr1); + URL url2 = new URL(urlStr2); + + if (!url1.equals(url2)) { + System.out.println("Urls are not equal, so the test cannot run."); + System.out.println("url1: " + url1 + ", url2:" + url2); + return 1; + } + + URL jarUrl1 = new URL("jar:" + urlStr1 + entry1); + URL jarUrl2 = new URL("jar:" + urlStr2 + entry2); + jarUrl2.openConnection(); + + boolean equal = jarUrl1.equals(jarUrl2); + if (expectEqual && !equal) { + System.out.println("URLs should be equal, but are not. " + + jarUrl1 + ", " + jarUrl2); + failed++; + } else if (!expectEqual && equal) { + System.out.println("URLs should NOT be equal, but are. " + + jarUrl1 + ", " + jarUrl2); + failed++; + } + + if (expectEqual) { + // hashCode MUST produce the same integer result for equal urls + int hash1 = jarUrl1.hashCode(); + int hash2 = jarUrl2.hashCode(); + if (hash1 != hash2) { + System.out.println("jarUrl1.hashCode = " + hash1); + System.out.println("jarUrl2.hashCode = " + hash2); + System.out.println("Equal urls should have same hashCode. " + + jarUrl1 + ", " + jarUrl2); + failed++; + } + } + + return failed; + } }