https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92382

            Bug ID: 92382
           Summary: variable double-definition in routine
                    replace_filename_variables of
                    libgcc/libgcov-driver-system.c
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: gcov-profile
          Assignee: unassigned at gcc dot gnu.org
          Reporter: qinzhao at gcc dot gnu.org
                CC: marxin at gcc dot gnu.org
  Target Milestone: ---

In the routine replace_filename_variables of libgcc/libgcov-driver-system.c:

145 static char *
146 replace_filename_variables (char *filename)
147 {
148   char buffer[16];
149   char empty[] = "";
150   for (char *p = filename; *p != '\0'; p++)
151     {
152       unsigned length = strlen (filename);
153       if (*p == '%' && *(p + 1) != '\0')
154         {
155           unsigned start = p - filename;
156           p++;
157           char *replacement = NULL;
158           switch (*p)
159             {
160             case 'p':
161               sprintf (buffer, "%d", getpid ());
162               replacement = buffer;
163               p++;
164               break;
165             case 'q':
166               if (*(p + 1) == '{')
167                 {
168                   p += 2;
169                   char *e = strchr (p, '}');
170                   if (e)
171                     {
172                       *e = '\0';
173                       replacement = getenv (p);
174                       if (replacement == NULL)
175                         replacement = empty;
176                       p = e + 1;
177                     }
178                   else
179                     return filename;
180                 }
181               break;
182             default:
183               return filename;
184             }
185 
186           /* Concat beginning of the path, replacement and
187              ending of the path.  */
188           unsigned end = length - (p - filename);
189           unsigned repl_length = replacement != NULL ? strlen (replacement)
: 0;
190 
191           char *buffer = (char *)xmalloc (start + end + repl_length + 1);
192           char *buffer_ptr = buffer;
193           buffer_ptr = (char *)memcpy (buffer_ptr, filename, start);
194           buffer_ptr += start;
195           if (replacement != NULL)
196             buffer_ptr = (char *)memcpy (buffer_ptr, replacement,
repl_length);
197           buffer_ptr += repl_length;
198           buffer_ptr = (char *)memcpy (buffer_ptr, p, end);
199           buffer_ptr += end;
200           *buffer_ptr = '\0';
201 
202           free (filename);
203           filename = buffer;
204           p = buffer + start + repl_length;
205         }
206     }
207 
208   return filename;
209 }

The major issue in the above code is:  the "buffer" is redefined: 

At line 148, "buffer" is defined outside the loop, the intend usage of this 
"buffer" is at line 161 and 162 to hold the process id string for the 
replacement of "%p"; 

However, At line 191, inside this same loop, "buffer" is defined again and 
initialized to hold the new name of the whole filename, and the lifetime of 
this "buffer" will overwrite the other "buffer" defined outside of the loop.   

the fix to this problem is to rename the second "buffer" of line 183 to 
another different name.

Reply via email to