Skip to content

Commit 2ad7e9c

Browse files
authored
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.
1 parent 5e5c0f9 commit 2ad7e9c

File tree

1 file changed

+16
-15
lines changed

1 file changed

+16
-15
lines changed

Parser/string_parser.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include <stdbool.h>
2+
13
#include <Python.h>
24

35
#include "tokenizer.h"
@@ -277,26 +279,23 @@ _PyPegen_parsestr(Parser *p, int *bytesmode, int *rawmode, PyObject **result,
277279
`n` is the node which locations are going to be fixed relative to parent.
278280
`expr_str` is the child node's string representation, including braces.
279281
*/
280-
static void
282+
static bool
281283
fstring_find_expr_location(Token *parent, char *expr_str, int *p_lines, int *p_cols)
282284
{
283-
char *substr = NULL;
284-
char *start;
285-
int lines = 0;
286-
int cols = 0;
287-
285+
*p_lines = 0;
286+
*p_cols = 0;
288287
if (parent && parent->bytes) {
289288
char *parent_str = PyBytes_AsString(parent->bytes);
290289
if (!parent_str) {
291-
return;
290+
return false;
292291
}
293-
substr = strstr(parent_str, expr_str);
292+
char *substr = strstr(parent_str, expr_str);
294293
if (substr) {
295294
// The following is needed, in order to correctly shift the column
296295
// offset, in the case that (disregarding any whitespace) a newline
297296
// immediately follows the opening curly brace of the fstring expression.
298-
int newline_after_brace = 1;
299-
start = substr + 1;
297+
bool newline_after_brace = 1;
298+
char *start = substr + 1;
300299
while (start && *start != '}' && *start != '\n') {
301300
if (*start != ' ' && *start != '\t' && *start != '\f') {
302301
newline_after_brace = 0;
@@ -312,19 +311,18 @@ fstring_find_expr_location(Token *parent, char *expr_str, int *p_lines, int *p_c
312311
while (start > parent_str && *start != '\n') {
313312
start--;
314313
}
315-
cols += (int)(substr - start);
314+
*p_cols += (int)(substr - start);
316315
}
317316
/* adjust the start based on the number of newlines encountered
318317
before the f-string expression */
319318
for (char* p = parent_str; p < substr; p++) {
320319
if (*p == '\n') {
321-
lines++;
320+
(*p_lines)++;
322321
}
323322
}
324323
}
325324
}
326-
*p_lines = lines;
327-
*p_cols = cols;
325+
return true;
328326
}
329327

330328

@@ -382,7 +380,10 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end,
382380
str[len+2] = 0;
383381

384382
int lines, cols;
385-
fstring_find_expr_location(t, str, &lines, &cols);
383+
if (!fstring_find_expr_location(t, str, &lines, &cols)) {
384+
PyMem_FREE(str);
385+
return NULL;
386+
}
386387

387388
// The parentheses are needed in order to allow for leading whitespace withing
388389
// the f-string expression. This consequently gets parsed as a group (see the

0 commit comments

Comments
 (0)