fix -F vs. -t

Eric Blake <[email protected]>
Newsgroups gmane.comp.gnu.m4.patches
Message-ID <[email protected]>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This core dump has been there for YEARS - basically, since -F was
introduced in 1994.  It finally bit today:
http://lists.gnu.org/archive/html/libtool-patches/2007-10/msg00022.html

Applying this to the branch, and a similar patch to head.

2007-10-17  Eric Blake  <[email protected]>

	Fix 'm4 -F file -t undefined'.
	* src/freeze.c (produce_frozen_state): Avoid core dump.
	* doc/m4.texinfo (Using frozen files): Test for the bug.
	* NEWS: Mention the fix.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             [email protected]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFHFrus84KuGfSFAYARAk3CAJ9xfeMgjJrZqxc6Sh0kd7U6M2FlqQCfYQ0o
o4R4ACB1PR7SgPE4M+lBW0M=
=pMQl
-----END PGP SIGNATURE-----

_______________________________________________
M4-patches mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/m4-patches
m4.patch287 (text/plain, 9.5 KB)
From 75160ba9c925c305a41b9002533e0c8013fe15ed Mon Sep 17 00:00:00 2001
From: Eric Blake <[email protected]>
Date: Wed, 17 Oct 2007 19:44:13 -0600
Subject: [PATCH] Fix 'm4 -F file -t undefined'.

* src/freeze.c (produce_frozen_state): Avoid core dump.
* doc/m4.texinfo (Using frozen files): Test for the bug.

Signed-off-by: Eric Blake <[email protected]>
---
 ChangeLog      |    7 ++
 NEWS           |    2 +
 doc/m4.texinfo |   10 +++
 src/freeze.c   |  192 ++++++++++++++++++++++++++++---------------------------
 4 files changed, 117 insertions(+), 94 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9e334f1..2e4a12b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2007-10-17  Eric Blake  <[email protected]>
+
+	Fix 'm4 -F file -t undefined'.
+	* src/freeze.c (produce_frozen_state): Avoid core dump.
+	* doc/m4.texinfo (Using frozen files): Test for the bug.
+	* NEWS: Mention the fix.
+
 2007-10-09  Eric Blake  <[email protected]>
 
 	* NEWS: Document recent speedups.
diff --git a/NEWS b/NEWS
index af9b7ae..66e16c3 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,8 @@ Foundation, Inc.
 
 Version 1.4.11 - ?? ??? 2007, by ????  (CVS version 1.4.10a)
 
+* Fix core dump in 'm4 -F file -t undefined', present since -F was
+  introduced in 1.3.
 * Fix regression introduced in 1.4.9b in the `divert' builtin when more
   than 512 kibibytes are saved in diversions on platforms like NetBSD
   where fopen(name,"a+") seeks to the end of the file.
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index 64e37ba..3bece3a 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -6029,6 +6029,16 @@ are handled correctly, as well as undefined or renamed builtins, and
 changed strings for quotes or comments.  And future releases of
 @acronym{GNU} M4 will improve on the utility of frozen files.
 
+@ignore
+@c This example is not worth putting in the manual, but caused core
+@c dumps in all versions prior to 1.4.11.
+
+@comment options: -F /dev/null
+@example
+traceon(`undefined')dnl
+@end example
+@end ignore
+
 When an @code{m4} run is to be frozen, the automatic undiversion
 which takes place at end of execution is inhibited.  Instead, all
 positively numbered diversions are saved into the frozen file.
diff --git a/src/freeze.c b/src/freeze.c
index fb4e93d..89a4c35 100644
--- a/src/freeze.c
+++ b/src/freeze.c
@@ -127,6 +127,10 @@ INTERNAL ERROR: builtin not found in builtin table!"));
 	      fputc ('\n', file);
 	      break;
 
+	    case TOKEN_VOID:
+	      /* Ignore placeholder tokens that exist due to traceon.  */
+	      break;
+
 	    default:
 	      M4ERROR ((warning_status, 0, "\
 INTERNAL ERROR: bad token data type in freeze_one_symbol ()"));
@@ -210,15 +214,15 @@ reload_frozen_state (const char *name)
      character to the next directive or to EOF.  */
 
 #define GET_DIRECTIVE \
