summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_compile.py
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2021-04-25 10:38:00 (GMT)
committerGitHub <noreply@github.com>2021-04-25 10:38:00 (GMT)
commitface87c94e67ad9c72b9a3724f112fd76c1002b9 (patch)
tree13d540eb4c3be35aff2f66bf981e300930ac0b49 /Lib/test/test_compile.py
parentb5adc8a7e5c13d175b4d3e53b37bc61de35b1457 (diff)
downloadcpython-face87c94e67ad9c72b9a3724f112fd76c1002b9.zip
cpython-face87c94e67ad9c72b9a3724f112fd76c1002b9.tar.gz
cpython-face87c94e67ad9c72b9a3724f112fd76c1002b9.tar.bz2
bpo-42609: Check recursion depth in the AST validator and optimizer (GH-23744)
Diffstat (limited to 'Lib/test/test_compile.py')
-rw-r--r--Lib/test/test_compile.py19
1 files changed, 12 insertions, 7 deletions
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index fd1ef61..d40347c 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -543,21 +543,26 @@ if 1:
# XXX (ncoghlan): duplicating the scaling factor here is a little
# ugly. Perhaps it should be exposed somewhere...
fail_depth = sys.getrecursionlimit() * 3
+ crash_depth = sys.getrecursionlimit() * 300
success_depth = int(fail_depth * 0.75)
- def check_limit(prefix, repeated):
+ def check_limit(prefix, repeated, mode="single"):
expect_ok = prefix + repeated * success_depth
- self.compile_single(expect_ok)
- broken = prefix + repeated * fail_depth
- details = "Compiling ({!r} + {!r} * {})".format(
- prefix, repeated, fail_depth)
- with self.assertRaises(RecursionError, msg=details):
- self.compile_single(broken)
+ compile(expect_ok, '<test>', mode)
+ for depth in (fail_depth, crash_depth):
+ broken = prefix + repeated * depth
+ details = "Compiling ({!r} + {!r} * {})".format(
+ prefix, repeated, depth)
+ with self.assertRaises(RecursionError, msg=details):
+ compile(broken, '<test>', mode)
check_limit("a", "()")
check_limit("a", ".b")
check_limit("a", "[0]")
check_limit("a", "*a")
+ # XXX Crashes in the parser.
+ # check_limit("a", " if a else a")
+ # check_limit("if a: pass", "\nelif a: pass", mode="exec")
def test_null_terminated(self):
# The source code is null-terminated internally, but bytes-like