代码之家  ›  专栏  ›  技术社区  ›  Ivo Danihelka

python中的安全表达式解析器

  •  14
  • Ivo Danihelka  · 技术社区  · 16 年前

    如何允许用户安全地执行数学表达式? 我需要写一个完整的解析器吗?

    有什么像 ast.literal_eval() 但是对于表达式呢?

    5 回复  |  直到 16 年前
        1
  •  10
  •   PaulMcG    16 年前

    这个 Pyparsing examples page 列出几个表达式分析器:

    http://pyparsing.wikispaces.com/file/view/fourFn.py -使用pyparsing的传统算术中缀表示法解析器/计算器实现(尽管它的名称是,实际上它执行5函数算术,加上几个trig函数)

    http://pyparsing.wikispaces.com/file/view/simpleBool.py -使用pyparsing助手方法的布尔中缀表示法分析器/计算器 operatorPrecedence 简化了中缀运算符符号的定义。

    http://pyparsing.wikispaces.com/file/view/simpleArith.py http://pyparsing.wikispaces.com/file/view/eval_arith.py - 一对使用fourfn.py重铸的示例 操作性接收 . 第一个只是解析并返回一个解析树,第二个添加了评估逻辑。

        2
  •  3
  •   Katriel    16 年前

    你想要什么样的表达式?变量分配?功能评估?

    SymPy 旨在成为一个成熟的Python CA。

        3
  •  1
  •   Zuljin    16 年前

    几周前,我做了类似的事情,但对于逻辑表达式(或,and,not,comparisons,圆括号等)。我是用 Ply 语法分析器。我创建了简单的lexer和parser。分析器生成了AST树,该树稍后用于执行计算。这样做可以让您完全控制用户输入的内容,因为只解析与语法兼容的表达式。

        4
  •  0
  •   jchl    16 年前

    对。即使有相当于 ast.literal_eval() 对于表达式,python表达式可以是许多东西,而不仅仅是纯数学表达式,例如任意函数调用。

    如果在一些开放源码模块中已经有了一个好的数学表达式解析器/评估器,我不会感到惊讶,但是如果没有,编写自己的模块就相当容易了。

        5
  •  -1
  •   Tony Delroy    16 年前

    数学函数将由数字和标点符号字符组成,如果您允许对有理数使用科学记数法,则可能是“e”或“e”,并且如果您允许/提供特定的数学函数(例如stdev),则字母字符的唯一(其他)合法使用将是。因此,在字符串中运行alpha字符并检查下一个小位是否可疑应该很简单,然后简单地在try/except块中对字符串进行eval。

    回复此回复收到的评论…我同意这种方法是玩火。尽管如此,这并不意味着它不能安全地完成。我对python还不熟悉(两个月),所以可能不知道它易受攻击的解决方法(当然,一个新的python版本在将来总是会使代码不安全),但是-就其价值而言(主要是我自己的娱乐),我的理解是:

    def evalMaths(s):
        i = 0
        while i < len(s):
            while s[i].isalpha() and i < len(s):
                idn += s[i]
                i += 1
            if (idn and idn != 'e' and idn != 'abs' and idn != 'round'):
                raise Exception("you naughty boy: don't " + repr(idn))
            else:
                i += 1
        return eval(s)
    

    我很想知道是否可以/如何规避…(顺便说一句,我知道你可以调用abs2783或这样的函数,如果它们存在的话,但是它们不会。我的意思是一些实用的。

    事实上,如果有人能做到的话,我会用200块奖金来创建一个问题,并接受他们的回答。