groovy - 在 groovy 中使用评估时我的代码中是否有任何错误?
问题描述
我正在为嵌套 Map 设置值,键都存在,这是我的代码:
def map = [a1:[a2:[a3:'a123']], b1:[b2:[b3_1:'b234', b3_2:'b345']], d1:'d1']
def name2 = "b1:::b2:::b3_1"
def data = "test"
def separator = ":::"
def names = name2.split(separator)
setValue(map, names, data)
def setValue(def map, def keys, def data) {
tmpMap = map
String str = 'map'
for (i = 0; i < keys.size(); i++) {
str = str.concat('.'+ keys[i])
}
str = str.concat(" = '" + data + "'")
evaluate(str)
}
str 内容将为“map.b1.b2.b3_1 = 'test'” 我可以手动运行它并更改地图内容,但是当我使用评估时,出现“java.lang.NullPointerException:无法获取属性”错误'b2' on null object",你能告诉我代码有什么问题吗,非常感谢。
解决方案
你想做的事情很难...
一种方法是使用Eval.x
, 并将地图作为x
:
def setValue(Map map, String[] keys, String data) {
def command = "x.${keys.join('.')} = '$data'"
Eval.x(map, command)
}
所以在这里,命令将是:x.b1.b2.b3_1 = 'test'
我们用x
它的值来评估它map
另一种(更丑陋的)方法是使用 inject 遍历 map 直到最后一个键,然后设置这个返回对象的最后一个键的值:
def setValue(Map map, String[] keys, String data) {
keys[0..-2].inject(map) { a, b -> a."$b" }."${keys[-1]}" = data
}
不过,您应该警惕随意评估代码......
例如,您可能会收到以下输入:
def name2 = "val = { -> println \"${System.properties.'user.name'}\" }.call(); def a"
评估为表达式(对我而言):
x.val = { -> println "tim" }.call(); def a = 'test'
然后打印用户名......您可以看到它如何适用于从互联网下载文件并将其放在某人的机器上......
如果可以...您应该避免这种情况...或者至少对允许的内容有严格的白名单
推荐阅读
- javascript - 将一维推入二维数组javascript后获取除第一个数组外的空值
- azure - 调用 New-AzureRmVm 的输出在返回给调用者之前是不可访问的
- windows - 将标准输入设置为非阻塞
- c# - 无法读取使用 System.IdentityModel.Tokens.Jwt 生成的 JWT 令牌
- system.reactive - 如何顺序运行Tasks并将结果放入IObservable
- php - html onclick不会触发php函数
- c - 使用 GDB 调试时 1ms posix 计时器未正确计时
- python - 在管理员更改表单中如何访问我的模型的当前实例?
- tensorflow - 张量流成本等于无
- git - Visual Studio 项目文件夹约定