简体   繁体   English

通过Python的eval()运行JSON?

[英]Running JSON through Python's eval()?

Best practices aside, is there a compelling reason not to do this? 除了最好的做法,有没有令人信服的理由这样做?

I'm writing a post-commit hook for use with a Google Code project, which provides commit data via a JSON object. 我正在编写一个post-commit钩子,用于Google Code项目,该项目通过JSON对象提供提交数据。 GC provides an HMAC authentication token along with the request (outside the JSON data), so by validating that token I gain high confidence that the JSON data is both benign (as there's little point in distrusting Google) and valid. GC提供HMAC身份验证令牌以及请求(在JSON数据之外),因此通过验证该令牌,我可以高度确信JSON数据是良性的(因为不信任Google)并且有效。

My own (brief) investigations suggest that JSON happens to be completely valid Python, with the exception of the "\\/" escape sequence — which GC doesn't appear to generate. 我自己(简短)的调查表明,JSON恰好是完全有效的Python,除了"\\/"转义序列 - GC似乎没有生成。

So, as I'm working with Python 2.4 (ie no json module), eval() is looking really tempting. 因此,当我使用Python 2.4(即没有json模块)时, eval()看起来真的很诱人。

Edit: For the record, I am very much not asking if this is a good idea. 编辑:为了记录,我不是在问这是不是一个好主意。 I'm quite aware that it isn't, and I very much doubt I'll ever use this technique for any future projects even if I end up using it for this one. 非常清楚它不是,我非常怀疑即使我最终将它用于这个项目,我也会将这项技术用于任何未来的项目。 I just wanted to make sure that I know what kind of trouble I'll run into if I do. 我只是想确保我知道如果我这样做会遇到什么样的麻烦。 :-) :-)

If you're comfortable with your script working fine for a while, and then randomly failing on some obscure edge case, I would go with eval. 如果你对你的脚本工作正常一段时间感觉很舒服,然后在一些不起眼的边缘情况下随机失败,我会选择eval。

If it's important that your code be robust, I would take the time to add simplejson. 如果你的代码很健壮很重要,我会花时间添加simplejson。 You don't need the C portion for speedups, so it really shouldn't be hard to dump a few .py files into a directory somewhere. 你不需要C部分来加速,所以将一些.py文件转储到某个目录中真的不难。

As an example of something that might bite you, JSON uses Unicode and simplejson returns Unicode, whereas eval returns str: 作为可能咬你的东西的一个例子,JSON使用Unicode而simplejson返回Unicode,而eval返回str:

>>> simplejson.loads('{"a":1, "b":2}')
{u'a': 1, u'b': 2}
>>> eval('{"a":1, "b":2}')
{'a': 1, 'b': 2}

Edit: a better example of where eval() behaves differently: 编辑:eval()行为不同的更好示例:

>>> simplejson.loads('{"X": "\uabcd"}')
{u'X': u'\uabcd'}
>>> eval('{"X": "\uabcd"}')
{'X': '\\uabcd'}
>>> simplejson.loads('{"X": "\uabcd"}') == eval('{"X": "\uabcd"}')
False

Edit 2: saw yet another problem today pointed out by SilentGhost: eval doesn't handle true -> True, false -> False, null -> None correctly. 编辑2:看到今天SilentGhost指出的另一个问题:eval不能处理true - > True,false - > False,null - > None not correct。

>>> simplejson.loads('[false, true, null]')
[False, True, None]
>>> eval('[false, true, null]')
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'false' is not defined
>>> 

The point of best practices is that in most cases, it's a bad idea to disregard them. 最佳实践的观点是,在大多数情况下,忽视它们是一个坏主意。 If I were you, I'd use a parser to parse JSON into Python. 如果我是你,我会使用解析器将JSON解析为Python。 Try out simplejson , it was very straightforward for parsing JSON when I last tried it and it claims to be compatible with Python 2.4. 尝试使用simplejson ,在我上次尝试时解析JSON非常简单,它声称与Python 2.4兼容。

I disagree that there's little point in distrusting Google. 我不同意谷歌不信任这一点。 I wouldn't distrust them, but I'd verify the data you get from them. 我不会不信任他们,但我会核实你从他们那里得到的数据。 The reason that I'd actually use a JSON parser is right in your question: 我实际使用JSON解析器的原因正好在你的问题中:

My own (brief) investigations suggest that JSON happens to be completely valid Python, with the exception of the "/" escape sequence — which GC doesn't appear to generate. 我自己(简短)的研究表明,JSON恰好是完全有效的Python,除了“/”转义序列 - GC似乎没有生成。

What makes you think that Google Code will never generate an escape sequence like that? 是什么让你认为Google Code永远不会产生这样的转义序列?

Parsing is a solved problem if you use the right tools. 如果使用正确的工具,解析是一个已解决的问题。 If you try to take shortcuts like this, you'll eventually get bitten by incorrect assumptions, or you'll do something like trying to hack together a parser with regex's and boolean logic when a parser already exists for your language of choice. 如果你试图采用这样的快捷方式,你最终会被错误的假设所困扰,或者你会做一些事情,比如当你的选择语言已经存在解析器时,尝试用正则表达式和布尔逻辑来破解解析器。

One major difference is that a boolean in JSON is true | 一个主要区别是JSON中的布尔值为true false , but Python uses True | false ,但Python使用True | False . False

The most important reason not to do this can be generalized: eval should never be used to interpret external input since this allows for arbitrary code execution. 不执行此操作的最重要原因可以概括为: eval不应该用于解释外部输入,因为这允许任意代码执行。

eval ing JSON is a bit like trying to run XML through a C++ compiler. eval JSON有点像尝试通过C ++编译器运行XML。

eval is meant to evaluate Python code. eval旨在评估Python代码。 Although there are some syntactical similarities, JSON isn't Python code . 尽管存在一些语法上的相似之处,但JSON不是Python代码 Heck, not only is it not Python code, it's not code to begin with. 哎呀,不仅不是Python代码,它不是代码开头。 Therefore, even if you can get away with it for your use-case, I'd argue that it's a bad idea conceptually. 因此,即使你可以为你的用例侥幸逃脱,我也认为从概念上来说这是一个坏主意。 Python is an apple, JSON is orange-flavored soda. Python是一个苹果,JSON是橙味的苏打水。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM