mirror of
https://github.com/python/cpython.git
synced 2025-12-23 09:19:18 +00:00
gh-141778: add missing validation in ast.literal_eval() for non-string input
This also changes parsing of the private `__text_signature__` attribute by inspect.signature(). Now we accept here only types, valid for ast.Constant().
This commit is contained in:
parent
1391ee664c
commit
7c90e20a2c
5 changed files with 22 additions and 4 deletions
13
Lib/ast.py
13
Lib/ast.py
|
|
@ -59,17 +59,26 @@ def literal_eval(node_or_string):
|
|||
"""
|
||||
if isinstance(node_or_string, str):
|
||||
node_or_string = parse(node_or_string.lstrip(" \t"), mode='eval').body
|
||||
return _convert_literal(node_or_string, True)
|
||||
elif isinstance(node_or_string, Expression):
|
||||
node_or_string = node_or_string.body
|
||||
return _convert_literal(node_or_string)
|
||||
|
||||
|
||||
def _convert_literal(node):
|
||||
_type_None = type(None)
|
||||
_type_Ellipsis = type(...)
|
||||
|
||||
|
||||
def _convert_literal(node, omit_validation=False):
|
||||
"""
|
||||
Used by `literal_eval` to convert an AST node into a value.
|
||||
"""
|
||||
if isinstance(node, Constant):
|
||||
return node.value
|
||||
if omit_validation:
|
||||
return node.value
|
||||
if type(value := node.value) in (str, bytes, int, float, complex,
|
||||
bool, _type_None, _type_Ellipsis):
|
||||
return value
|
||||
if isinstance(node, Dict) and len(node.keys) == len(node.values):
|
||||
return dict(zip(
|
||||
map(_convert_literal, node.keys),
|
||||
|
|
|
|||
|
|
@ -2216,7 +2216,8 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
|
|||
except NameError:
|
||||
raise ValueError
|
||||
|
||||
if isinstance(value, (str, int, float, bytes, bool, type(None))):
|
||||
if type(value) in (str, int, float, bytes, bool, complex,
|
||||
type(None), type(...)):
|
||||
return ast.Constant(value)
|
||||
raise ValueError
|
||||
|
||||
|
|
|
|||
|
|
@ -1890,6 +1890,10 @@ Module(
|
|||
self.assertRaises(ValueError, ast.literal_eval, '++6')
|
||||
self.assertRaises(ValueError, ast.literal_eval, '+True')
|
||||
self.assertRaises(ValueError, ast.literal_eval, '2+3')
|
||||
# gh-141778: reject values of invalid types
|
||||
node = ast.Expression(body=ast.Constant(object()))
|
||||
ast.fix_missing_locations(node)
|
||||
self.assertRaises(ValueError, ast.literal_eval, node)
|
||||
|
||||
def test_literal_eval_str_int_limit(self):
|
||||
with support.adjust_int_max_str_digits(4000):
|
||||
|
|
|
|||
|
|
@ -6286,7 +6286,9 @@ class TestSignatureDefinitions(unittest.TestCase):
|
|||
def test_thread_module_has_signatures(self):
|
||||
import _thread
|
||||
no_signature = {'RLock'}
|
||||
self._test_module_has_signatures(_thread, no_signature)
|
||||
unsupported_signature = {'interrupt_main'}
|
||||
self._test_module_has_signatures(_thread, no_signature,
|
||||
unsupported_signature)
|
||||
|
||||
def test_time_module_has_signatures(self):
|
||||
no_signature = {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
Validate value types of :class:`ast.Constant` nodes in the
|
||||
:func:`ast.literal_eval`. Patch by Sergey B Kirpichev.
|
||||
Loading…
Add table
Add a link
Reference in a new issue