Revert "bpo-46110: Add a recursion check to avoid stack overflow in the PEG parser (GH-30177)" (GH-30363)

This reverts commit e9898bf153 temporarily as we want to confirm if this commit is the cause of a slowdown at startup time.
This commit is contained in:
Pablo Galindo Salgado 2022-01-03 18:29:18 +00:00 committed by GitHub
parent c960b191b8
commit 9d35dedc5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 3197 additions and 4602 deletions

View File

@ -1729,14 +1729,6 @@ while 1:
""" """
self._check_error(source, "too many statically nested blocks") self._check_error(source, "too many statically nested blocks")
@support.cpython_only
def test_error_on_parser_stack_overflow(self):
source = "-" * 100000 + "4"
for mode in ["exec", "eval", "single"]:
with self.subTest(mode=mode):
with self.assertRaises(MemoryError):
compile(source, "<string>", mode)
def load_tests(loader, tests, pattern): def load_tests(loader, tests, pattern):
tests.addTest(doctest.DocTestSuite()) tests.addTest(doctest.DocTestSuite())

View File

@ -1,2 +0,0 @@
Add a maximum recursion check to the PEG parser to avoid stack overflow.
Patch by Pablo Galindo

File diff suppressed because it is too large Load Diff

View File

@ -815,7 +815,6 @@ void *
_PyPegen_run_parser(Parser *p) _PyPegen_run_parser(Parser *p)
{ {
void *res = _PyPegen_parse(p); void *res = _PyPegen_parse(p);
assert(p->level == 0);
if (res == NULL) { if (res == NULL) {
if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_SyntaxError)) { if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_SyntaxError)) {
return NULL; return NULL;

View File

@ -37,8 +37,6 @@ EXTENSION_PREFIX = """\
# define D(x) # define D(x)
#endif #endif
# define MAXSTACK 6000
""" """
@ -366,14 +364,10 @@ class CParserGenerator(ParserGenerator, GrammarVisitor):
self.skip_actions = skip_actions self.skip_actions = skip_actions
def add_level(self) -> None: def add_level(self) -> None:
self.print("if (p->level++ == MAXSTACK) {") self.print("D(p->level++);")
with self.indent():
self.print("p->error_indicator = 1;")
self.print("PyErr_NoMemory();")
self.print("}")
def remove_level(self) -> None: def remove_level(self) -> None:
self.print("p->level--;") self.print("D(p->level--);")
def add_return(self, ret_val: str) -> None: def add_return(self, ret_val: str) -> None:
self.remove_level() self.remove_level()
@ -550,10 +544,9 @@ class CParserGenerator(ParserGenerator, GrammarVisitor):
self.print("p->in_raw_rule++;") self.print("p->in_raw_rule++;")
self.print(f"void *_raw = {node.name}_raw(p);") self.print(f"void *_raw = {node.name}_raw(p);")
self.print("p->in_raw_rule--;") self.print("p->in_raw_rule--;")
self.print("if (p->error_indicator) {") self.print("if (p->error_indicator)")
with self.indent(): with self.indent():
self.add_return("NULL") self.print("return NULL;")
self.print("}")
self.print("if (_raw == NULL || p->mark <= _resmark)") self.print("if (_raw == NULL || p->mark <= _resmark)")
with self.indent(): with self.indent():
self.print("break;") self.print("break;")