Hello, attached are a regression test and sort of initial version of a fix for https://bugzilla.redhat.com/656834 -- the problem is that during xheader_decode(), the file name obtained from "GNU.sparse.name" is later overriden by the dummy name stored in "path", which leads to a nonsense file name stored on disk. A minimal example may look like:
$ NAME=`seq 60 | tr -d '\n'` $ truncate -s 10M $NAME $ tar -c --sparse --posix $NAME | tar t Attached is also a gdb trace that shows what happens. Just two concerns about the fix: 1) It expects that "GNU.sparse.major" comes before "path", what is IMO not guaranteed. 2) It inserts a sparse-related quirk into the common part of code. I guess we should rather go through keyword_override_list or something like that, but I don't understand much the code. Kamil
From 6dd0f205b1b9753e3ad4b11e31c93b119f3e9923 Mon Sep 17 00:00:00 2001 From: Kamil Dudka <[email protected]> Date: Thu, 25 Nov 2010 00:01:52 +0100 Subject: [PATCH 1/2] tests: new test sparse04 for --sparse --posix and long names * tests/Makefile.am (TESTSUITE_AT): Add sparse04.at. * tests/sparse04.at: New file. * tests/testsuite.at: Include it. --- tests/Makefile.am | 1 + tests/sparse04.at | 42 ++++++++++++++++++++++++++++++++++++++++++ tests/testsuite.at | 1 + 3 files changed, 44 insertions(+), 0 deletions(-) create mode 100644 tests/sparse04.at diff --git a/tests/Makefile.am b/tests/Makefile.am index 7b1e226..ab7d104 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -146,6 +146,7 @@ TESTSUITE_AT = \ sparse01.at\ sparse02.at\ sparse03.at\ + sparse04.at\ sparsemv.at\ sparsemvp.at\ spmvp00.at\ diff --git a/tests/sparse04.at b/tests/sparse04.at new file mode 100644 index 0000000..b4513bc --- /dev/null +++ b/tests/sparse04.at @@ -0,0 +1,42 @@ +# Process this file with autom4te to create testsuite. -*- Autotest -*- + +# Test suite for GNU tar. +# Copyright (C) 2010 Free Software Foundation, Inc. + +# This program 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, or (at your option) +# any later version. + +# This program 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. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +AT_SETUP([restoring long names of sparse files]) +AT_KEYWORDS([sparse sparse04]) + +# Tar 1.25 incorrectly restored long names of sparse files from PAX header +# Reference: https://bugzilla.redhat.com/656834 + +m4_define([NAME_111], + [123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960]) + +AT_TAR_CHECK([ +genfile --sparse --file NAME_111 --block-size 512 8M A || AT_SKIP_TEST +tar -c --sparse --posix NAME_111 | tar t +], +[0], +[NAME_111 +], +[], +[], +[], +[pax]) + +AT_CLEANUP diff --git a/tests/testsuite.at b/tests/testsuite.at index e8df868..40e1ea3 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -224,6 +224,7 @@ m4_include([shortrec.at]) m4_include([sparse01.at]) m4_include([sparse02.at]) m4_include([sparse03.at]) +m4_include([sparse04.at]) m4_include([sparsemv.at]) m4_include([spmvp00.at]) m4_include([spmvp01.at]) -- 1.7.3.2
From 68e17f7bf15fee3b1473d5f4d4b92c77b2722769 Mon Sep 17 00:00:00 2001 From: Kamil Dudka <[email protected]> Date: Thu, 25 Nov 2010 00:04:06 +0100 Subject: [PATCH 2/2] tar --sparse now properly restore long file names from PAX header Problem reported by Bernd Schubert in <https://bugzilla.redhat.com/656834>. * xheader.c (decx): Do not override "GNU.sparse.name" by "path". --- src/xheader.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/src/xheader.c b/src/xheader.c index 2284e97..8178aef 100644 --- a/src/xheader.c +++ b/src/xheader.c @@ -608,6 +608,8 @@ decx (void *data, char const *keyword, char const *value, size_t size) { struct xhdr_tab const *t; struct tar_stat_info *st = data; + if (0 < st->sparse_major && !strcmp ("path", keyword)) + return; if (xheader_keyword_deleted_p (keyword) || xheader_keyword_override_p (keyword)) -- 1.7.3.2
(gdb) break decx Breakpoint 1 at 0x4125bf: file xheader.c, line 610. (gdb) break path_decoder Breakpoint 2 at 0x413a41: file xheader.c, line 1173. (gdb) run Breakpoint 1, decx (data=0x65aca0, keyword=0x660b43 "GNU.sparse.major", value=0x660b54 "1", size=1) at xheader.c:610 610 struct tar_stat_info *st = data; (gdb) cont Breakpoint 1, decx (data=0x65aca0, keyword=0x660b59 "GNU.sparse.minor", value=0x660b6a "0", size=1) at xheader.c:610 610 struct tar_stat_info *st = data; (gdb) Breakpoint 1, decx (data=0x65aca0, keyword=0x660b70 "GNU.sparse.name", value=0x660b80 "123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960", size=111) at xheader.c:610 610 struct tar_stat_info *st = data; (gdb) Breakpoint 2, path_decoder (st=0x65aca0, keyword=0x660b70 "GNU.sparse.name", arg=0x660b80 "123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960", size=111) at xheader.c:1173 1173 decode_string (&st->orig_file_name, arg); (gdb) finish 0x0000000000412623 in decx (data=0x65aca0, keyword=0x660b70 "GNU.sparse.name", value=0x660b80 "123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960", size=111) at xheader.c:618 618 t->decoder (st, keyword, value, size); (gdb) print st->file_name $1 = 0x66ad40 "123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960" (gdb) cont Breakpoint 1, decx (data=0x65aca0, keyword=0x660bf3 "GNU.sparse.realsize", value=0x660c07 "10485760", size=8) at xheader.c:610 610 struct tar_stat_info *st = data; (gdb) Breakpoint 1, decx (data=0x65aca0, keyword=0x660c14 "path", value=0x660c19 "./GNUSparseFile.18026/123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960", size=133) at xheader.c:610 610 struct tar_stat_info *st = data; (gdb) Breakpoint 2, path_decoder (st=0x65aca0, keyword=0x660c14 "path", arg=0x660c19 "./GNUSparseFile.18026/123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960", size=133) at xheader.c:1173 1173 decode_string (&st->orig_file_name, arg); (gdb) finish 0x0000000000412623 in decx (data=0x65aca0, keyword=0x660c14 "path", value=0x660c19 "./GNUSparseFile.18026/123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960", size=133) at xheader.c:618 618 t->decoder (st, keyword, value, size); (gdb) print st->file_name $2 = 0x66a630 "./GNUSparseFile.18026/123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960"
