https://bz.apache.org/bugzilla/show_bug.cgi?id=65586
Bug ID: 65586
Summary: JarContents#mightContainResource doesn't return true
when found directory in jar file by using bloom filter
Product: Tomcat 9
Version: unspecified
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P2
Component: Catalina
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: -----
Dear all
When using a bloom filter to speed up archive lookups
(useBloomFilterForArchives = "true" in context.xml) in Tomcat9, tomcat will
fail to get resources from jar file in some special condition.
For example , when we want to find a directory resource in xxx.jar by using a
bloom filter,
if we use " cl.getResouce("/org/apache/coyote", "/WEB-INF/classes") " to get
resources , noting will be returned,
(By the way,
we find the same way to be used to get resources in the xmlbeans-4.0.0.jar
org.apache.xmlbeans.impl.schema.SchemaTypeLoaderImpl#isPath30)
but if we use cl.getResouce("/org/apache/coyote/", "/WEB-INF/classes") , it
will return the resources we want successfully.
if we do not use bloomFilter , both ways will return resources successfully.
It is cause by org.apache.catalina.webresources.JarContents#JarContents who
create hashCode of JarEntry.getName(), if JarEntry is directory, its name
contain
"/" at the last of string.
So when you use param didn't contain "/" at last,
org.apache.catalina.webresources.JarContents#mightContainResource will return
false.
For example:
JarFile jarFile = new JarFile("D:\\tomcat-coyote.jar");
JarContents jarContents = new JarContents(jarFile);
// false
System.out.println(jarContents.mightContainResource("/org/apache/catalina",
"/WEB-INF/classes"));
// true
System.out.println(jarContents.mightContainResource("/org/apache/catalina/",
"/WEB-INF/classes"));
So I suggest changing JarContents#hashcode like this to ignore end slash of
path
private int hashcode(String content, int startPos, int hashPrime) {
int h = hashPrime/2;
int contentLength = content.length();
if (contentLength > 1 && content.charAt(contentLength - 1) == '/') {
// ignore end slash
contentLength--;
}
for (int i = startPos; i < contentLength; i++) {
h = hashPrime * h + content.charAt(i);
}
if (h < 0) {
h = h * -1;
}
return h;
}
sorry ,I am not native speaker , hope that I made it clear!
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]