Skip to content

Commit ddcd57e

Browse files
authored
[3.9] bpo-42214: Fix check for NOTEQUAL token in the PEG parser for the barry_as_flufl rule (GH-23048) (GH-23051)
(cherry picked from commit 06f8c33) Co-authored-by: Pablo Galindo <[email protected]>
1 parent 09c6120 commit ddcd57e

File tree

6 files changed

+23
-5
lines changed

6 files changed

+23
-5
lines changed

Grammar/python.gram

+1-1
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ compare_op_bitwise_or_pair[CmpopExprPair*]:
413413
| is_bitwise_or
414414
eq_bitwise_or[CmpopExprPair*]: '==' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, Eq, a) }
415415
noteq_bitwise_or[CmpopExprPair*]:
416-
| (tok='!=' {_PyPegen_check_barry_as_flufl(p) ? NULL : tok}) a=bitwise_or {_PyPegen_cmpop_expr_pair(p, NotEq, a) }
416+
| (tok='!=' { _PyPegen_check_barry_as_flufl(p, tok) ? NULL : tok}) a=bitwise_or {_PyPegen_cmpop_expr_pair(p, NotEq, a) }
417417
lte_bitwise_or[CmpopExprPair*]: '<=' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, LtE, a) }
418418
lt_bitwise_or[CmpopExprPair*]: '<' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, Lt, a) }
419419
gte_bitwise_or[CmpopExprPair*]: '>=' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, GtE, a) }

Lib/test/test_syntax.py

+17
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,23 @@ def test_empty_line_after_linecont(self):
947947
self.fail("Empty line after a line continuation character is valid.")
948948

949949

950+
def test_barry_as_flufl_with_syntax_errors(self):
951+
# The "barry_as_flufl" rule can produce some "bugs-at-a-distance" if
952+
# is reading the wrong token in the presence of syntax errors later
953+
# in the file. See bpo-42214 for more information.
954+
code = """
955+
def func1():
956+
if a != b:
957+
raise ValueError
958+
959+
def func2():
960+
try
961+
return 1
962+
finally:
963+
pass
964+
"""
965+
self._check_error(code, "invalid syntax")
966+
950967
def test_main():
951968
support.run_unittest(SyntaxTestCase)
952969
from test import test_syntax
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed a possible crash in the PEG parser when checking for the '!=' token in
2+
the ``barry_as_flufl`` rule. Patch by Pablo Galindo.

Parser/pegen/parse.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -21307,7 +21307,7 @@ _tmp_93_rule(Parser *p)
2130721307
)
2130821308
{
2130921309
D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!='"));
21310-
_res = _PyPegen_check_barry_as_flufl ( p ) ? NULL : tok;
21310+
_res = _PyPegen_check_barry_as_flufl ( p , tok ) ? NULL : tok;
2131121311
if (_res == NULL && PyErr_Occurred()) {
2131221312
p->error_indicator = 1;
2131321313
D(p->level--);

Parser/pegen/pegen.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ init_normalization(Parser *p)
6262
/* Checks if the NOTEQUAL token is valid given the current parser flags
6363
0 indicates success and nonzero indicates failure (an exception may be set) */
6464
int
65-
_PyPegen_check_barry_as_flufl(Parser *p) {
66-
Token *t = p->tokens[p->fill - 1];
65+
_PyPegen_check_barry_as_flufl(Parser *p, Token* t) {
6766
assert(t->bytes != NULL);
6867
assert(t->type == NOTEQUAL);
6968

Parser/pegen/pegen.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ expr_ty _PyPegen_collect_call_seqs(Parser *, asdl_seq *, asdl_seq *,
263263
int end_col_offset, PyArena *arena);
264264
expr_ty _PyPegen_concatenate_strings(Parser *p, asdl_seq *);
265265
asdl_seq *_PyPegen_join_sequences(Parser *, asdl_seq *, asdl_seq *);
266-
int _PyPegen_check_barry_as_flufl(Parser *);
266+
int _PyPegen_check_barry_as_flufl(Parser *, Token *);
267267
mod_ty _PyPegen_make_module(Parser *, asdl_seq *);
268268

269269
// Error reporting helpers

0 commit comments

Comments
 (0)