Fix possibly-unitialized warning in string_parser.c. (GH-21503)

GCC says
```
../cpython/Parser/string_parser.c: In function ‘fstring_find_expr’:
../cpython/Parser/string_parser.c:404:93: warning: ‘cols’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  404 |     p2->starting_col_offset = p->tok->first_lineno == p->tok->lineno ? t->col_offset + cols : cols;
      |                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
../cpython/Parser/string_parser.c:384:16: note: ‘cols’ was declared here
  384 |     int lines, cols;
      |                ^~~~
../cpython/Parser/string_parser.c:403:45: warning: ‘lines’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  403 |     p2->starting_lineno = t->lineno + lines - 1;
      |                           ~~~~~~~~~~~~~~~~~~^~~
../cpython/Parser/string_parser.c:384:9: note: ‘lines’ was declared here
  384 |     int lines, cols;
      |         ^~~~~
```

and, indeed, if `PyBytes_AsString` somehow fails, lines & cols will not be initialized.
This commit is contained in:
Benjamin Peterson 2020-07-16 06:07:29 -07:00 committed by GitHub
parent 5e5c0f9866
commit 2ad7e9c011
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 16 additions and 15 deletions

View File

@ -1,3 +1,5 @@
#include <stdbool.h>
#include <Python.h> #include <Python.h>
#include "tokenizer.h" #include "tokenizer.h"
@ -277,26 +279,23 @@ _PyPegen_parsestr(Parser *p, int *bytesmode, int *rawmode, PyObject **result,
`n` is the node which locations are going to be fixed relative to parent. `n` is the node which locations are going to be fixed relative to parent.
`expr_str` is the child node's string representation, including braces. `expr_str` is the child node's string representation, including braces.
*/ */
static void static bool
fstring_find_expr_location(Token *parent, char *expr_str, int *p_lines, int *p_cols) fstring_find_expr_location(Token *parent, char *expr_str, int *p_lines, int *p_cols)
{ {
char *substr = NULL; *p_lines = 0;
char *start; *p_cols = 0;
int lines = 0;
int cols = 0;
if (parent && parent->bytes) { if (parent && parent->bytes) {
char *parent_str = PyBytes_AsString(parent->bytes); char *parent_str = PyBytes_AsString(parent->bytes);
if (!parent_str) { if (!parent_str) {
return; return false;
} }
substr = strstr(parent_str, expr_str); char *substr = strstr(parent_str, expr_str);
if (substr) { if (substr) {
// The following is needed, in order to correctly shift the column // The following is needed, in order to correctly shift the column
// offset, in the case that (disregarding any whitespace) a newline // offset, in the case that (disregarding any whitespace) a newline
// immediately follows the opening curly brace of the fstring expression. // immediately follows the opening curly brace of the fstring expression.
int newline_after_brace = 1; bool newline_after_brace = 1;
start = substr + 1; char *start = substr + 1;
while (start && *start != '}' && *start != '\n') { while (start && *start != '}' && *start != '\n') {
if (*start != ' ' && *start != '\t' && *start != '\f') { if (*start != ' ' && *start != '\t' && *start != '\f') {
newline_after_brace = 0; newline_after_brace = 0;
@ -312,19 +311,18 @@ fstring_find_expr_location(Token *parent, char *expr_str, int *p_lines, int *p_c
while (start > parent_str && *start != '\n') { while (start > parent_str && *start != '\n') {
start--; start--;
} }
cols += (int)(substr - start); *p_cols += (int)(substr - start);
} }
/* adjust the start based on the number of newlines encountered /* adjust the start based on the number of newlines encountered
before the f-string expression */ before the f-string expression */
for (char* p = parent_str; p < substr; p++) { for (char* p = parent_str; p < substr; p++) {
if (*p == '\n') { if (*p == '\n') {
lines++; (*p_lines)++;
} }
} }
} }
} }
*p_lines = lines; return true;
*p_cols = cols;
} }
@ -382,7 +380,10 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end,
str[len+2] = 0; str[len+2] = 0;
int lines, cols; int lines, cols;
fstring_find_expr_location(t, str, &lines, &cols); if (!fstring_find_expr_location(t, str, &lines, &cols)) {
PyMem_FREE(str);
return NULL;
}
// The parentheses are needed in order to allow for leading whitespace withing // The parentheses are needed in order to allow for leading whitespace withing
// the f-string expression. This consequently gets parsed as a group (see the // the f-string expression. This consequently gets parsed as a group (see the