m4-patches
[Top][All Lists]
Advanced

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

Re: fix frozen diversions on master branch


From: Eric Blake
Subject: Re: fix frozen diversions on master branch
Date: Tue, 10 Jun 2008 07:12:37 -0600
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.14) Gecko/20080421 Thunderbird/2.0.0.14 Mnenhy/0.7.5.666

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Eric Blake on 5/13/2008 11:39 AM:
| Jim's recent complaint about not detecting numeric overflow made me realize
| that the master branch has been broken for more than a year when it
comes to
| freezing a diversion that contains a \.  Fixed as follows.

|
| I also realized that because this patch uses the quotearg module, and
quotearg
| does not pad out a trailing NUL as '\000', then without the newline between
| strings, this would be ambiguous (macro '\0' with content '\1', or macro
'\1'
| with content '\n'?) once argv_ref patch 24 allows NUL in macro names:

It turns out that frozen diversions are also subject to this bug - if a
NUL byte fell immediately before the COPY_BUFFER_SIZE block in a diversion
that spilled to a file, and the next byte in the diversion was a digit,
then the frozen file is corrupted (not to mention it has extremely long
lines).  This fixes the corruption by guaranteeing the next character is
not a digit, and also makes line length in frozen files a bit more
manageable.  I couldn't really write a test case without defining a macro
containing a NUL, but that part of the argv_ref branch hasn't been ported
yet, so this is more of a fix by inspection.

I still need to fix reloading to stage the 'D' directive in
COPY_BUFFER_SIZE blocks, rather than trying to read the entire diversion
into memory only to turn around and spill back to a file - that can fail
with an ENOMEM where the original case did not.  And it would be nice to
support off_t in the 'D' size, so that you could freeze a 2 gigabyte
diversion (although that seems quite theoretical, it would be removing an
arbitrary limitation on platforms with 32-bit size_t but 64-bit off_t).

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

Eric Blake             address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkhOfcMACgkQ84KuGfSFAYCNvQCgxjB2dmDy2sFMOEHgWyuy/Udf
Me0An2jgzId73tzgKHgLQMT7daW4RWu0
=oPzR
-----END PGP SIGNATURE-----
>From 33ac212bed1448f8fd9b87f94f4c1c79461f2eaf Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Tue, 10 Jun 2008 07:00:29 -0600
Subject: [PATCH] Avoid corrupted frozen file if NUL appears on block boundary.

* m4/output.c (insert_file): Separate consecutive quotearg blocks
with \<newline>, in case last byte of first block was NUL.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog   |    6 ++++++
 m4/output.c |    9 ++++++++-
 2 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b94b250..b2f0cc4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-06-10  Eric Blake  <address@hidden>
+
+       Avoid corrupted frozen file if NUL appears on block boundary.
+       * m4/output.c (insert_file): Separate consecutive quotearg blocks
+       with \<newline>, in case last byte of first block was NUL.
+
 2008-06-03  Eric Blake  <address@hidden>
 
        Fix printf type mismatches.
diff --git a/m4/output.c b/m4/output.c
index d3c5507..f94cbd2 100644
--- a/m4/output.c
+++ b/m4/output.c
@@ -749,6 +749,7 @@ insert_file (m4 *context, FILE *file, bool escaped)
   char buffer[COPY_BUFFER_SIZE];
   size_t length;
   char *str = buffer;
+  bool first = true;
 
   assert (output_diversion);
   /* Insert output by big chunks.  */
@@ -761,7 +762,13 @@ insert_file (m4 *context, FILE *file, bool escaped)
       if (length == 0)
        break;
       if (escaped)
-       str = quotearg_style_mem (escape_quoting_style, buffer, length);
+       {
+         if (first)
+           first = false;
+         else
+           m4_output_text (context, "\\\n", 2);
+         str = quotearg_style_mem (escape_quoting_style, buffer, length);
+       }
       m4_output_text (context, str, escaped ? strlen (str) : length);
     }
 }
-- 
1.5.5.1


reply via email to

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