lib/re1.5: Check stack during compilecode.

Otherwise, a very deeply nested regular expression like

    re.compile("(" * 65536)

can exhaust the host stack during the compile phase. This turns
that into a `RuntimeError: maximum recursion depth exceeded`
instead.

This crash was found via fuzzing.

Signed-off-by: Jeff Epler <jepler@unpythonic.net>
This commit is contained in:
Jeff Epler
2026-04-08 16:33:27 -05:00
committed by Damien George
parent 98e4264ea6
commit bd69a0ddef
3 changed files with 28 additions and 0 deletions
+2
View File
@@ -29,6 +29,8 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode)
int term = PC;
int alt_label = 0;
re1_5_stack_chk();
for (; *re && *re != ')'; re++) {
switch (*re) {
case '\\':
+25
View File
@@ -0,0 +1,25 @@
# Test overflow in re.compile output code.
try:
import re
except ImportError:
print("SKIP")
raise SystemExit
def test_re(r):
try:
re.compile(r)
except:
print("Error")
try:
r = "(" * 65536 + ")" * 65536
except MemoryError:
print("SKIP")
raise SystemExit
# This happens to trigger RecursionError on current versions of CPython
# (tested with 3.13.5) as well, so no .exp file is needed.
test_re(r)
+1
View File
@@ -178,6 +178,7 @@ platform_tests_to_skip = {
"extmod/binascii_a2b_base64.py",
"extmod/deflate_compress_memory_error.py", # tries to allocate unlimited memory
"extmod/re_stack_overflow.py",
"extmod/re_stack_overflow2.py",
"extmod/time_res.py",
"extmod/vfs_posix.py",
"extmod/vfs_posix_enoent.py",