Re: branch-1_4 allocation overflow

Eric Blake <[email protected]>
Newsgroups gmane.comp.gnu.m4.patches
Message-ID <[email protected]>
Eric Blake <ebb9 <at> byu.net> writes:

> 
> Likewise for this, although since -H is a no-op on head, I'm not sure if
> it needs porting:

I double-checked.  hash.c on head is safe; it uses xcalloc to perform its 
growth, which catches overflow (if you haven't already run out of memory due to 
doubling every growth).  But I had a couple of other errors, turned up with a 
warnings compile run.

2006-10-26  Eric Blake  <[email protected]>

	Silence -O2 -Wall -Wwrite-strings warnings.
	* m4/m4private.h (m4_symbol_value): Const-ify text.
	* m4/m4module.h (m4_get_symbol_value_text)
	(m4_get_symbol_value_placeholder, m4_set_symbol_value_text)
	(m4_set_symbol_value_placeholder): Likewise.
	* m4/macro.c (expand_token, expand_argument, expand_macro): Fix
	fallout.
	* m4/symtab.c (m4_symbol_value_delete, m4_symbol_value_copy)
	(m4_get_symbol_value_text, m4_get_symbol_value_placeholder)
	(m4_set_symbol_value_text, m4_set_symbol_value_placeholder):
	Likewise.
	* modules/format.c (format): Likewise.
	* src/main.c (main): Likewise.
	* src/freeze.c (produce_symbol_dump, dump_symbol_CB): Likewise.
	* modules/shadow.c (shadow, test): Likewise.
	* m4/output.c (m4_make_diversion): Don't hold on to empty
	diversions.
	(m4_output_init, make_room_for, m4_undivert_all): Don't type-pun.
	(m4_freeze_diversions): Likewise.  Don't use uninitialized
	variable.

Index: m4/m4module.h
===================================================================
RCS file: /sources/m4/m4/m4/m4module.h,v
retrieving revision 1.97
diff -u -r1.97 m4module.h
--- m4/m4module.h	26 Oct 2006 23:11:41 -0000	1.97
+++ m4/m4module.h	27 Oct 2006 03:59:13 -0000
@@ -256,14 +256,15 @@
 extern bool		m4_is_symbol_value_func   (m4_symbol_value *);
 extern bool		m4_is_symbol_value_placeholder  (m4_symbol_value *);
 extern bool		m4_is_symbol_value_void	  (m4_symbol_value *);
-extern char	       *m4_get_symbol_value_text  (m4_symbol_value *);
+extern const char      *m4_get_symbol_value_text  (m4_symbol_value *);
 extern m4_builtin_func *m4_get_symbol_value_func  (m4_symbol_value *);
-extern char	       *m4_get_symbol_value_placeholder  (m4_symbol_value *);
-extern void		m4_set_symbol_value_text  (m4_symbol_value *, char *);
+extern const char      *m4_get_symbol_value_placeholder  (m4_symbol_value *);
+extern void		m4_set_symbol_value_text  (m4_symbol_value *,
+                                                   const char *);
 extern void		m4_set_symbol_value_func  (m4_symbol_value *,
 						   m4_builtin_func *);
 extern void		m4_set_symbol_value_placeholder  (m4_symbol_value *,
-							  char *);
+							  const char *);
 
 
 
Index: m4/m4private.h
===================================================================
RCS file: /sources/m4/m4/m4/m4private.h,v
retrieving revision 1.67
diff -u -r1.67 m4private.h
--- m4/m4private.h	13 Oct 2006 16:46:47 -0000	1.67
+++ m4/m4private.h	27 Oct 2006 03:59:13 -0000
@@ -180,7 +180,7 @@
 
   m4__symbol_type	type;
   union {
-    char *		text; /* Valid when type is TEXT, PLACEHOLDER.  */
+    const char *	text; /* Valid when type is TEXT, PLACEHOLDER.  */
     m4_builtin_func *	func; /* Valid when type is FUNC.  */
   } u;
 };
