Access simple bindings directly instead of accessing them via the Groovy engine
This commit is contained in:
parent
9209349f0c
commit
7afe232264
|
@ -13,7 +13,9 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.script.Bindings;
|
||||
import javax.script.Compilable;
|
||||
import javax.script.CompiledScript;
|
||||
|
@ -33,38 +35,6 @@ import groovy.lang.MissingPropertyException;
|
|||
|
||||
public class ExpressionFormat extends Format {
|
||||
|
||||
private static ScriptEngine engine;
|
||||
private static Map<String, CompiledScript> scriptletCache = new HashMap<String, CompiledScript>();
|
||||
|
||||
protected static ScriptEngine createScriptEngine() {
|
||||
CompilerConfiguration config = new CompilerConfiguration();
|
||||
|
||||
// include default functions
|
||||
ImportCustomizer imports = new ImportCustomizer();
|
||||
imports.addStaticStars(ExpressionFormatFunctions.class.getName());
|
||||
config.addCompilationCustomizers(imports);
|
||||
|
||||
GroovyClassLoader classLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);
|
||||
return new GroovyScriptEngineImpl(classLoader);
|
||||
}
|
||||
|
||||
protected static synchronized ScriptEngine getGroovyScriptEngine() throws ScriptException {
|
||||
if (engine == null) {
|
||||
engine = createScriptEngine();
|
||||
}
|
||||
return engine;
|
||||
}
|
||||
|
||||
protected static synchronized CompiledScript compileScriptlet(String expression) throws ScriptException {
|
||||
Compilable engine = (Compilable) getGroovyScriptEngine();
|
||||
CompiledScript scriptlet = scriptletCache.get(expression);
|
||||
if (scriptlet == null) {
|
||||
scriptlet = engine.compile(expression);
|
||||
scriptletCache.put(expression, scriptlet);
|
||||
}
|
||||
return scriptlet;
|
||||
}
|
||||
|
||||
private final String expression;
|
||||
|
||||
private final Object[] compilation;
|
||||
|
@ -230,21 +200,87 @@ public class ExpressionFormat extends Format {
|
|||
return lastException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parseObject(String source, ParsePosition pos) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private Object[] secure(Object[] compilation) {
|
||||
for (int i = 0; i < compilation.length; i++) {
|
||||
Object snipped = compilation[i];
|
||||
Object snippet = compilation[i];
|
||||
|
||||
if (snipped instanceof CompiledScript) {
|
||||
compilation[i] = new SecureCompiledScript((CompiledScript) snipped);
|
||||
// simple expressions like {n} can't contain any malicious code
|
||||
if (snippet instanceof Variable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (snippet instanceof CompiledScript) {
|
||||
compilation[i] = new SecureCompiledScript((CompiledScript) snippet);
|
||||
}
|
||||
}
|
||||
|
||||
return compilation;
|
||||
}
|
||||
|
||||
private static ScriptEngine engine;
|
||||
private static Map<String, CompiledScript> scriptletCache = new HashMap<String, CompiledScript>();
|
||||
|
||||
protected static ScriptEngine createScriptEngine() {
|
||||
CompilerConfiguration config = new CompilerConfiguration();
|
||||
|
||||
// include default functions
|
||||
ImportCustomizer imports = new ImportCustomizer();
|
||||
imports.addStaticStars(ExpressionFormatFunctions.class.getName());
|
||||
config.addCompilationCustomizers(imports);
|
||||
|
||||
GroovyClassLoader classLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);
|
||||
return new GroovyScriptEngineImpl(classLoader);
|
||||
}
|
||||
|
||||
protected static synchronized ScriptEngine getGroovyScriptEngine() throws ScriptException {
|
||||
if (engine == null) {
|
||||
engine = createScriptEngine();
|
||||
}
|
||||
return engine;
|
||||
}
|
||||
|
||||
protected static synchronized CompiledScript compileScriptlet(String expression) throws ScriptException {
|
||||
// simple expressions like {n} don't need to be interpreted by the script engine
|
||||
if (SourceVersion.isIdentifier(expression)) {
|
||||
return new Variable(expression);
|
||||
}
|
||||
|
||||
CompiledScript scriptlet = scriptletCache.get(expression);
|
||||
if (scriptlet == null) {
|
||||
Compilable engine = (Compilable) getGroovyScriptEngine();
|
||||
scriptlet = engine.compile(expression);
|
||||
scriptletCache.put(expression, scriptlet);
|
||||
}
|
||||
return scriptlet;
|
||||
}
|
||||
|
||||
private static class Variable extends CompiledScript {
|
||||
|
||||
private String name;
|
||||
|
||||
public Variable(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parseObject(String source, ParsePosition pos) {
|
||||
throw new UnsupportedOperationException();
|
||||
public Object eval(ScriptContext context) throws ScriptException {
|
||||
try {
|
||||
return context.getAttribute(name);
|
||||
} catch (Throwable t) {
|
||||
throw new ScriptException(new ExecutionException(t));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptEngine getEngine() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue