]> git.ipfire.org Git - thirdparty/make.git/commitdiff
Ensure variable_buffer is always nul-terminated
authorPaul Smith <psmith@gnu.org>
Sun, 26 Mar 2023 13:24:06 +0000 (09:24 -0400)
committerPaul Smith <psmith@gnu.org>
Sun, 26 Mar 2023 13:24:06 +0000 (09:24 -0400)
* src/expand.c (variable_buffer_output): Allocate an extra byte and
set it to nul.  For safety, add assert() on PTR.
(variable_expand_string): Don't call variable_buffer_output just to
add a nul byte.
(allocated_variable_append): Ditto.

src/expand.c
src/function.c
src/variable.c

index c7233e8ce82fbb7e1ab966a282e5dc75493852e9..d9d903fbee49f1cfbee2851676a22416e342ef8d 100644 (file)
@@ -46,29 +46,33 @@ const floc **expanding_var = &reading_file;
 static size_t variable_buffer_length;
 char *variable_buffer;
 
-/* Subroutine of variable_expand and friends:
-   The text to add is LENGTH chars starting at STRING to the variable_buffer.
-   The text is added to the buffer at PTR, and the updated pointer into
-   the buffer is returned as the value.  Thus, the value returned by
-   each call to variable_buffer_output should be the first argument to
-   the following call.  */
+/* Append LENGTH chars of STRING at PTR which must point into variable_buffer.
+   The buffer will always be kept nul-terminated.
+   The updated pointer into the buffer is returned as the value.  Thus, the
+   value returned by each call to variable_buffer_output should be the first
+   argument to the following call.  */
 
 char *
 variable_buffer_output (char *ptr, const char *string, size_t length)
 {
   size_t newlen = length + (ptr - variable_buffer);
 
-  if ((newlen + VARIABLE_BUFFER_ZONE) > variable_buffer_length)
+  assert (ptr >= variable_buffer);
+  assert (ptr < variable_buffer + variable_buffer_length);
+
+  if (newlen + VARIABLE_BUFFER_ZONE + 1 > variable_buffer_length)
     {
       size_t offset = ptr - variable_buffer;
       variable_buffer_length = (newlen + 100 > 2 * variable_buffer_length
                                 ? newlen + 100
                                 : 2 * variable_buffer_length);
-      variable_buffer = xrealloc (variable_buffer, variable_buffer_length);
+      variable_buffer = xrealloc (variable_buffer, variable_buffer_length + 1);
       ptr = variable_buffer + offset;
     }
 
-  return mempcpy (ptr, string, length);
+  ptr = mempcpy (ptr, string, length);
+  *ptr = '\0';
+  return ptr;
 }
 
 /* Return a pointer to the beginning of the variable buffer.
@@ -83,9 +87,10 @@ initialize_variable_output ()
     {
       variable_buffer_length = 200;
       variable_buffer = xmalloc (variable_buffer_length);
-      variable_buffer[0] = '\0';
     }
 
+  variable_buffer[0] = '\0';
+
   return variable_buffer;
 }
 \f
@@ -229,10 +234,7 @@ variable_expand_string (char *line, const char *string, size_t length)
   line_offset = line - variable_buffer;
 
   if (length == 0)
-    {
-      variable_buffer_output (o, "", 1);
-      return variable_buffer;
-    }
+    return variable_buffer;
 
   /* We need a copy of STRING: due to eval, it's possible that it will get
      freed as we process it (it might be the value of a variable that's reset
@@ -426,7 +428,6 @@ variable_expand_string (char *line, const char *string, size_t length)
 
   free (save);
 
-  variable_buffer_output (o, "", 1);
   return (variable_buffer + line_offset);
 }
 \f
@@ -563,9 +564,8 @@ allocated_variable_append (const struct variable *v)
 
   variable_buffer = 0;
 
-  val = variable_append (v->name, strlen (v->name),
-                         current_variable_set_list, 1);
-  variable_buffer_output (val, "", 1);
+  variable_append (v->name, strlen (v->name), current_variable_set_list, 1);
+
   val = variable_buffer;
 
   variable_buffer = obuf;
@@ -604,7 +604,7 @@ install_variable_buffer (char **bufp, size_t *lenp)
   *bufp = variable_buffer;
   *lenp = variable_buffer_length;
 
-  variable_buffer = 0;
+  variable_buffer = NULL;
   initialize_variable_output ();
 }
 
index 8b966484977fbc90f0cccfe38592af6c7b9a4911..62b13f52dbf00959debe6d285197637aa7294085 100644 (file)
@@ -2011,7 +2011,8 @@ static char *
 func_eq (char *o, char **argv, char *funcname UNUSED)
 {
   int result = ! strcmp (argv[0], argv[1]);
-  o = variable_buffer_output (o,  result ? "1" : "", result);
+  if (result)
+    o = variable_buffer_output (o,  "1", 1);
   return o;
 }
 
@@ -2026,7 +2027,8 @@ func_not (char *o, char **argv, char *funcname UNUSED)
   int result = 0;
   NEXT_TOKEN (s);
   result = ! (*s);
-  o = variable_buffer_output (o,  result ? "1" : "", result);
+  if (result)
+    o = variable_buffer_output (o,  "1", 1);
   return o;
 }
 #endif
index cfb7dc03ef55d96361af0ab88be94eab9d4f58e9..acb3bcbb3dda819782e9113a5647f5d844690df6 100644 (file)
@@ -1278,7 +1278,7 @@ shell_result (const char *p)
 
   args[0] = (char *) p;
   args[1] = NULL;
-  variable_buffer_output (func_shell_base (variable_buffer, args, 0), "\0", 1);
+  func_shell_base (variable_buffer, args, 0);
   result = strdup (variable_buffer);
 
   restore_variable_buffer (buf, len);