mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-95588: Drop the safety claim from ast.literal_eval
docs. (#95919)
It was never really safe and this claim conflicts directly with the big warning in the docs about it being able to crash the interpreter.
This commit is contained in:
parent
bd7d0e875e
commit
8baef8ae36
3 changed files with 25 additions and 9 deletions
|
@ -1991,20 +1991,28 @@ and classes for traversing abstract syntax trees:
|
||||||
|
|
||||||
.. function:: literal_eval(node_or_string)
|
.. function:: literal_eval(node_or_string)
|
||||||
|
|
||||||
Safely evaluate an expression node or a string containing a Python literal or
|
Evaluate an expression node or a string containing only a Python literal or
|
||||||
container display. The string or node provided may only consist of the
|
container display. The string or node provided may only consist of the
|
||||||
following Python literal structures: strings, bytes, numbers, tuples, lists,
|
following Python literal structures: strings, bytes, numbers, tuples, lists,
|
||||||
dicts, sets, booleans, ``None`` and ``Ellipsis``.
|
dicts, sets, booleans, ``None`` and ``Ellipsis``.
|
||||||
|
|
||||||
This can be used for safely evaluating strings containing Python values from
|
This can be used for evaluating strings containing Python values without the
|
||||||
untrusted sources without the need to parse the values oneself. It is not
|
need to parse the values oneself. It is not capable of evaluating
|
||||||
capable of evaluating arbitrarily complex expressions, for example involving
|
arbitrarily complex expressions, for example involving operators or
|
||||||
operators or indexing.
|
indexing.
|
||||||
|
|
||||||
|
This function had been documented as "safe" in the past without defining
|
||||||
|
what that meant. That was misleading. This is specifically designed not to
|
||||||
|
execute Python code, unlike the more general :func:`eval`. There is no
|
||||||
|
namespace, no name lookups, or ability to call out. But it is not free from
|
||||||
|
attack: A relatively small input can lead to memory exhaustion or to C stack
|
||||||
|
exhaustion, crashing the process. There is also the possibility for
|
||||||
|
excessive CPU consumption denial of service on some inputs. Calling it on
|
||||||
|
untrusted data is thus not recommended.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
It is possible to crash the Python interpreter with a
|
It is possible to crash the Python interpreter due to stack depth
|
||||||
sufficiently large/complex string due to stack depth limitations
|
limitations in Python's AST compiler.
|
||||||
in Python's AST compiler.
|
|
||||||
|
|
||||||
It can raise :exc:`ValueError`, :exc:`TypeError`, :exc:`SyntaxError`,
|
It can raise :exc:`ValueError`, :exc:`TypeError`, :exc:`SyntaxError`,
|
||||||
:exc:`MemoryError` and :exc:`RecursionError` depending on the malformed
|
:exc:`MemoryError` and :exc:`RecursionError` depending on the malformed
|
||||||
|
|
|
@ -54,10 +54,12 @@ def parse(source, filename='<unknown>', mode='exec', *,
|
||||||
|
|
||||||
def literal_eval(node_or_string):
|
def literal_eval(node_or_string):
|
||||||
"""
|
"""
|
||||||
Safely evaluate an expression node or a string containing a Python
|
Evaluate an expression node or a string containing only a Python
|
||||||
expression. The string or node provided may only consist of the following
|
expression. The string or node provided may only consist of the following
|
||||||
Python literal structures: strings, bytes, numbers, tuples, lists, dicts,
|
Python literal structures: strings, bytes, numbers, tuples, lists, dicts,
|
||||||
sets, booleans, and None.
|
sets, booleans, and None.
|
||||||
|
|
||||||
|
Caution: A complex expression can overflow the C stack and cause a crash.
|
||||||
"""
|
"""
|
||||||
if isinstance(node_or_string, str):
|
if isinstance(node_or_string, str):
|
||||||
node_or_string = parse(node_or_string.lstrip(" \t"), mode='eval')
|
node_or_string = parse(node_or_string.lstrip(" \t"), mode='eval')
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
Clarified the conflicting advice given in the :mod:`ast` documentation about
|
||||||
|
:func:`ast.literal_eval` being "safe" for use on untrusted input while at
|
||||||
|
the same time warning that it can crash the process. The latter statement is
|
||||||
|
true and is deemed unfixable without a large amount of work unsuitable for a
|
||||||
|
bugfix. So we keep the warning and no longer claim that ``literal_eval`` is
|
||||||
|
safe.
|
Loading…
Add table
Add a link
Reference in a new issue