Skip to content

Commit 7c90e20

Browse files
committed
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().
1 parent 1391ee6 commit 7c90e20

File tree

5 files changed

+22
-4
lines changed

5 files changed

+22
-4
lines changed

Lib/ast.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,26 @@ def literal_eval(node_or_string):
5959
"""
6060
if isinstance(node_or_string, str):
6161
node_or_string = parse(node_or_string.lstrip(" \t"), mode='eval').body
62+
return _convert_literal(node_or_string, True)
6263
elif isinstance(node_or_string, Expression):
6364
node_or_string = node_or_string.body
6465
return _convert_literal(node_or_string)
6566

6667

67-
def _convert_literal(node):
68+
_type_None = type(None)
69+
_type_Ellipsis = type(...)
70+
71+
72+
def _convert_literal(node, omit_validation=False):
6873
"""
6974
Used by `literal_eval` to convert an AST node into a value.
7075
"""
7176
if isinstance(node, Constant):
72-
return node.value
77+
if omit_validation:
78+
return node.value
79+
if type(value := node.value) in (str, bytes, int, float, complex,
80+
bool, _type_None, _type_Ellipsis):
81+
return value
7382
if isinstance(node, Dict) and len(node.keys) == len(node.values):
7483
return dict(zip(
7584
map(_convert_literal, node.keys),

Lib/inspect.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2216,7 +2216,8 @@ def wrap_value(s):
22162216
except NameError:
22172217
raise ValueError
22182218

2219-
if isinstance(value, (str, int, float, bytes, bool, type(None))):
2219+
if type(value) in (str, int, float, bytes, bool, complex,
2220+
type(None), type(...)):
22202221
return ast.Constant(value)
22212222
raise ValueError
22222223

Lib/test/test_ast/test_ast.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1890,6 +1890,10 @@ def test_literal_eval(self):
18901890
self.assertRaises(ValueError, ast.literal_eval, '++6')
18911891
self.assertRaises(ValueError, ast.literal_eval, '+True')
18921892
self.assertRaises(ValueError, ast.literal_eval, '2+3')
1893+
# gh-141778: reject values of invalid types
1894+
node = ast.Expression(body=ast.Constant(object()))
1895+
ast.fix_missing_locations(node)
1896+
self.assertRaises(ValueError, ast.literal_eval, node)
18931897

18941898
def test_literal_eval_str_int_limit(self):
18951899
with support.adjust_int_max_str_digits(4000):

Lib/test/test_inspect/test_inspect.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6286,7 +6286,9 @@ def test_threading_module_has_signatures(self):
62866286
def test_thread_module_has_signatures(self):
62876287
import _thread
62886288
no_signature = {'RLock'}
6289-
self._test_module_has_signatures(_thread, no_signature)
6289+
unsupported_signature = {'interrupt_main'}
6290+
self._test_module_has_signatures(_thread, no_signature,
6291+
unsupported_signature)
62906292

62916293
def test_time_module_has_signatures(self):
62926294
no_signature = {
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Validate value types of :class:`ast.Constant` nodes in the
2+
:func:`ast.literal_eval`. Patch by Sergey B Kirpichev.

0 commit comments

Comments
 (0)