[Python-checkins] Fix possibly-unitialized warning in string_parser.c. (GH-21503)

Benjamin Peterson webhook-mailer at python.org
Thu Jul 16 09:07:52 EDT 2020


https://github.com/python/cpython/commit/2ad7e9c011b7606c5c7307176df07419a0e60134
commit: 2ad7e9c011b7606c5c7307176df07419a0e60134
branch: master
author: Benjamin Peterson <benjamin at python.org>
committer: GitHub <noreply at github.com>
date: 2020-07-16T08:07:29-05:00
summary:

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.

files:
M Parser/string_parser.c

diff --git a/Parser/string_parser.c b/Parser/string_parser.c
index 9f56ce21d0f20..627879e8179e4 100644
--- a/Parser/string_parser.c
+++ b/Parser/string_parser.c
@@ -1,3 +1,5 @@
+#include <stdbool.h>
+
 #include <Python.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.
    `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



More information about the Python-checkins mailing list