m4-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

fix -F vs. -t


From: Eric Blake
Subject: fix -F vs. -t
Date: Wed, 17 Oct 2007 19:49:33 -0600
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070728 Thunderbird/2.0.0.6 Mnenhy/0.7.5.666

-----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  <address@hidden>

        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             address@hidden
-----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-----
>From 75160ba9c925c305a41b9002533e0c8013fe15ed Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
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 <address@hidden>
---
 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  <address@hidden>
+
+       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  <address@hidden>
 
        * 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.
 
address@hidden
address@hidden This example is not worth putting in the manual, but caused core
address@hidden dumps in all versions prior to 1.4.11.
+
address@hidden options: -F /dev/null
address@hidden
+traceon(`undefined')dnl
address@hidden example
address@hidden 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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]