@@ -221,7 +221,7 @@
 #  define m4_get_symbol_value_placeholder(V)				\
 					((V)->u.text)
 #  define m4_symbol_value_groks_macro(V) (BIT_TEST ((V)->flags,	
	\
-                                                    VALUE_MACRO_ARGS_BIT))
+						    VALUE_MACRO_ARGS_BIT))
 
 #  define m4_set_symbol_value_text(V, T)				\
 	((V)->type = M4_SYMBOL_TEXT, (V)->u.text = (T))
Index: m4/macro.c
===================================================================
RCS file: /sources/m4/m4/m4/macro.c,v
retrieving revision 1.60
diff -u -r1.60 macro.c
--- m4/macro.c	25 Oct 2006 12:45:45 -0000	1.60
+++ m4/macro.c	27 Oct 2006 03:59:13 -0000
@@ -95,8 +95,8 @@
 	      m4__token_type type, m4_symbol_value *token)
 {
   m4_symbol *symbol;
-  char *text = (m4_is_symbol_value_text (token)
-		? m4_get_symbol_value_text (token) : NULL);
+  const char *text = (m4_is_symbol_value_text (token)
+		      ? m4_get_symbol_value_text (token) : NULL);
 
   switch (type)
     {				/* TOKSW */
@@ -115,7 +115,7 @@
 
     case M4_TOKEN_WORD:
       {
-	unsigned char *textp = text;
+	const unsigned char *textp = text;
 
 	if (m4_has_syntax (M4SYNTAX, *textp, M4_SYNTAX_ESCAPE))
 	  ++textp;
@@ -153,7 +153,7 @@
 {
   m4__token_type type;
   m4_symbol_value token;
-  unsigned char *text;
+  const unsigned char *text;
   int paren_level = 0;
   const char *file = m4_get_current_file (context);
   int line = m4_get_current_line (context);
@@ -237,7 +237,7 @@
 static void
 expand_macro (m4 *context, const char *name, m4_symbol *symbol)
 {
-  char *argc_base;		/* Base of argc_stack on entry.  */
+  char *argc_base = NULL;	/* Base of argc_stack on entry.  */
   unsigned int argc_size;	/* Size of argc_stack on entry.  */
   unsigned int argv_size;	/* Size of argv_stack on entry.  */
   m4_symbol_value **argv;
@@ -293,7 +293,8 @@
 
   argc = ((obstack_object_size (&argv_stack) - argv_size)
 	  / sizeof (m4_symbol_value *));
-  argv = (m4_symbol_value **) (obstack_base (&argv_stack) + argv_size);
+  argv = (m4_symbol_value **) ((char *) obstack_base (&argv_stack)
+			       + argv_size);
   /* Calling collect_arguments invalidated name, but we copied it as
      argv[0].  */
   name = m4_get_symbol_value_text (argv[0]);
Index: m4/output.c
===================================================================
RCS file: /sources/m4/m4/m4/output.c,v
retrieving revision 1.34
diff -u -r1.34 output.c
--- m4/output.c	26 Oct 2006 23:19:12 -0000	1.34
+++ m4/output.c	27 Oct 2006 03:59:13 -0000
@@ -130,12 +130,13 @@
 m4_output_init (m4 *context)
 {
   m4_diversion *diversion = xmalloc (sizeof *diversion);
+  const void *tmp = diversion;
   diversion->u.file = stdout;
   diversion->divnum = 0;
   diversion->size = 0;
   diversion->used = 0;
   diversion_table = gl_list_create (GL_AVLTREE_LIST, equal_diversion_CB, NULL,
-				    false, 1, (const void **) &diversion);
+				    false, 1, &tmp);
 
   diversions = 1;
   m4_set_current_diversion (context, 0);
@@ -238,6 +239,7 @@
       m4_diversion *diversion;
       size_t count;
       gl_list_iterator_t iter;
+      const void *elt;
 
       /* Find out the buffer having most data, in view of flushing it to
 	 disk.  Fake the current buffer as having already received the
@@ -249,12 +251,15 @@
 
       iter = gl_list_iterator_from_to (diversion_table, 1,
 				       gl_list_size (diversion_table));
-      while (gl_list_iterator_next (&iter, (const void **) &diversion, NULL))
-	if (diversion->used > selected_used)
-	  {
-	    selected_diversion = diversion;
-	    selected_used = diversion->used;
-	  }
+      while (gl_list_iterator_next (&iter, &elt, NULL))
+	{
+	  diversion = (m4_diversion *) elt;
+	  if (diversion->used > selected_used)
+	    {
+	      selected_diversion = diversion;
+	      selected_used = diversion->used;
+	    }
+	}
       gl_list_iterator_free (&iter);
 
       /* Create a temporary file, write the in-memory buffer of the
@@ -514,7 +519,15 @@
     {
       assert (!output_file || output_diversion->u.file == output_file);
       assert (output_diversion->divnum != divnum);
-      output_diversion->used = output_diversion->size - output_unused;
+      if (!output_diversion->size && !output_diversion->u.file)
+	{
+	  if (!gl_list_remove (diversion_table, output_diversion))
+	    assert (false);
+	  output_diversion->u.next = free_list;
+	  free_list = output_diversion;
+	}
+      else
+	output_diversion->used = output_diversion->size - output_unused;
       output_diversion = NULL;
       output_file = NULL;
       output_cursor = NULL;
@@ -664,12 +677,16 @@
   gl_list_iterator_t iter;
   gl_list_node_t node;
   int divnum = m4_get_current_diversion (context);
+  const void *elt;
 
   iter = gl_list_iterator_from_to (diversion_table, 1,
 				   gl_list_size (diversion_table));
-  while (gl_list_iterator_next (&iter, (const void **) &diversion, &node))
-    if (diversion->divnum != divnum)
-      m4_insert_diversion_helper (context, diversion, node);
+  while (gl_list_iterator_next (&iter, &elt, &node))
+    {
+      diversion = (m4_diversion *) elt;
+      if (diversion->divnum != divnum)
+	m4_insert_diversion_helper (context, diversion, node);
+    }
   gl_list_iterator_free (&iter);
 }
 
@@ -679,11 +696,11 @@
 {
   int saved_number;
   int last_inserted;
-  int divnum;
   m4_diversion *diversion;
   struct stat file_stat;
   gl_list_iterator_t iter;
   gl_list_node_t node;
+  const void *elt;
 
   saved_number = m4_get_current_diversion (context);
   last_inserted = 0;
@@ -692,14 +709,16 @@
 
   iter = gl_list_iterator_from_to (diversion_table, 1,
 				   gl_list_size (diversion_table));
-  while (gl_list_iterator_next (&iter, (const void **) &diversion, &node))
+  while (gl_list_iterator_next (&iter, &elt, &node))
     {
+      diversion = (m4_diversion *) elt;
       if (diversion->size || diversion->u.file)
 	{
 	  if (diversion->size)
 	    {
 	      assert (diversion->used == (int) diversion->used);
-	      fprintf (file, "D%d,%d\n", divnum, (int) diversion->used);
+	      fprintf (file, "D%d,%d\n", diversion->divnum,
+		       (int) diversion->used);
 	    }
 	  else
 	    {
@@ -714,14 +733,14 @@
 		  || file_stat.st_size != (unsigned long) file_stat.st_size)
 		m4_error (context, EXIT_FAILURE, errno,
 			  _("diversion too large"));
-	      fprintf (file, "D%d,%lu", divnum,
+	      fprintf (file, "D%d,%lu", diversion->divnum,
 		       (unsigned long) file_stat.st_size);
 	    }
 
 	  m4_insert_diversion_helper (context, diversion, node);
 	  putc ('\n', file);
 
-	  last_inserted = divnum;
+	  last_inserted = diversion->divnum;
 	}
     }
   gl_list_iterator_free (&iter);
Index: m4/symtab.c
===================================================================
RCS file: /sources/m4/m4/m4/symtab.c,v
retrieving revision 1.65
diff -u -r1.65 symtab.c
--- m4/symtab.c	16 Oct 2006 22:12:07 -0000	1.65
+++ m4/symtab.c	27 Oct 2006 03:59:13 -0000
@@ -320,9 +320,9 @@
 	  m4_hash_delete (VALUE_ARG_SIGNATURE (value));
 	}
       if (m4_is_symbol_value_text (value))
-	free (m4_get_symbol_value_text (value));
+	free ((char *) m4_get_symbol_value_text (value));
       else if (m4_is_symbol_value_placeholder (value))
-	free (m4_get_symbol_value_placeholder (value));
+	free ((char *) m4_get_symbol_value_placeholder (value));
       free (value);
     }
 }
@@ -386,9 +386,9 @@
   assert (src);
 
   if (m4_is_symbol_value_text (dest))
-    free (m4_get_symbol_value_text (dest));
+    free ((char *) m4_get_symbol_value_text (dest));
   else if (m4_is_symbol_value_placeholder (dest))
-    free (m4_get_symbol_value_placeholder (dest));
+    free ((char *) m4_get_symbol_value_placeholder (dest));
 
   if (VALUE_ARG_SIGNATURE (dest))
     {
@@ -629,7 +629,7 @@
 }
 
 #undef m4_get_symbol_value_text
-char *
+const char *
 m4_get_symbol_value_text (m4_symbol_value *value)
 {
   assert (value && value->type == M4_SYMBOL_TEXT);
@@ -645,7 +645,7 @@
 }
 
 #undef m4_get_symbol_value_placeholder
-char *
+const char *
 m4_get_symbol_value_placeholder (m4_symbol_value *value)
 {
   assert (value && value->type == M4_SYMBOL_PLACEHOLDER);
@@ -654,7 +654,7 @@
 
 #undef m4_set_symbol_value_text
 void
-m4_set_symbol_value_text (m4_symbol_value *value, char *text)
+m4_set_symbol_value_text (m4_symbol_value *value, const char *text)
 {
   assert (value);
   assert (text);
@@ -676,7 +676,7 @@
 
 #undef m4_set_symbol_value_placeholder
 void
-m4_set_symbol_value_placeholder (m4_symbol_value *value, char *text)
+m4_set_symbol_value_placeholder (m4_symbol_value *value, const char *text)
 {
   assert (value);
   assert (text);
Index: modules/format.c
===================================================================
RCS file: /sources/m4/m4/modules/format.c,v
retrieving revision 1.19
diff -u -r1.19 format.c
--- modules/format.c	22 Jul 2006 21:42:13 -0000	1.19
+++ modules/format.c	27 Oct 2006 03:59:13 -0000
@@ -61,6 +61,7 @@
 format (m4_obstack *obs, int argc, m4_symbol_value **argv)
 {
   char *fmt;			/* format control string */
+  char *copy;			/* we temporarily edit fmt */
   const char *fstart;		/* beginning of current format spec */
   int c;			/* a simple character */
 
@@ -77,13 +78,16 @@
   char *str;			/* malloc'd buffer for formatted text */
   enum {INT, UINT, LONG, ULONG, DOUBLE, STR} datatype;
 
-  fmt = ARG_STR (argc, argv);
+  fmt = copy = xstrdup (ARG_STR (argc, argv));
   for (;;)
     {
       while ((c = *fmt++) != '%')
 	{
 	  if (c == '\0')
-	    return;
+	    {
+	      free (copy);
+	      return;
+	    }
 	  obstack_1grow (obs, c);
 	}
 
@@ -164,6 +168,7 @@
 
 	case '\0':
 	  /* TODO - warn about incomplete % specifier.  */
+	  free (copy);
 	  return;
 
 	case 'c':
@@ -216,72 +221,72 @@
       c = *fmt;
       *fmt = '\0';
 
-      switch(datatype)
+      switch (datatype)
 	{
 	case INT:
 	  if (width != -1 && prec != -1)
-	    str = xasprintf (fstart, width, prec, ARG_INT(argc, argv));
+	    str = xasprintf (fstart, width, prec, ARG_INT (argc, argv));
 	  else if (width != -1)
-	    str = xasprintf (fstart, width, ARG_INT(argc, argv));
+	    str = xasprintf (fstart, width, ARG_INT (argc, argv));
 	  else if (prec != -1)
-	    str = xasprintf (fstart, prec, ARG_INT(argc, argv));
+	    str = xasprintf (fstart, prec, ARG_INT (argc, argv));
 	  else
-	    str = xasprintf (fstart, ARG_INT(argc, argv));
+	    str = xasprintf (fstart, ARG_INT (argc, argv));
 	  break;
 
 	case UINT:
 	  if (width != -1 && prec != -1)
-	    str = xasprintf (fstart, width, prec, ARG_UINT(argc, argv));
+	    str = xasprintf (fstart, width, prec, ARG_UINT (argc, argv));
 	  else if (width != -1)
-	    str = xasprintf (fstart, width, ARG_UINT(argc, argv));
+	    str = xasprintf (fstart, width, ARG_UINT (argc, argv));
 	  else if (prec != -1)
-	    str = xasprintf (fstart, prec, ARG_UINT(argc, argv));
+	    str = xasprintf (fstart, prec, ARG_UINT (argc, argv));
 	  else
-	    str = xasprintf (fstart, ARG_UINT(argc, argv));
+	    str = xasprintf (fstart, ARG_UINT (argc, argv));
 	  break;
 
 	case LONG:
 	  if (width != -1 && prec != -1)
-	    str = xasprintf (fstart, width, prec, ARG_LONG(argc, argv));
+	    str = xasprintf (fstart, width, prec, ARG_LONG (argc, argv));
 	  else if (width != -1)
-	    str = xasprintf (fstart, width, ARG_LONG(argc, argv));
+	    str = xasprintf (fstart, width, ARG_LONG (argc, argv));
 	  else if (prec != -1)
-	    str = xasprintf (fstart, prec, ARG_LONG(argc, argv));
+	    str = xasprintf (fstart, prec, ARG_LONG (argc, argv));
 	  else
-	    str = xasprintf (fstart, ARG_LONG(argc, argv));
+	    str = xasprintf (fstart, ARG_LONG (argc, argv));
 	  break;
 
 	case ULONG:
 	  if (width != -1 && prec != -1)
-	    str = xasprintf (fstart, width, prec, ARG_ULONG(argc, argv));
+	    str = xasprintf (fstart, width, prec, ARG_ULONG (argc, argv));
 	  else if (width != -1)
-	    str = xasprintf (fstart, width, ARG_ULONG(argc, argv));
+	    str = xasprintf (fstart, width, ARG_ULONG (argc, argv));
 	  else if (prec != -1)
-	    str = xasprintf (fstart, prec, ARG_ULONG(argc, argv));
+	    str = xasprintf (fstart, prec, ARG_ULONG (argc, argv));
 	  else
-	    str = xasprintf (fstart, ARG_ULONG(argc, argv));
+	    str = xasprintf (fstart, ARG_ULONG (argc, argv));
 	  break;
 
 	case DOUBLE:
 	  if (width != -1 && prec != -1)
-	    str = xasprintf (fstart, width, prec, ARG_DOUBLE(argc, argv));
+	    str = xasprintf (fstart, width, prec, ARG_DOUBLE (argc, argv));
 	  else if (width != -1)
-	    str = xasprintf (fstart, width, ARG_DOUBLE(argc, argv));
+	    str = xasprintf (fstart, width, ARG_DOUBLE (argc, argv));
 	  else if (prec != -1)
-	    str = xasprintf (fstart, prec, ARG_DOUBLE(argc, argv));
+	    str = xasprintf (fstart, prec, ARG_DOUBLE (argc, argv));
 	  else
-	    str = xasprintf (fstart, ARG_DOUBLE(argc, argv));
+	    str = xasprintf (fstart, ARG_DOUBLE (argc, argv));
 	  break;
 
 	case STR:
 	  if (width != -1 && prec != -1)
-	    str = xasprintf (fstart, width, prec, ARG_STR(argc, argv));
+	    str = xasprintf (fstart, width, prec, ARG_STR (argc, argv));
 	  else if (width != -1)
-	    str = xasprintf (fstart, width, ARG_STR(argc, argv));
+	    str = xasprintf (fstart, width, ARG_STR (argc, argv));
 	  else if (prec != -1)
-	    str = xasprintf (fstart, prec, ARG_STR(argc, argv));
+	    str = xasprintf (fstart, prec, ARG_STR (argc, argv));
 	  else
-	    str = xasprintf (fstart, ARG_STR(argc, argv));
+	    str = xasprintf (fstart, ARG_STR (argc, argv));
 	  break;
 
 	default:
@@ -298,4 +303,5 @@
       obstack_grow (obs, str, strlen (str));
       free (str);
     }
+  free (copy);
 }
Index: modules/shadow.c
===================================================================
RCS file: /sources/m4/m4/modules/shadow.c,v
retrieving revision 1.13
diff -u -r1.13 shadow.c
--- modules/shadow.c	26 Sep 2006 13:19:26 -0000	1.13
+++ modules/shadow.c	27 Oct 2006 03:59:13 -0000
@@ -80,7 +80,7 @@
  **/
 M4BUILTIN_HANDLER (shadow)
 {
-  char *s = "Shadow::`shadow' called.";
+  const char *s = "Shadow::`shadow' called.";
   obstack_grow (obs, s, strlen(s));
 }
 
@@ -89,6 +89,6 @@
  **/
 M4BUILTIN_HANDLER (test)
 {
-  char *s = "Shadow::`test' called.";
+  const char *s = "Shadow::`test' called.";
   obstack_grow (obs, s, strlen(s));
 }
Index: src/freeze.c
===================================================================
RCS file: /sources/m4/m4/src/freeze.c,v
retrieving revision 1.52
diff -u -r1.52 freeze.c
--- src/freeze.c	4 Oct 2006 03:57:01 -0000	1.52
+++ src/freeze.c	27 Oct 2006 03:59:13 -0000
@@ -153,9 +153,7 @@
 void
 produce_symbol_dump (m4 *context, FILE *file, m4_symbol_table *symtab)
 {
-  const char *errormsg = m4_symtab_apply (symtab, dump_symbol_CB, file);
-
-  if (errormsg != NULL)
+  if (m4_symtab_apply (symtab, dump_symbol_CB, file))
     assert (false);
 }
 
@@ -188,7 +186,7 @@
 						m4_get_symbol_func (symbol));
 
       if (bp == NULL)
-	return "INTERNAL ERROR: builtin not found in builtin table!";
+	assert (!"INTERNAL ERROR: builtin not found in builtin table!");
 
       fprintf (file, "F%lu,%lu",
 	       (unsigned long) strlen (symbol_name),
@@ -208,7 +206,7 @@
   else if (m4_is_symbol_placeholder (symbol))
     ; /* Nothing to do for a builtin we couldn't reload earlier.  */
   else
-    return "INTERNAL ERROR: bad token data type in produce_symbol_dump ()";
+    assert (!"INTERNAL ERROR: bad token data type in produce_symbol_dump ()");
 
   return NULL;
 }
Index: src/main.c
===================================================================
RCS file: /sources/m4/m4/src/main.c,v
retrieving revision 1.99
diff -u -r1.99 main.c
--- src/main.c	21 Oct 2006 12:49:57 -0000	1.99
+++ src/main.c	27 Oct 2006 03:59:13 -0000
@@ -564,11 +564,10 @@
 	      m4_symbol_value *value = m4_symbol_value_create ();
 
 	      macro_value = strchr (arg, '=');
-	      if (macro_value == NULL)
-		macro_value = "";
-	      else
+	      if (macro_value != NULL)
 		*macro_value++ = '\0';
-	      m4_set_symbol_value_text (value, xstrdup (macro_value));
+	      m4_set_symbol_value_text (value, xstrdup (macro_value
+                                                        ? macro_value : ""));
 
 	      m4_symbol_pushdef (M4SYMTAB, arg, value);
 	    }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.