Merge remote-tracking branch 'origin/jetty-8'

Conflicts:
	jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
	jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java
This commit is contained in:
Jan Bartel 2013-08-08 14:24:19 +10:00
commit bd1b19b45c
4 changed files with 76 additions and 18 deletions

View File

@ -71,6 +71,11 @@
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty.toolchain</groupId> <groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId> <artifactId>jetty-test-helper</artifactId>

View File

@ -753,7 +753,7 @@ public class AnnotationParser
public void parseDir (Resource dir, ClassNameResolver resolver) public void parseDir (Resource dir, ClassNameResolver resolver)
throws Exception throws Exception
{ {
if (!dir.isDirectory() || !dir.exists()) if (!dir.isDirectory() || !dir.exists() || dir.getName().startsWith("."))
return; return;
if (LOG.isDebugEnabled()) {LOG.debug("Scanning dir {}", dir);}; if (LOG.isDebugEnabled()) {LOG.debug("Scanning dir {}", dir);};
@ -767,7 +767,7 @@ public class AnnotationParser
if (res.isDirectory()) if (res.isDirectory())
parseDir(res, resolver); parseDir(res, resolver);
String name = res.getName(); String name = res.getName();
if (name.endsWith(".class")) if (isValidClassFileName(name))
{ {
if ((resolver == null)|| (!resolver.isExcluded(name) && (!isParsed(name) || resolver.shouldOverride(name)))) if ((resolver == null)|| (!resolver.isExcluded(name) && (!isParsed(name) || resolver.shouldOverride(name))))
{ {
@ -812,8 +812,12 @@ public class AnnotationParser
{ {
try try
{ {
//skip directories
if (entry.isDirectory())
return;
String name = entry.getName(); String name = entry.getName();
if (name.toLowerCase(Locale.ENGLISH).endsWith(".class")) if (isValidClassFileName(name))
{ {
String shortName = name.replace('/', '.').substring(0,name.length()-6); String shortName = name.replace('/', '.').substring(0,name.length()-6);
if ((resolver == null) if ((resolver == null)
@ -930,28 +934,33 @@ public class AnnotationParser
JarEntry entry = jar_in.getNextJarEntry(); JarEntry entry = jar_in.getNextJarEntry();
while (entry!=null) while (entry!=null)
{ {
try //skip directories
if (!entry.isDirectory())
{ {
String name = entry.getName(); try
if (name.toLowerCase(Locale.ENGLISH).endsWith(".class"))
{ {
String shortName = name.replace('/', '.').substring(0,name.length()-6); String name = entry.getName();
if ((resolver == null) //skip any class files that are in a hidden directory (ie dirname starts with .)
|| if (isValidClassFileName(name))
(!resolver.isExcluded(shortName) && (!isParsed(shortName) || resolver.shouldOverride(shortName))))
{ {
Resource clazz = Resource.newResource("jar:"+uri+"!/"+name); String shortName = name.replace('/', '.').substring(0,name.length()-6);
if (LOG.isDebugEnabled()) {LOG.debug("Scanning class from jar {}", clazz);};
scanClass(clazz.getInputStream()); if ((resolver == null)
||
(!resolver.isExcluded(shortName) && (!isParsed(shortName) || resolver.shouldOverride(shortName))))
{
Resource clazz = Resource.newResource("jar:"+uri+"!/"+name);
if (LOG.isDebugEnabled()) {LOG.debug("Scanning class from jar {}", clazz);};
scanClass(clazz.getInputStream());
}
} }
} }
catch (Exception e)
{
LOG.warn("Problem processing jar entry "+entry, e);
}
} }
catch (Exception e)
{
LOG.warn("Problem processing jar entry "+entry, e);
}
entry = jar_in.getNextJarEntry(); entry = jar_in.getNextJarEntry();
} }
} }
@ -975,5 +984,37 @@ public class AnnotationParser
ClassReader reader = new ClassReader(is); ClassReader reader = new ClassReader(is);
reader.accept(new MyClassVisitor(), ClassReader.SKIP_CODE|ClassReader.SKIP_DEBUG|ClassReader.SKIP_FRAMES); reader.accept(new MyClassVisitor(), ClassReader.SKIP_CODE|ClassReader.SKIP_DEBUG|ClassReader.SKIP_FRAMES);
} }
/**
* Check that the given path represents a valid class file name.
* The check is fairly cursory, checking that:
* <ul>
* <li> the name ends with .class</li>
* <li> it isn't a dot file or in a hidden directory </li>
* <li> the name of the class at least begins with a valid identifier for a class name </li>
* </ul>
* @param path
* @return
*/
private boolean isValidClassFileName (String path)
{
//skip anything that is not a class file
if (!path.toLowerCase(Locale.ENGLISH).endsWith(".class"))
return false;
//skip any classfiles that are not a valid name
int c0 = 0;
int ldir = path.lastIndexOf('/', path.length()-6);
c0 = (ldir > -1 ? ldir+1 : c0);
if (!Character.isJavaIdentifierStart(path.charAt(c0)))
return false;
//skip any classfiles that are in a hidden directory
if (path.startsWith(".") || path.contains("/."))
return false;
return true;
}
} }

View File

@ -22,11 +22,13 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.eclipse.jetty.annotations.AnnotationParser.DiscoverableAnnotationHandler; import org.eclipse.jetty.annotations.AnnotationParser.DiscoverableAnnotationHandler;
import org.eclipse.jetty.annotations.AnnotationParser.Value; import org.eclipse.jetty.annotations.AnnotationParser.Value;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.Test; import org.junit.Test;
public class TestAnnotationParser public class TestAnnotationParser
@ -162,4 +164,14 @@ public class TestAnnotationParser
parser.registerHandler(new MultiAnnotationHandler()); parser.registerHandler(new MultiAnnotationHandler());
parser.parse(classNames, null); parser.parse(classNames, null);
} }
@Test
public void testHiddenFilesInJar () throws Exception
{
File badClassesJar = MavenTestingUtils.getTestResourceFile("bad-classes.jar");
AnnotationParser parser = new AnnotationParser();
parser.parse(badClassesJar.toURI(), null);
//only the valid classes inside bad-classes.jar should be parsed. If any invalid classes are parsed and exception would be thrown here
}
} }

Binary file not shown.