-  do                                                            \
-    {                                                           \
-      GET_CHARACTER;                                            \
-      if (character == '#')                                     \
-        {                                                       \
-          while (character != EOF && character != '\n')         \
-            GET_CHARACTER;                                      \
-          VALIDATE ('\n');                                      \
-        }                                                       \
+  do								\
+    {								\
+      GET_CHARACTER;						\
+      if (character == '#')					\
+	{							\
+	  while (character != EOF && character != '\n')		\
+	    GET_CHARACTER;					\
+	  VALIDATE ('\n');					\
+	}							\
     }                                                           \
   while (character == '\n')
 
@@ -238,131 +242,131 @@ reload_frozen_state (const char *name)
   GET_NUMBER (number[0]);
   if (number[0] > 1)
     M4ERROR ((EXIT_MISMATCH, 0,
-              "frozen file version %d greater than max supported of 1",
+	      "frozen file version %d greater than max supported of 1",
 	      number[0]));
   else if (number[0] < 1)
     M4ERROR ((EXIT_FAILURE, 0,
-              "ill-formed frozen file, version directive expected"));
+	      "ill-formed frozen file, version directive expected"));
   VALIDATE ('\n');
 
   GET_DIRECTIVE;
   while (character != EOF)
     {
       switch (character)
-        {
-        default:
-          M4ERROR ((EXIT_FAILURE, 0, "ill-formed frozen file"));
-
-        case 'C':
-        case 'D':
-        case 'F':
-        case 'T':
-        case 'Q':
-          operation = character;
-          GET_CHARACTER;
+	{
+	default:
+	  M4ERROR ((EXIT_FAILURE, 0, "ill-formed frozen file"));
 
-          /* Get string lengths.  Accept a negative diversion number.  */
+	case 'C':
+	case 'D':
+	case 'F':
+	case 'T':
+	case 'Q':
+	  operation = character;
+	  GET_CHARACTER;
 
-          if (operation == 'D' && character == '-')
-            {
-              GET_CHARACTER;
-              GET_NUMBER (number[0]);
-              number[0] = -number[0];
-            }
-          else
-            GET_NUMBER (number[0]);
-          VALIDATE (',');
-          GET_CHARACTER;
-          GET_NUMBER (number[1]);
-          VALIDATE ('\n');
+	  /* Get string lengths.  Accept a negative diversion number.  */
 
-          if (operation != 'D')
-            {
+	  if (operation == 'D' && character == '-')
+	    {
+	      GET_CHARACTER;
+	      GET_NUMBER (number[0]);
+	      number[0] = -number[0];
+	    }
+	  else
+	    GET_NUMBER (number[0]);
+	  VALIDATE (',');
+	  GET_CHARACTER;
+	  GET_NUMBER (number[1]);
+	  VALIDATE ('\n');
+
+	  if (operation != 'D')
+	    {
 
-              /* Get first string contents.  */
+	      /* Get first string contents.  */
 
-              if (number[0] + 1 > allocated[0])
-                {
-                  free (string[0]);
-                  allocated[0] = number[0] + 1;
-                  string[0] = xcharalloc ((size_t) allocated[0]);
-                }
+	      if (number[0] + 1 > allocated[0])
+		{
+		  free (string[0]);
+		  allocated[0] = number[0] + 1;
+		  string[0] = xcharalloc ((size_t) allocated[0]);
+		}
 
-              if (number[0] > 0)
-                if (!fread (string[0], (size_t) number[0], 1, file))
-                  M4ERROR ((EXIT_FAILURE, 0, "premature end of frozen file"));
+	      if (number[0] > 0)
+		if (!fread (string[0], (size_t) number[0], 1, file))
+		  M4ERROR ((EXIT_FAILURE, 0, "premature end of frozen file"));
 
-              string[0][number[0]] = '\0';
-            }
+	      string[0][number[0]] = '\0';
+	    }
 
-          /* Get second string contents.  */
+	  /* Get second string contents.  */
 
-          if (number[1] + 1 > allocated[1])
-            {
-              free (string[1]);
-              allocated[1] = number[1] + 1;
-              string[1] = xcharalloc ((size_t) allocated[1]);
-            }
+	  if (number[1] + 1 > allocated[1])
+	    {
+	      free (string[1]);
+	      allocated[1] = number[1] + 1;
+	      string[1] = xcharalloc ((size_t) allocated[1]);
+	    }
 
-          if (number[1] > 0)
-            if (!fread (string[1], (size_t) number[1], 1, file))
-              M4ERROR ((EXIT_FAILURE, 0, "premature end of frozen file"));
+	  if (number[1] > 0)
+	    if (!fread (string[1], (size_t) number[1], 1, file))
+	      M4ERROR ((EXIT_FAILURE, 0, "premature end of frozen file"));
 
-          string[1][number[1]] = '\0';
-          GET_CHARACTER;
-          VALIDATE ('\n');
+	  string[1][number[1]] = '\0';
+	  GET_CHARACTER;
+	  VALIDATE ('\n');
 
-          /* Act according to operation letter.  */
+	  /* Act according to operation letter.  */
 
-          switch (operation)
-            {
-            case 'C':
+	  switch (operation)
+	    {
+	    case 'C':
 
-              /* Change comment strings.  */
+	      /* Change comment strings.  */
 
-              set_comment (string[0], string[1]);
-              break;
+	      set_comment (string[0], string[1]);
+	      break;
 
-            case 'D':
+	    case 'D':
 
-              /* Select a diversion and add a string to it.  */
+	      /* Select a diversion and add a string to it.  */
 
-              make_diversion (number[0]);
-              if (number[1] > 0)
-                output_text (string[1], number[1]);
-              break;
+	      make_diversion (number[0]);
+	      if (number[1] > 0)
+		output_text (string[1], number[1]);
+	      break;
 
-            case 'F':
+	    case 'F':
 
-              /* Enter a macro having a builtin function as a definition.  */
+	      /* Enter a macro having a builtin function as a definition.  */
 
-              bp = find_builtin_by_name (string[1]);
-              define_builtin (string[0], bp, SYMBOL_PUSHDEF);
-              break;
+	      bp = find_builtin_by_name (string[1]);
+	      define_builtin (string[0], bp, SYMBOL_PUSHDEF);
+	      break;
 
-            case 'T':
+	    case 'T':
 
-              /* Enter a macro having an expansion text as a definition.  */
+	      /* Enter a macro having an expansion text as a definition.  */
 
-              define_user_macro (string[0], string[1], SYMBOL_PUSHDEF);
-              break;
+	      define_user_macro (string[0], string[1], SYMBOL_PUSHDEF);
+	      break;
 
-            case 'Q':
+	    case 'Q':
 
-              /* Change quote strings.  */
+	      /* Change quote strings.  */
 
-              set_quotes (string[0], string[1]);
-              break;
+	      set_quotes (string[0], string[1]);
+	      break;
 
-            default:
+	    default:
 
-              /* Cannot happen.  */
+	      /* Cannot happen.  */
 
-              break;
-            }
-          break;
+	      break;
+	    }
+	  break;
 
-        }
+	}
       GET_DIRECTIVE;
     }
 
-- 
1.5.3.2
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.