groovy - 在 Groovy 中实现 DSL 白名单

标签 groovy dsl

Groovy in Action提供以下代码,用于通过 SecureASTCustomizer 为 DSL 提供安全性。

// @author: Groovy in Action 
import org.codehaus.groovy.control.*
import org.codehaus.groovy.control.customizers.*

def secure = new SecureASTCustomizer()

secure.with {
                  closuresAllowed = false 
                  methodDefinitionAllowed = false 
                  importsWhitelist = [] 

                  staticImportsWhitelist = [] 
                  staticStarImportsWhitelist = ['java.lang.Math']

                  tokensWhitelist = [ 
                    PLUS, MINUS, MULTIPLY, DIVIDE, MOD, POWER, 
                    PLUS_PLUS, MINUS_MINUS, 
                    COMPARE_EQUAL, COMPARE_NOT_EQUAL, 
                    COMPARE_LESS_THAN, COMPARE_LESS_THAN_EQUAL, 
                    COMPARE_GREATER_THAN, COMPARE_GREATER_THAN_EQUAL, 
                  ]

                  constantTypesClassesWhiteList = [ 
                    Integer, Float, Long, Double, BigDecimal, 
                    Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE 
                  ]

                  receiversClassesWhiteList = [ 
                    Math, Integer, Float, Double, Long, BigDecimal 
                  ]

                  statementsWhitelist = [
                    BlockStatement, ExpressionStatement
                  ]

                  expressionsWhitelist = [ 
                    BinaryExpression, ConstantExpression,
                    MethodCallExpression, StaticMethodCallExpression,
                    ArgumentListExpression, PropertyExpression,
                    UnaryMinusExpression, UnaryPlusExpression,
                    PrefixExpression, PostfixExpression,
                    TernaryExpression, ElvisOperatorExpression,
                    BooleanExpression, ClassExpression
                  ] 
}

def config = new CompilerConfiguration()
config.addCompilationCustomizers(secure)

def shell = new GroovyShell(config)

x = shell.evaluate '''
    5 + 10  
    println("exiting...")
    System.exit(0)
'''

println x

但是,当我运行此代码时,出现运行时错误。

如何修复错误以使示例正常工作 - 即执行数学运算的 DSL,不允许任何其他类型的命令,例如 System.exit(0)

>groovy WhiteListSimple.groovy
Caught: groovy.lang.MissingPropertyException: No such property: PLUS for class: org.codehaus.groovy.control.customizers.SecureASTCustomizer
groovy.lang.MissingPropertyException: No such property: PLUS for class: org.codehaus.groovy.control.customizers.SecureASTCustomizer
        at WhiteListSimple$_run_closure1.doCall(WhiteListSimple.groovy:14)
        at WhiteListSimple.run(WhiteListSimple.groovy:6)

最佳答案

PLUS 和 friend 现在在

import static org.codehaus.groovy.syntax.Types.*

你还需要

import org.codehaus.groovy.ast.stmt.* // for the classes in `statementsWhitelist`
import org.codehaus.groovy.ast.expr.* // for the classes in `expressionsWhitelist`

鉴于这本书是 2009 年的,而您现在使用的是 2.3 范围内的 groovy,包/类位置只是随着时间的推移而发生了变化,或者那里的源代码从一开始就从未工作过。

您可能需要考虑一个 IDE,它可以帮助您查找类/创建导入

关于groovy - 在 Groovy 中实现 DSL 白名单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27412609/

相关文章:

斯卡拉 DSL : invocation that mimics English

scala - Scala : Lists without "," 中的内部 DSL

java - 将 XML 文本节点替换为元素节点

grails - Groovy 元编程 - 将静态方法添加到 Object.metaClass

java - Apache Camel - GSON JsonSerializer 在路线上使用

groovy - 有人可以解释一下 geb 页面内容 DSL 中的语法吗?

scala - 是否可以在 Scala 中创建 "restricted scope"?

parsing - 使用 TimeZone 格式化字符串日期

java - RapidMiner:通过 Id 属性访问 ExampleSet 的示例

mysql - 使用 Groovy 字符串作为 SQL select 语句