From 2ad7e9c011b7606c5c7307176df07419a0e60134 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 16 Jul 2020 06:07:29 -0700 Subject: [PATCH] Fix possibly-unitialized warning in string_parser.c. (GH-21503) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- Parser/string_parser.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/Parser/string_parser.c b/Parser/string_parser.c index 9f56ce21d0f..627879e8179 100644 --- a/Parser/string_parser.c +++ b/Parser/string_parser.c @@ -1,3 +1,5 @@ +#include + #include #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. `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) { - char *substr = NULL; - char *start; - int lines = 0; - int cols = 0; - + *p_lines = 0; + *p_cols = 0; if (parent && parent->bytes) { char *parent_str = PyBytes_AsString(parent->bytes); if (!parent_str) { - return; + return false; } - substr = strstr(parent_str, expr_str); + char *substr = strstr(parent_str, expr_str); if (substr) { // The following is needed, in order to correctly shift the column // offset, in the case that (disregarding any whitespace) a newline // immediately follows the opening curly brace of the fstring expression. - int newline_after_brace = 1; - start = substr + 1; + bool newline_after_brace = 1; + char *start = substr + 1; while (start && *start != '}' && *start != '\n') { if (*start != ' ' && *start != '\t' && *start != '\f') { 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') { start--; } - cols += (int)(substr - start); + *p_cols += (int)(substr - start); } /* adjust the start based on the number of newlines encountered before the f-string expression */ for (char* p = parent_str; p < substr; p++) { if (*p == '\n') { - lines++; + (*p_lines)++; } } } } - *p_lines = lines; - *p_cols = cols; + return true; } @@ -382,7 +380,10 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end, str[len+2] = 0; 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 f-string expression. This consequently gets parsed as a group (see the