接口作用
拦截特定的函数执行,并返回自定义的函数,根据自定义函数的实现返回该值。
接口内容
主要接口
package com.fr.stable.fun;
import com.fr.stable.fun.mark.Selectable;
import com.fr.stable.script.CalculatorProvider;
import com.fr.stable.script.Function;
public interface FunctionDefendProvider extends Selectable {
String MARK_STRING = "FunctionDefendProvider";
int CURRENT_LEVEL = 1;
/**
* 占位的函数
*
* @param calculator 算子
* @param clazz 函数类
* @return 占位函数,替代掉有危险的函数
*/
Function replacer(CalculatorProvider calculator, Class clazz);
/**
* 实际函数的类
*
* @param calculator 算子
* @param clazz 函数类
* @return 是否要替换这个函数实现
*/
boolean match(CalculatorProvider calculator, Class clazz);
}
关联接口
package com.fr.script;
import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.Primitive;
import com.fr.stable.UtilEvalError;
import com.fr.stable.script.Node;
/**
* 这个表示函数参数按顺序执行
* 例如:SQRT (ABS(99) + 1)
* 执行顺序为:先算ABS(99)等于99,再计算99 +1等于100,最后计算SQRT(100)等于10
*/
public abstract class AbstractFunction extends CalculatorEmbeddedFunction {
/**
* 通过指定的参数,计算函数的结果
*
* @param arguments 参数
* @return 计算结果
* @throws UtilEvalError 如果在计算中出现无法解析的值,则抛出此异常
*/
public Object evalExpression(Node[] arguments) throws UtilEvalError {
Object returnValue;
if(this.getType() == HA){
returnValue = run(arguments);
}else{
Object[] args = new Object[arguments.length];
for (int i = 0; i < arguments.length; i++) {
args[i] = this.getCalculator().evalValue(arguments[i]);
}
returnValue = run(args);
}
if(returnValue == Primitive.ERROR_VALUE || returnValue == Primitive.ERROR_NAME){
FineLoggerFactory.getLogger().error(InterProviderFactory.getProvider().getLocText("Fine-Core_Base_NS_Cell_Formula") + this.toString());
}
return returnValue;
}
/**
* 计算函数结果
*
* 使用SUM公式进行计算,公式的使用:
*
* SUM sum = new SUM();
* System.out.println(sum.run(new Object[]{1, 2, 3}));
*
* @param args 函数的参数,是经过了算子处理了其中特殊参数的
* @return 计算结果
*/
public abstract Object run(Object[] args);
}
接口接入
<extra-core>
<FunctionDefendProvider class="com.fr.security.function.RemoteEvalFunctionDefender"/>
</extra-core>
示例效果
安装插件后,在决策平台的设置中开启公式的调用限制,并设置公式的返回值
可以看到再前端直接调用SQL公式,就会返回设置的值
接口示例
示例源码:https://code.fanruan.com/fanruan/demo-function-defender