Skip to content

Commit d11da8d

Browse files
committed
bpo-42214: Fix check for NOTEQUAL token in the PEG parser for the barry_as_flufl rule
1 parent bca7014 commit d11da8d

File tree

6 files changed

+23
-5
lines changed

6 files changed

+23
-5
lines changed

Grammar/python.gram

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ compare_op_bitwise_or_pair[CmpopExprPair*]:
428428
| is_bitwise_or
429429
eq_bitwise_or[CmpopExprPair*]: '==' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, Eq, a) }
430430
noteq_bitwise_or[CmpopExprPair*]:
431-
| (tok='!=' {_PyPegen_check_barry_as_flufl(p) ? NULL : tok}) a=bitwise_or {_PyPegen_cmpop_expr_pair(p, NotEq, a) }
431+
| (tok='!=' {_PyPegen_check_barry_as_flufl(p, tok) ? NULL : tok}) a=bitwise_or {_PyPegen_cmpop_expr_pair(p, NotEq, a) }
432432
lte_bitwise_or[CmpopExprPair*]: '<=' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, LtE, a) }
433433
lt_bitwise_or[CmpopExprPair*]: '<' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, Lt, a) }
434434
gte_bitwise_or[CmpopExprPair*]: '>=' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, GtE, a) }

Lib/test/test_syntax.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,23 @@ def test_nested_named_except_blocks(self):
952952
code += f"{' '*4*12}pass"
953953
self._check_error(code, "too many statically nested blocks")
954954

955+
def test_barry_as_flufl_with_syntax_errors(self):
956+
# The "barry_as_flufl" rule can produce some "bugs-at-a-distance" if
957+
# is reading the wrong token in the presence of syntax errors later
958+
# in the file. See bpo-42214 for more information.
959+
code = """
960+
def func1():
961+
if a != b:
962+
raise ValueError
963+
964+
def func2():
965+
try
966+
return 1
967+
finally:
968+
pass
969+
"""
970+
self._check_error(code, "invalid syntax")
971+
955972
def test_main():
956973
support.run_unittest(SyntaxTestCase)
957974
from test import test_syntax
Lines changed: 2 additions & 0 deletions
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/parser.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21221,7 +21221,7 @@ _tmp_93_rule(Parser *p)
2122121221
)
2122221222
{
2122321223
D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!='"));
21224-
_res = _PyPegen_check_barry_as_flufl ( p ) ? NULL : tok;
21224+
_res = _PyPegen_check_barry_as_flufl ( p , tok ) ? NULL : tok;
2122521225
if (_res == NULL && PyErr_Occurred()) {
2122621226
p->error_indicator = 1;
2122721227
D(p->level--);

Parser/pegen.c

Lines changed: 1 addition & 2 deletions
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.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ expr_ty _PyPegen_collect_call_seqs(Parser *, asdl_expr_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_stmt_seq *);
268268

269269
// Error reporting helpers

0 commit comments

Comments
 (0)