1 From 00f928642f7f7f1e7154a47df9cbf37ae70402ea Mon Sep 17 00:00:00 2001
2 From: Pavel Raiskup <praiskup@redhat.com>
3 Date: Thu, 30 Jun 2016 16:17:29 +0200
4 Subject: [PATCH] sparse: fix pax extraction for unicode filenames
6 Make sure that 'GNU.sparse.name' header has higher priority than
7 (for sparse-purposes artificially modified) 'path' pax header.
9 Historically, the 'GNU.sparse.name' header comes before 'path';
10 this caused that modified 'path' header won and that is not what
11 we want in sparse "capable" tar implementation.
13 * src/tar.h (tar_stat_info): New argument sparse_name_done.
14 * src/xheader.c (raw_path_decoder): Move here the unconditional
15 code from path_decoder.
16 (path_decoder): Apply raw_path_decoder only if sparse_path_decoder
18 (sparse_path_decoder): New wrapper around raw_path_decoder.
19 * tests/sparse07.at: New testcase.
20 * tests/testsuite.at: Mention new testcase.
21 * tests/Makefile.am: Likewise.
24 src/xheader.c | 26 ++++++++++++++++++++++----
25 tests/Makefile.am | 1 +
26 tests/sparse07.at | 35 +++++++++++++++++++++++++++++++++++
27 tests/testsuite.at | 1 +
28 5 files changed, 63 insertions(+), 4 deletions(-)
29 create mode 100644 tests/sparse07.at
31 diff --git a/src/tar.h b/src/tar.h
32 index 07b5bc1..f3e2c43 100644
35 @@ -331,6 +331,10 @@ struct tar_stat_info
36 int real_size_set; /* True when GNU.sparse.realsize is set in
39 + bool sparse_name_done; /* Set to true if 'GNU.sparse.name' header was
40 + processed pax header parsing. Following 'path'
41 + header (lower priority) will be ignored. */
43 size_t xattr_map_size; /* Size of the xattr map */
44 struct xattr_array *xattr_map;
46 diff --git a/src/xheader.c b/src/xheader.c
47 index 8dda580..335ddaf 100644
50 @@ -1291,14 +1291,32 @@ path_coder (struct tar_stat_info const *st, char const *keyword,
54 +raw_path_decoder (struct tar_stat_info *st, char const *arg)
56 + decode_string (&st->orig_file_name, arg);
57 + decode_string (&st->file_name, arg);
58 + st->had_trailing_slash = strip_trailing_slashes (st->file_name);
63 path_decoder (struct tar_stat_info *st,
64 char const *keyword __attribute__((unused)),
66 size_t size __attribute__((unused)))
68 - decode_string (&st->orig_file_name, arg);
69 - decode_string (&st->file_name, arg);
70 - st->had_trailing_slash = strip_trailing_slashes (st->file_name);
71 + if (! st->sparse_name_done)
72 + raw_path_decoder (st, arg);
76 +sparse_path_decoder (struct tar_stat_info *st,
77 + char const *keyword __attribute__((unused)),
79 + size_t size __attribute__((unused)))
81 + st->sparse_name_done = true;
82 + raw_path_decoder (st, arg);
86 @@ -1730,7 +1748,7 @@ struct xhdr_tab const xhdr_tab[] = {
87 { "uname", uname_coder, uname_decoder, 0, false },
89 /* Sparse file handling */
90 - { "GNU.sparse.name", path_coder, path_decoder,
91 + { "GNU.sparse.name", path_coder, sparse_path_decoder,
92 XHDR_PROTECTED, false },
93 { "GNU.sparse.major", sparse_major_coder, sparse_major_decoder,
94 XHDR_PROTECTED, false },
95 diff --git a/tests/Makefile.am b/tests/Makefile.am
96 index 06f2325..fd38cb4 100644
97 --- a/tests/Makefile.am
98 +++ b/tests/Makefile.am
99 @@ -215,6 +215,7 @@ TESTSUITE_AT = \
107 diff --git a/tests/sparse07.at b/tests/sparse07.at
109 index 0000000..8191c00
111 +++ b/tests/sparse07.at
113 +# Process this file with autom4te to create testsuite. -*- Autotest -*-
115 +# Test suite for GNU tar.
116 +# Copyright 2016 Free Software Foundation, Inc.
118 +# This file is part of GNU tar.
120 +# GNU tar is free software; you can redistribute it and/or modify
121 +# it under the terms of the GNU General Public License as published by
122 +# the Free Software Foundation; either version 3 of the License, or
123 +# (at your option) any later version.
125 +# GNU tar is distributed in the hope that it will be useful,
126 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
127 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
128 +# GNU General Public License for more details.
130 +# You should have received a copy of the GNU General Public License
131 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
133 +AT_SETUP([sparse files with unicode names])
134 +AT_KEYWORDS([sparse sparse07 unicode])
137 +genfile --sparse --file žluť --block-size 512 0 ABCD 1M EFGH 2000K IJKL || AT_SKIP_TEST
138 +tar -c -f archive --sparse žluť || exit 1
145 +[],[],[],[posix, gnu, oldgnu])
148 diff --git a/tests/testsuite.at b/tests/testsuite.at
149 index e0525a1..59ace0b 100644
150 --- a/tests/testsuite.at
151 +++ b/tests/testsuite.at
152 @@ -387,6 +387,7 @@ m4_include([sparse03.at])
153 m4_include([sparse04.at])
154 m4_include([sparse05.at])
155 m4_include([sparse06.at])
156 +m4_include([sparse07.at])
157 m4_include([sparsemv.at])
158 m4_include([spmvp00.at])
159 m4_include([spmvp01.at])