Skip to content

Commit bf26a6d

Browse files
bpo-45738: Fix computation of error location for invalid continuation (GH-29550)
characters in the parser (cherry picked from commit 25835c5) Co-authored-by: Pablo Galindo Salgado <[email protected]>
1 parent 28326ac commit bf26a6d

File tree

4 files changed

+14
-12
lines changed

4 files changed

+14
-12
lines changed

Lib/test/test_syntax.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -1487,7 +1487,13 @@ def func2():
14871487
def test_invalid_line_continuation_error_position(self):
14881488
self._check_error(r"a = 3 \ 4",
14891489
"unexpected character after line continuation character",
1490-
lineno=1, offset=9)
1490+
lineno=1, offset=8)
1491+
self._check_error('1,\\#\n2',
1492+
"unexpected character after line continuation character",
1493+
lineno=1, offset=4)
1494+
self._check_error('\nfgdfgf\n1,\\#\n2\n',
1495+
"unexpected character after line continuation character",
1496+
lineno=3, offset=4)
14911497

14921498
def test_invalid_line_continuation_left_recursive(self):
14931499
# Check bpo-42218: SyntaxErrors following left-recursive rules
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix computation of error location for invalid continuation characters in the
2+
parser. Patch by Pablo Galindo.

Parser/pegen.c

+5-10
Original file line numberDiff line numberDiff line change
@@ -372,22 +372,17 @@ tokenizer_error(Parser *p)
372372
msg = "too many levels of indentation";
373373
break;
374374
case E_LINECONT: {
375-
char* loc = strrchr(p->tok->buf, '\n');
376-
const char* last_char = p->tok->cur - 1;
377-
if (loc != NULL && loc != last_char) {
378-
col_offset = p->tok->cur - loc - 1;
379-
p->tok->buf = loc;
380-
} else {
381-
col_offset = last_char - p->tok->buf - 1;
382-
}
375+
col_offset = p->tok->cur - p->tok->buf - 1;
383376
msg = "unexpected character after line continuation character";
384377
break;
385378
}
386379
default:
387380
msg = "unknown parsing error";
388381
}
389382

390-
RAISE_ERROR_KNOWN_LOCATION(p, errtype, p->tok->lineno, col_offset, p->tok->lineno, -1, msg);
383+
RAISE_ERROR_KNOWN_LOCATION(p, errtype, p->tok->lineno,
384+
col_offset >= 0 ? col_offset : 0,
385+
p->tok->lineno, -1, msg);
391386
return -1;
392387
}
393388

@@ -497,7 +492,7 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype,
497492
does not physically exist */
498493
assert(p->tok->fp == NULL || p->tok->fp == stdin || p->tok->done == E_EOF || !uses_utf8_codec);
499494

500-
if (p->tok->lineno <= lineno) {
495+
if (p->tok->lineno <= lineno && p->tok->inp > p->tok->buf) {
501496
Py_ssize_t size = p->tok->inp - p->tok->buf;
502497
error_line = PyUnicode_DecodeUTF8(p->tok->buf, size, "replace");
503498
}

Parser/tokenizer.c

-1
Original file line numberDiff line numberDiff line change
@@ -1969,7 +1969,6 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end)
19691969
c = tok_nextc(tok);
19701970
if (c != '\n') {
19711971
tok->done = E_LINECONT;
1972-
tok->cur = tok->inp;
19731972
return ERRORTOKEN;
19741973
}
19751974
c = tok_nextc(tok);

0 commit comments

Comments
 (0)