Re: 4523159: suggestion for a bugfix for 13 year old "jars in path with !"

2015-09-15 Thread Stuart Marks

Hi Daniel,

Thanks for looking at this old bug.

I'm concerned about the approach of looking in the filesystem to determine how 
to parse the URL. If that's the case, then it's no longer possible to look at 
just the URL string and determine what it represents. Instead, it's possible 
that different systems will parse the URL differently depending upon the 
contents of their filesystems, or that the same system will parse the same URL 
differently at different times if the contents of its filesystem has changed. 
That leads toward another, different class of errors.


There is clearly a bug here, which is that the '!' character is ambiguous: 
either it's the separator between the jar filename and the path to the entry 
within the jar file, or it's part of the jar filename. The solution suggested in 
the bug report by Michael McMahon (cc'd) is to allow for a quoting or escape 
mechanism to disambiguate the meaning of the '!' character.


Would it be possible to pursue that solution?

s'marks

On 9/15/15 5:27 AM, Daniel Wilhlem wrote:

Hi,

Our download manager http://jdownloader.org/ has millions of customers.
Some of them also suffered from the 13 year old bug 
http://bugs.java.com/view_bug.do?bug_id=4523159.
The issue happens because '!/' is used as seperator between a jar file and its 
content in URLStreamHandler and JarURLConnection.


I hereby want to suggest our bugfix.

It consists of a modified sun.net.www.protocol.jar.Handler and 
sun.net.www.protocol.jar.JarURLConnection.
Instead of searching for '!/' and using the first hit, our customized 
sun.net.www.protocol.jar.Handler loops through URL.getFile()

via indexof and substring and tests if it specifies the actual jar file on disk.
In case the path contains '!/' we return a customized 
sun.net.www.protocol.jar.JarURLConnection that overrides

getJarFileURL(),getJarEntry(),getEntryName() to provide the correct information.

The one disadvantage of this bugfix is the additional IO introduced by 
File.exits(), but that can be considered//neglectable/./


Please find attached our customized classes.

Best Regards
Daniel Wilhelm

PS: sean.cof...@oracle.com/sean.cof...@oracle.com told me to post this to 
net-dev
--
---
Daniel Wilhelm
CTO, Co-Founder
Appwork GmbH

T: +49 (911)97923112 (Mo-Fr 9:00 - 17:00 CET)

Schwabacherstraße 117,   90763 Fürth,  Germany




4523159: suggestion for a bugfix for 13 year old "jars in path with !"

2015-09-15 Thread Daniel Wilhlem

Hi,

Our download manager http://jdownloader.org/ has millions of customers.
Some of them also suffered from the 13 year old bug 
http://bugs.java.com/view_bug.do?bug_id=4523159.
The issue happens because '!/' is used as seperator between a jar file 
and its content in URLStreamHandler and JarURLConnection.


I hereby want to suggest our bugfix.

It consists of a modified sun.net.www.protocol.jar.Handler and 
sun.net.www.protocol.jar.JarURLConnection.
Instead of searching for '!/' and using the first hit, our customized 
sun.net.www.protocol.jar.Handler loops through URL.getFile()
via indexof and substring and tests if it specifies the actual jar file 
on disk.
In case the path contains '!/' we return a customized 
sun.net.www.protocol.jar.JarURLConnection that overrides
getJarFileURL(),getJarEntry(),getEntryName() to provide the correct 
information.


The one disadvantage of this bugfix is the additional IO introduced by 
File.exits(), but that can be considered//neglectable/./


Please find attached our customized classes.

Best Regards
Daniel Wilhelm

PS: sean.cof...@oracle.com/sean.cof...@oracle.com told me to post this 
to net-dev


--
---
Daniel Wilhelm
CTO, Co-Founder
Appwork GmbH

T: +49 (911)97923112 (Mo-Fr 9:00 - 17:00 CET)

Schwabacherstraße 117,   90763 Fürth,  Germany

public class OracleWorkaroundJarHandler extends sun.net.www.protocol.jar.Handler {

@Override
protected URLConnection openConnection(final URL url) throws IOException {
try {
// System.out.println("openConnection:" + url);
final String path = url.getFile();
URL jarFileURL = null;
int lastIndex = 0;
if (path.startsWith("file:")) {
while (true) {
final int indexOf = path.indexOf(".jar", lastIndex);
if (indexOf > 0) {
final int index = indexOf + 4;
lastIndex = index;
final String jarFileName = path.substring(0, index);
if (jarFileName.contains("!/")) {
final File jarFile;
final URL jarURL;
try {
jarURL = new URL(jarFileName);
jarFile = new File(jarURL.toURI());
} catch (Exception e) {
e.printStackTrace();
continue;
}
if (jarFile.exists() && jarFile.isFile()) {
jarFileURL = jarURL;
break;
}
}
} else {
break;
}
}
}
if (jarFileURL != null) {
lastIndex++;// skip !
final URL finalJarFileURL = jarFileURL;
final String entryName;
if (++lastIndex != path.length()) {
final String tempEntryName = path.substring(lastIndex, path.length());
entryName = sun.net.www.ParseUtil.decode(tempEntryName);
} else {
entryName = null;
}
System.out.println("Workaround for URL.openConnection:" + finalJarFileURL + " Entry:" + entryName);
return new sun.net.www.protocol.jar.JarURLConnection(url, this) {
@Override
public URL getJarFileURL() {
return finalJarFileURL;
}

@Override
public JarEntry getJarEntry() throws IOException {
return getJarFile().getJarEntry(getEntryName());
}

@Override
public String getEntryName() {
return entryName;
}
};
}
} catch (final Throwable e) {
e.printStackTrace();
}
return super.openConnection(url);

}
}