2010-11-14 61 views
1

我创建ConfigParser的子类,是容易,我在我的项目中使用:覆盖ConfigParser get()方法以包含eval的任何缺点?

class MyConfiguration(ConfigParser.ConfigParser): 

    def __init__(self, filename): 
     ConfigParser.ConfigParser.__init__(self) 
     self.readfp(open(filename)) 

    def get(self, section, option): 
     return eval(ConfigParser.ConfigParser.get(self, section, option)) 

问:是否有任何缺点(安全性,意想不到的后果)与一个重写的get()方法包括评估?

我宁愿将eval烧入MyConfiguration类,因为我想在我的配置文件中使用Python数据类型(元组等),但我不想处理遍布我的项目代码的evals。

+1

你的意思是,除了eval的所有常见缺点? – delnan 2010-11-14 14:25:07

回答

1

如果您在eval唯一的兴趣是文本值,你似乎表明,那么你可以使用ast.literal_eval

这将读取元组文字,列表文字和他人的安全使用,因为它是有选择性的关于什么将接受。

>>> import ast 
>>> a = ast.literal_eval('(1, 2, 3)') 
>>> a 
(1, 2, 3) 
>>> b = ast.literal_eval('__import__("evil")') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.6/ast.py", line 68, in literal_eval 
    return _convert(node_or_string) 
    File "/usr/lib/python2.6/ast.py", line 67, in _convert 
    raise ValueError('malformed string') 
ValueError: malformed string 

像这样的用例正是这个函数的目的。

1

我不确定评估可能包含在配置文件中的任意文本是否是个好主意。正常的eval调用通常被认为是不安全的。

参见:

  1. Security of Python's eval() on untrusted strings?
  2. Use of eval in Python?

如果你想使用Python的数据类型,那么它是更好的将其存储为一个Python模块和导入。在这种情况下,这可能是更好的解决方案。

你可以将配置文件拆分为包含Python模块中的python数据类型的配置文件,并将其余配置文件保存为可由configparser解析的配置文件。

+0

那么ConfigParser的典型用法是创建和使用具有基本数据类型(即那些有特定get()方法的配置文件,如str,int,float,boolean)?或者容器是允许的,但是eval通常在调用类中完成(可能有更好的方法来处理eval)? – MikeRand 2010-11-14 16:33:50

+0

@MikeRand:是的,最好在调用类中调用eval。尽管我的回答指出了eval的问题,但aaronasterling提供了更好的答案。你可以使用它。 – pyfunc 2010-11-14 17:17:01