> Hello,
>    I discovered this recently. It it is always reproducible for me on
> CentOS 6.4, Fedora 14 - 19, Ubuntu 12.04 (versions 1.23 and 1.26).
> CentOS 4 and 5 are ok.
>
> cd /tmp; > empty; echo . > valid; tar cf /dev/null -T empty -T valid
> Segmentation fault (core dumped)

Thanks for the report.  It was easily reproducible on my Fedora 19 box.

Possible fix is in attachment, Pavel
>From 87c6b8e31c5f9b33d0ba458e6a40152f130262ae Mon Sep 17 00:00:00 2001
From: Pavel Raiskup <prais...@redhat.com>
Date: Tue, 23 Jul 2013 12:01:36 +0200
Subject: [PATCH] tar: fix -T option for empty and corrupted files
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Problem reported by Michal Žejdl:
<http://lists.gnu.org/archive/html/bug-tar/2013-07/msg00009.html>

* src/tar.c (read_name_from_file): Don't return file_list_end
when some characters was successfully read.  Don't obstack_1grow
when no characters was read.
* tests/T-torture.at: Add new test case.
* tests/Makefile.am: Register new testcase.
* tests/testsuite.at: Likewise.
---
 src/tar.c          |  9 ++++---
 tests/Makefile.am  |  1 +
 tests/T-torture.at | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/testsuite.at |  1 +
 4 files changed, 82 insertions(+), 4 deletions(-)
 create mode 100644 tests/T-torture.at

diff --git a/src/tar.c b/src/tar.c
index 9111433..2381c8c 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -1140,12 +1140,13 @@ read_name_from_file (FILE *fp, struct obstack *stk, int term)
       counter++;
     }
 
-  if (counter == 0 && c != EOF)
-    return file_list_skip;
+  if (counter == 0)
+    return c == EOF ? file_list_end : file_list_skip;
 
+  /* if (c == EOF), the file is bad (last line without '\n').  In that case,
+     this function will be called once again. */
   obstack_1grow (stk, 0);
-
-  return (counter == 0 && c == EOF) ? file_list_end : file_list_success;
+  return file_list_success;
 }
 
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8b7acb1..d86d7ab 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -44,6 +44,7 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac
 TESTSUITE_AT = \
  T-empty.at\
  T-null.at\
+ T-torture.at\
  testsuite.at\
  append.at\
  append01.at\
diff --git a/tests/T-torture.at b/tests/T-torture.at
new file mode 100644
index 0000000..7360822
--- /dev/null
+++ b/tests/T-torture.at
@@ -0,0 +1,75 @@
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
+
+# Test suite for GNU tar.
+# Copyright 2013 Free Software Foundation, Inc.
+
+# This file is part of GNU tar.
+
+# GNU tar is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# GNU tar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# Tar was unable to handle '-T empty -T valid' parameterer.  Also did not work
+# for files ending without newline.
+#
+# Reported by: Michal Žejdl <ze...@suas.cz>
+# References: <http://lists.gnu.org/archive/html/bug-tar/2013-07/msg00009.html>
+
+AT_SETUP([files-from: torture -T option])
+AT_KEYWORDS([files-from T-torture])
+
+AT_TAR_CHECK([
+AT_SORT_PREREQ
+
+echo -n         > empty
+echo            > empty_newline
+echo    file1   > valid
+echo    file2   > valid_multiline
+echo    file3  >> valid_multiline
+
+echo -n file4   > invalid
+echo    file5   > invalid_multiline
+echo -n file6  >> invalid_multiline
+
+touch file1 file2 file3 file4 file5 file6
+
+tar cf ar -T empty -T valid
+tar tf ar
+echo ====
+
+tar cf ar -T valid -T empty
+tar tf ar
+echo ====
+
+tar cf ar -T empty -T invalid -T invalid_multiline -T valid
+tar tf ar | sort
+echo ====
+
+tar cf ar -T invalid_multiline -T empty -T valid_multiline -T invalid
+tar tf ar | sort
+],
+[0],
+[file1
+====
+file1
+====
+file1
+file4
+file5
+file6
+====
+file2
+file3
+file4
+file5
+file6
+],
+[],[],[],[ustar]) # Testing one format is enough
+
+AT_CLEANUP
diff --git a/tests/testsuite.at b/tests/testsuite.at
index d3fabe5..b25792c 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -199,6 +199,7 @@ m4_include([opcomp06.at])
 AT_BANNER([The -T option])
 m4_include([T-empty.at])
 m4_include([T-null.at])
+m4_include([T-torture.at])
 
 AT_BANNER([Various options])
 m4_include([indexfile.at])
-- 
1.8.3.1

Reply via email to