【仅供内部供应商使用,不提供对外解答和培训】

Page tree

【仅供内部供应商使用,不提供对外解答和培训】

Skip to end of metadata
Go to start of metadata

接口作用

拦截特定的函数执行,并返回自定义的函数,根据自定义函数的实现返回该值。

接口内容

主要接口

FunctionDefendProvider
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);
}


关联接口

AbstractFunction
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

  • No labels