Skip to content

Commit

Permalink
gh-94360: Fix a tokenizer crash when reading encoded files with synta…
Browse files Browse the repository at this point in the history
…x errors from stdin (#94386)

* gh-94360: Fix a tokenizer crash when reading encoded files with syntax errors from stdin

Signed-off-by: Pablo Galindo <[email protected]>

* nitty nit

Co-authored-by: Łukasz Langa <[email protected]>
  • Loading branch information
pablogsal and ambv authored Jul 5, 2022
1 parent c8556bc commit 36fcde6
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fixed a tokenizer crash when reading encoded files with syntax errors from
``stdin`` with non utf-8 encoded text. Patch by Pablo Galindo
8 changes: 4 additions & 4 deletions Parser/pegen_errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,15 +259,15 @@ get_error_line_from_tokenizer_buffers(Parser *p, Py_ssize_t lineno)
const char* buf_end = p->tok->fp_interactive ? p->tok->interactive_src_end : p->tok->inp;

for (int i = 0; i < relative_lineno - 1; i++) {
char *new_line = strchr(cur_line, '\n') + 1;
char *new_line = strchr(cur_line, '\n');
// The assert is here for debug builds but the conditional that
// follows is there so in release builds we do not crash at the cost
// to report a potentially wrong line.
assert(new_line != NULL && new_line <= buf_end);
if (new_line == NULL || new_line > buf_end) {
assert(new_line != NULL && new_line + 1 < buf_end);
if (new_line == NULL || new_line + 1 > buf_end) {
break;
}
cur_line = new_line;
cur_line = new_line + 1;
}

char *next_newline;
Expand Down
10 changes: 9 additions & 1 deletion Parser/tokenizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ tok_concatenate_interactive_new_line(struct tok_state *tok, const char *line) {

Py_ssize_t current_size = tok->interactive_src_end - tok->interactive_src_start;
Py_ssize_t line_size = strlen(line);
char last_char = line[line_size > 0 ? line_size - 1 : line_size];
if (last_char != '\n') {
line_size += 1;
}
char* new_str = tok->interactive_src_start;

new_str = PyMem_Realloc(new_str, current_size + line_size + 1);
Expand All @@ -321,7 +325,11 @@ tok_concatenate_interactive_new_line(struct tok_state *tok, const char *line) {
return -1;
}
strcpy(new_str + current_size, line);

if (last_char != '\n') {
/* Last line does not end in \n, fake one */
new_str[current_size + line_size - 1] = '\n';
new_str[current_size + line_size] = '\0';
}
tok->interactive_src_start = new_str;
tok->interactive_src_end = new_str + current_size + line_size;
return 0;
Expand Down

0 comments on commit 36fcde6

Please sign in to comment.