LUCENE-5207: Add a test which verifies that the classloader restrictions work correctly

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/branches/lucene5207@1523419 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Uwe Schindler 2013-09-15 08:53:30 +00:00
parent f30af35667
commit 8574686af4
2 changed files with 55 additions and 1 deletions

View File

@ -87,7 +87,7 @@ public class JavascriptCompiler {
}
public Class<? extends Expression> define(String className, byte[] bytecode) {
return super.defineClass(className, bytecode, 0, bytecode.length).asSubclass(Expression.class);
return defineClass(className, bytecode, 0, bytecode.length).asSubclass(Expression.class);
}
}

View File

@ -17,6 +17,8 @@ package org.apache.lucene.expressions.js;
* limitations under the License.
*/
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
@ -157,4 +159,56 @@ public class TestCustomFunctions extends LuceneTestCase {
assertTrue(e.getMessage().contains("is not public"));
}
}
/** hack to load this test a second time in a different classLoader */
static class Loader extends ClassLoader {
Loader(ClassLoader parent) {
super(parent);
}
public Class<?> loadFromParentResource(String className) throws Exception {
final ByteArrayOutputStream byteCode = new ByteArrayOutputStream();
try (InputStream in = getParent().getResourceAsStream(className.replace('.', '/') + ".class")) {
final byte[] buf = new byte[1024];
int read;
do {
read = in.read(buf);
if (read > 0) byteCode.write(buf, 0, read);
} while (read > 0);
}
final byte[] bc = byteCode.toByteArray();
return defineClass(className, bc, 0, bc.length);
}
}
/** uses this test with a different classloader and tries to
* register it using the default classloader, which should fail */
public void testClassLoader() throws Exception {
Loader child = new Loader(this.getClass().getClassLoader());
Class<?> thisInDifferentLoader = child.loadFromParentResource(getClass().getName());
Map<String,Method> functions = Collections.singletonMap("zeroArgMethod", thisInDifferentLoader.getMethod("zeroArgMethod"));
// use our classloader, not the foreign one, which should fail!
try {
JavascriptCompiler.compile("zeroArgMethod()", functions, getClass().getClassLoader());
fail();
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage().contains("is not declared by a class which is accessible by the given parent ClassLoader"));
}
// this should pass:
JavascriptCompiler.compile("zeroArgMethod()", functions, child);
// mix foreign and default functions
Map<String,Method> mixedFunctions = new HashMap<>(JavascriptCompiler.DEFAULT_FUNCTIONS);
mixedFunctions.putAll(functions);
JavascriptCompiler.compile("zeroArgMethod()", mixedFunctions, child);
JavascriptCompiler.compile("sqrt(20)", mixedFunctions, child);
try {
JavascriptCompiler.compile("zeroArgMethod()", functions, getClass().getClassLoader());
fail();
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage().contains("is not declared by a class which is accessible by the given parent ClassLoader"));
}
}
}