From: Jim Meyering Date: Wed, 13 Aug 2008 18:53:12 +0000 (+0200) Subject: mktemp, sort, tac: don't use undefined after mkstemp failure X-Git-Tag: v7.0~75 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=22999697b81acf3e8683c95c310a36926e7af96f;p=thirdparty%2Fcoreutils.git mktemp, sort, tac: don't use undefined after mkstemp failure When mkstemp fails, the template buffer may have undefined contents, so we must not print it. * 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. --- diff --git a/THANKS b/THANKS index 5f3c5bd720..021ff6ad62 100644 --- a/THANKS +++ b/THANKS @@ -250,6 +250,7 @@ Jeff Moore jbm@mordor.com Jeff Sheinberg jeff@bsrd.net Jens Elkner elkner@imsgroup.de Jens Schmidt jms@jsds.hamburg.com +Jeph Cowan jeph@ucar.edu Jeremy Maitin-Shepard jbms@cmu.edu Jerome Abela abela@hsc.fr Jérôme Zago bug-coreutils-ml@agt-the-walker.net diff --git a/src/mktemp.c b/src/mktemp.c index 8a09231f98..d745e6069a 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 b932a51b3f..92f400a968 100644 --- a/src/sort.c +++ b/src/sort.c @@ -741,7 +741,8 @@ create_temp_file (int *pfd) errno = saved_errno; if (fd < 0) - die (_("cannot create temporary file"), file); + error (SORT_FAILURE, errno, _("cannot create temporary file in %s"), + quote (temp_dir)); *pfd = fd; return node; diff --git a/src/tac.c b/src/tac.c index 9cf6d60dc2..c83986f592 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 616a9e44f3..3565582914 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,12 @@ 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/...\n"}, + {EXIT => 1}], ); my $save_temps = $ENV{DEBUG}; diff --git a/tests/misc/sort-merge b/tests/misc/sort-merge index 985d7a414c..6b81926104 100755 --- a/tests/misc/sort-merge +++ b/tests/misc/sort-merge @@ -66,8 +66,9 @@ 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|': .*|':|"}, + {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 2f9981d498..9995357abe 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_SUBST => "s,`$bad_dir': .*,...,"}, + {ERR => "$prog: cannot create temporary file in ...\n"}, + {EXIT => 1}], ); @Tests = triple_test \@Tests;