bug-coreutils
[Top][All Lists]
Advanced

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

[PATCH] mktemp, sort, tac: don't use undefined after mkstemp failure


From: Jim Meyering
Subject: [PATCH] mktemp, sort, tac: don't use undefined after mkstemp failure
Date: Wed, 13 Aug 2008 16:14:34 +0200

Thanks again to both of you for the reports of test failure.
This was a real bug.  And mktemp and tac both had similar problems.
I've fixed it like this:

>From 55416011e0a5b3275024226a6f91dd46389a18b3 Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Wed, 13 Aug 2008 16:01:38 +0200
Subject: [PATCH] mktemp, sort, tac: don't use undefined after mkstemp failure

* src/sort.c (create_temp_file): Use temp_dir, not "file"
when diagnosing failed mkstemp, because "file" may be undefined.
* tests/misc/sort-merge: Adjust for new expected output.
Jeph Cowan and Ralf Wildenhues reported the test failure:
http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/14235/focus=14257
* src/tac.c (copy_to_temp): Don't use template buffer after
failed mkstemp call, since its contents may be undefined.
* tests/misc/tac (pipe-bad-tmpdir): New test for the above.
* src/mktemp.c (main): Save a copy of the template string,
solely for use in case mkstemp fails.
* tests/misc/mktemp (pipe-bad-tmpdir): New test for the above.
---
 THANKS                |    1 +
 src/mktemp.c          |   12 ++++++++----
 src/sort.c            |    2 +-
 src/tac.c             |    3 ++-
 tests/misc/mktemp     |    8 ++++++++
 tests/misc/sort-merge |    4 ++--
 tests/misc/tac        |    9 +++++++++
 7 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/THANKS b/THANKS
index 5f3c5bd..021ff6a 100644
--- a/THANKS
+++ b/THANKS
@@ -250,6 +250,7 @@ Jeff Moore                          address@hidden
 Jeff Sheinberg                      address@hidden
 Jens Elkner                         address@hidden
 Jens Schmidt                        address@hidden
+Jeph Cowan                          address@hidden
 Jeremy Maitin-Shepard               address@hidden
 Jerome Abela                        address@hidden
 Jérôme Zago                         address@hidden
diff --git a/src/mktemp.c b/src/mktemp.c
index 8a09231..d745e60 100644
--- a/src/mktemp.c
+++ b/src/mktemp.c
@@ -242,20 +242,24 @@ main (int argc, char **argv)
                    quote (template));
         }

-      dest_name = file_name_concat (dest_dir, template, NULL);
+      template = file_name_concat (dest_dir, template, NULL);
     }
   else
     {
-      dest_name = xstrdup (template);
+      template = xstrdup (template);
     }

+  /* Make a copy to be used in case of diagnostic, since failing
+     mkstemp may leave the buffer in an undefined state.  */
+  dest_name = xstrdup (template);
+
   if (create_directory)
     {
       int err = mkdtemp_len (dest_name, x_count, dry_run);
       if (err != 0)
         {
           error (0, errno, _("failed to create directory via template %s"),
-                 quote (dest_name));
+                 quote (template));
           status = EXIT_FAILURE;
         }
     }
@@ -265,7 +269,7 @@ main (int argc, char **argv)
       if (fd < 0 || (!dry_run && close (fd) != 0))
         {
           error (0, errno, _("failed to create file via template %s"),
-                 quote (dest_name));
+                 quote (template));
           status = EXIT_FAILURE;
         }
     }
diff --git a/src/sort.c b/src/sort.c
index b932a51..728c935 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -741,7 +741,7 @@ create_temp_file (int *pfd)
   errno = saved_errno;

   if (fd < 0)
-    die (_("cannot create temporary file"), file);
+    die (_("cannot create temporary file in"), temp_dir);

   *pfd = fd;
   return node;
diff --git a/src/tac.c b/src/tac.c
index 9cf6d60..c83986f 100644
--- a/src/tac.c
+++ b/src/tac.c
@@ -454,7 +454,8 @@ copy_to_temp (FILE **g_tmp, char **g_tempfile, int 
input_fd, char const *file)
   fd = mkstemp (template);
   if (fd < 0)
     {
-      error (0, errno, _("cannot create temporary file %s"), quote (tempfile));
+      error (0, errno, _("cannot create temporary file in %s"),
+            quote (tempdir));
       return false;
     }

diff --git a/tests/misc/mktemp b/tests/misc/mktemp
index 616a9e4..269dfb1 100755
--- a/tests/misc/mktemp
+++ b/tests/misc/mktemp
@@ -49,6 +49,7 @@ sub check_tmp($$)
 # Turn off localization of executable's output.
 @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
 my $prog = 'mktemp';
+my $bad_dir = 'no/such/dir';

 my @Tests =
     (
@@ -97,6 +98,13 @@ my @Tests =
       {POST => sub { my ($f) = @_; defined $f or return; chomp $f;
        check_tmp $f, 'F'; unlink $f; rmdir 'a' or die "rmdir a: $!\n" }}
      ],
+
+     ['pipe-bad-tmpdir',
+      {ENV=>"TMPDIR=$bad_dir"},
+      {ERR_SUBST => "s,($bad_dir/)[^']+,\$1...,"},
+      {ERR=>"$prog: failed to create file via template `$bad_dir/...':"
+       . " No such file or directory\n"},
+      {EXIT => 1}],
     );

 my $save_temps = $ENV{DEBUG};
diff --git a/tests/misc/sort-merge b/tests/misc/sort-merge
index 985d7a4..53559bf 100755
--- a/tests/misc/sort-merge
+++ b/tests/misc/sort-merge
@@ -66,8 +66,8 @@ my @Tests =
      # this should fail since nmerge < # of input files, so
      # temp files are needed
      ['nmerge-no', "-m --batch-size=2 -T$badtmp", @inputs,
-        {ERR_SUBST=>"s|: $badtmp/sort.+||"},
-        {ERR=>"$prog: cannot create temporary file\n"}, {EXIT=>2}],
+        {ERR_SUBST=>"s|(: $badtmp):.*|\$1|"},
+        {ERR=>"$prog: cannot create temporary file in: $badtmp\n"}, {EXIT=>2}],

      # This used to fail because setting batch-size without also setting
      # buffer size would cause the buffer size to be set to the minimum.
diff --git a/tests/misc/tac b/tests/misc/tac
index 2f9981d..cd03be0 100755
--- a/tests/misc/tac
+++ b/tests/misc/tac
@@ -22,6 +22,8 @@ my $prog = 'tac';
 # Turn off localization of executable's output.
 @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;

+my $bad_dir = 'no/such/dir';
+
 my @Tests =
 (
   ['segfault', '-r', {IN=>"a\n"}, {IN=>"b\n"}, {OUT=>"a\nb\n"}],
@@ -58,6 +60,13 @@ my @Tests =
   ['opt-br2', qw(-b -r -s '\._+'),
    {IN=>".__x.___y.____z._1._2.__3.___4"},
    {OUT=>".___4.__3._2._1.____z.___y.__x"}],
+
+  ['pipe-bad-tmpdir',
+   {ENV=>"TMPDIR=$bad_dir"},
+   {IN_PIPE=>"a\n"},
+   {ERR=>"$prog: cannot create temporary file in `$bad_dir':"
+    . " No such file or directory\n"},
+   {EXIT => 1}],
 );

 @Tests = triple_test address@hidden;
--
1.6.0.rc2.38.g413e06




reply via email to

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