一个更好的替代 eval()

A better alternative to eval()

我正在寻找 python 字符串计算器 eval()

的替代品
from telethon import Button

c = "Click Here To Open Google | [Button.url('Google', 'google.com')]"
if "|" in c:
   filter, options= c.split("|")
filter = filter.strip()     
button = options.strip()

g = eval(button)
await event.reply(filter, buttons=g)

这里使用 eval()related to this 一样危险,我可以用什么来替代?

更安全的替代方法是 ast.literal_eval,但与 eval() 相比,它非常受限,仅适用于代表有效 Python 文字的字符串,至少对于您的示例而言。

更好的建议是自己解析字符串,首先你可以使用正则表达式获取两个参数:

import re

c = "Click Here To Open Google | [Button.url('Google', 'google.com')]"
if "|" in c:
   filter, options= c.split("|")
filter = filter.strip()     
button = options.strip()
params = re.findall(r'\'(.*)\'',button)

returns params 中的 ["Google', 'google.com"] 列表。

然后你可以使用if检查它是否包含恶意输入,如果然后修改它或阻止用户,否则解压到使用Button.url(*params)

的方法

使用ast.literal_eval

所以你会有

from telethon import Button
import ast

c = "Click Here To Open Google | [Button.url('Google', 'google.com')]"
if "|" in c:
   filter, options= c.split("|")
filter = filter.strip()
button = options.strip()

g = ast.literal_eval(button)
await event.reply(filter, buttons=g)

你的 API 坏了。如果您要求用户使用 python 代码,那么可以 来评估它。 eval 可以通过指定评估的代码可以使用哪个 locals/globals 来变得更难利用,但是要使代码安全是非常困难的......此外,一旦你开始将内置函数列入黑名单,它就变成了编码极其困难,而且 API 因为很难理解,因为不清楚你能做什么或不能做什么。

处理此问题的正确方法是以结构化数据而不是可执行代码

的形式提供该信息

现有的格式有很多JSON、yaml、xml等

我将使用 JSON 作为示例,因为现在它很常见并且 stdlib 有一个实现:

import json

c = '''
{
    "filter": Click Here To Open Google",
    "button": {
        "label": "Google",
        "url": "google.com"
    }
}
'''
data = json.loads(c)
filter = data['filter']
if 'button' in data:
    options = data['button']
    g = Button.url(options['label'], options['url'])
elif 'checkbox' in data:
     # as an example
    options = data['checkbox']
    g = Checkbox.url(options['label'], options['url'], options['status'])

await event.reply(filter, buttons=[g])

显然,根据您希望赋予用户多少权力,数据将变得越来越复杂,处理起来也越来越复杂。您必须考虑用户可能想要做什么,以及如何将该信息指定为数据以及如何处理它。这不是一件容易或简单的任务。不幸的是,我们无法真正帮助您解决这个问题,因为您提供了一个示例,而这需要对应支持的用例有完整的了解。

eval 可能对不适用于其他人或互联网的早期原型或家庭模式脚本有用。

使用数据的额外好处:您现在可以轻松地用不同的语言重新实现应用程序的一部分。如果您使用 python,则必须实现一个完整的 python 解释器。