io.github.wycst.wast.common.expression.compile.CompilerEnvironment Maven / Gradle / Ivy
Show all versions of wast Show documentation
package io.github.wycst.wast.common.expression.compile;
import io.github.wycst.wast.common.expression.*;
import io.github.wycst.wast.common.expression.functions.JavassistExprFunction;
import java.lang.reflect.Modifier;
import java.util.*;
/**
* 表达式编译环境
*
* @Author: wangy
* @Date: 2021/11/20 0:00
* @Description:
*/
public class CompilerEnvironment extends EvaluateEnvironment {
public CompilerEnvironment() {
}
// 跳过解析直接使用源代码运行,支持所有java代码;
private boolean skipParse;
// 默认禁用system类调用
private boolean enableSystem;
// 禁用安全检查
private boolean disableSecurityCheck;
// disable keys
private Set disableKeys = new HashSet();
// 变量类型映射
private Map variableTypeMap = new LinkedHashMap();
// 变量类型映射
private List typeNameInvokers = new ArrayList();
protected List getTypeNameInvokers() {
return typeNameInvokers;
}
protected Map getVariableTypes() {
return variableTypeMap;
}
Map javassistFunctionMetaMap = new LinkedHashMap();
/**
* 拓展注册函数,仅仅在javassist编译下生效;
*
* note: 解决在javassist编译下泛型和基本类型(泛型不支持)引发生成的方法导致表达式调用类型不匹配问题;
* ps: 如果使用javassist编译带有自定义注册函数的表达式,请使用数组替换可变参数(javassist不支持);
*
* @param name 函数得名称,再表达式种通过@标识符调用
* @param function 函数对象
* @return
*/
public EvaluateEnvironment registerJavassistFunction(String name, JavassistExprFunction function, Class> returnClass, Class>... paramClassList) {
name.getClass();
returnClass.getClass();
function.getClass();
registerFunction(name, function);
ExprFunctionMeta exprFunctionMeta = new ExprFunctionMeta(name, function, returnClass, paramClassList);
javassistFunctionMetaMap.put(name, exprFunctionMeta);
return this;
}
static class ExprFunctionMeta {
String name;
JavassistExprFunction function;
Class> returnClass;
Class>[] paramClassList;
ExprFunctionMeta(String name, JavassistExprFunction function, Class> returnClass, Class>[] paramClassList) {
this.name = name;
this.function = function;
this.returnClass = returnClass;
this.paramClassList = paramClassList;
}
}
static class TypeNameInvoker implements Comparable {
final String varName;
final String defineJavaIdentifier;
final Class type;
final ElVariableInvoker variableInvoker;
public TypeNameInvoker(String varName, String defineJavaIdentifier, Class type, ElVariableInvoker variableInvoker) {
this.varName = varName;
this.defineJavaIdentifier = defineJavaIdentifier;
this.type = type;
this.variableInvoker = variableInvoker;
}
@Override
public int compareTo(TypeNameInvoker o) {
return varName.length() > o.varName.length() ? -1 : 1;
}
}
public void setVariableType(Class> type, String... vars) {
for (String var : vars) {
if (type == System.class) continue;
if (type == Runtime.class) continue;
if (!Modifier.isPublic(type.getModifiers())) {
throw new UnsupportedOperationException(type + " is not public access");
}
variableTypeMap.put(var, type);
}
}
/**
* 通过解析器初始化invoke
*
* @param parser
*/
void initTypeNameInvokers(CompilerExprParser parser) {
// 清除设置的变量信息
typeNameInvokers.clear();
if (parser.getVariableCount() == 0) return;
// Invoker variableValues = parser.getChainValues();
//// // collect variableValue if tail
// variableValues.internKey();
Collection tailInvokers = parser.getTailVariableInvokers(); // variableValues.tailInvokers();
for (ElVariableInvoker tailInvoker : tailInvokers) {
String varName = "_$" + tailInvoker.getIndex();
Class type = variableTypeMap.get(tailInvoker.toString());
if (type == null) {
type = double.class;
}
typeNameInvokers.add(new TypeNameInvoker(varName, varName, type, tailInvoker));
}
}
/**
* 通过variableTypeMap初始化invoke
*/
void initTypeNameInvokers() {
if (variableTypeMap.size() == 0) return;
typeNameInvokers.clear();
HashMap invokes = new HashMap();
HashMap tailInvokes = new HashMap();
Set> entrySet = variableTypeMap.entrySet();
for (Map.Entry entry : entrySet) {
String var = entry.getKey();
Class type = entry.getValue();
typeNameInvokers.add(new TypeNameInvoker(var, var.replace('.', '_'), type, ElVariableUtils.build(var, invokes, tailInvokes)));
}
Collections.sort(typeNameInvokers);
ElInvoker variableValues = ElChainVariableInvoker.build(invokes, true);
variableValues.internKey();
}
public boolean isSkipParse() {
return skipParse;
}
public void setSkipParse(boolean skipParse) {
this.skipParse = skipParse;
}
public boolean isEnableSystem() {
return enableSystem;
}
public void setEnableSystem(boolean enableSystem) {
this.enableSystem = enableSystem;
}
public boolean isDisableSecurityCheck() {
return disableSecurityCheck;
}
public void setDisableSecurityCheck(boolean disableSecurityCheck) {
this.disableSecurityCheck = disableSecurityCheck;
}
@Override
protected Map getFunctionMap() {
return super.getFunctionMap();
}
@Override
protected ExprFunction getFunction(String functionName) {
return super.getFunction(functionName);
}
/**
* 设置黑名单词组关键字调用防注入漏洞
*/
public void setKeyBlacklist(String... keys) {
for (String key : keys) {
disableKeys.add(key);
}
}
public void setKeyBlacklist(Collection keys) {
if (keys != null) {
disableKeys.addAll(keys);
}
}
public Set getDisableKeys() {
return disableKeys;
}
}