Allow to store extended attribute keywords containing '=' character
This commit is contained in:
parent
d51fc76643
commit
9989b8ed46
236
tar-1.26-xattrs-equal-sign.patch
Normal file
236
tar-1.26-xattrs-equal-sign.patch
Normal file
@ -0,0 +1,236 @@
|
||||
diff --git a/src/xheader.c b/src/xheader.c
|
||||
index e785248..de47388 100644
|
||||
--- a/src/xheader.c
|
||||
+++ b/src/xheader.c
|
||||
@@ -499,6 +499,43 @@ static void xheader_xattr__add (struct xattr_array **xattr_map,
|
||||
(*xattr_map)[pos].xval_len = len;
|
||||
}
|
||||
|
||||
+/* This is reversal function for xattr_encode_keyword. See comment for
|
||||
+ xattr_encode_keyword() for more info. */
|
||||
+static void xattr_decode_keyword (char *keyword)
|
||||
+{
|
||||
+ char *kpr, *kpl; /* keyword pointer left/right */
|
||||
+ kpr = kpl = keyword;
|
||||
+
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ if (*kpr == '%')
|
||||
+ {
|
||||
+ if (kpr[1] == '3' && kpr[2] == 'D')
|
||||
+ {
|
||||
+ *kpl = '=';
|
||||
+ kpr += 3;
|
||||
+ kpl ++;
|
||||
+ continue;
|
||||
+ }
|
||||
+ else if (kpr[1] == '2' && kpr[2] == '5')
|
||||
+ {
|
||||
+ *kpl = '%';
|
||||
+ kpr += 3;
|
||||
+ kpl ++;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *kpl = *kpr;
|
||||
+
|
||||
+ if (*kpr == 0)
|
||||
+ break;
|
||||
+
|
||||
+ kpr++;
|
||||
+ kpl++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void xheader_xattr_add(struct tar_stat_info *st,
|
||||
const char *key, const char *val, size_t len)
|
||||
{
|
||||
@@ -807,15 +844,70 @@ xheader_read (struct xheader *xhdr, union block *p, size_t size)
|
||||
while (size > 0);
|
||||
}
|
||||
|
||||
+/* xattr_encode_keyword() substitutes '=' ~~> '%3D' and '%' ~~> '%25'
|
||||
+ in extended attribute keywords. This is needed because the '=' character
|
||||
+ has special purpose in extended attribute header - it splits keyword and
|
||||
+ value part of header. If there was the '=' occurrence allowed inside
|
||||
+ keyword, there would be no unambiguous way how to decode this extended
|
||||
+ attribute.
|
||||
+
|
||||
+ (http://lists.gnu.org/archive/html/bug-tar/2012-10/msg00017.html)
|
||||
+ */
|
||||
+static char *xattr_encode_keyword(const char *keyword)
|
||||
+{
|
||||
+ static char *encode_buffer = NULL;
|
||||
+ static size_t encode_buffer_size = 0;
|
||||
+ size_t bp; /* keyword/buffer pointers */
|
||||
+
|
||||
+ if (!encode_buffer)
|
||||
+ {
|
||||
+ encode_buffer_size = 256;
|
||||
+ encode_buffer = xmalloc (encode_buffer_size);
|
||||
+ }
|
||||
+ else
|
||||
+ *encode_buffer = 0;
|
||||
+
|
||||
+ for (bp = 0; *keyword != 0; ++bp, ++keyword)
|
||||
+ {
|
||||
+ char c = *keyword;
|
||||
+
|
||||
+ if (bp + 2 /* enough for URL encoding also.. */ >= encode_buffer_size)
|
||||
+ {
|
||||
+ encode_buffer = x2realloc (encode_buffer, &encode_buffer_size);
|
||||
+ }
|
||||
+
|
||||
+ if (c == '%')
|
||||
+ {
|
||||
+ strcpy (encode_buffer + bp, "%25");
|
||||
+ bp += 2;
|
||||
+ }
|
||||
+ else if (c == '=')
|
||||
+ {
|
||||
+ strcpy (encode_buffer + bp, "%3D");
|
||||
+ bp += 2;
|
||||
+ }
|
||||
+ else
|
||||
+ encode_buffer[bp] = c;
|
||||
+ }
|
||||
+
|
||||
+ encode_buffer[bp] = 0;
|
||||
+
|
||||
+ return encode_buffer;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
xheader_print_n (struct xheader *xhdr, char const *keyword,
|
||||
char const *value, size_t vsize)
|
||||
{
|
||||
- size_t len = strlen (keyword) + vsize + 3; /* ' ' + '=' + '\n' */
|
||||
size_t p;
|
||||
size_t n = 0;
|
||||
char nbuf[UINTMAX_STRSIZE_BOUND];
|
||||
char const *np;
|
||||
+ size_t len, klen;
|
||||
+
|
||||
+ keyword = xattr_encode_keyword (keyword);
|
||||
+ klen = strlen (keyword);
|
||||
+ len = klen + vsize + 3; /* ' ' + '=' + '\n' */
|
||||
|
||||
do
|
||||
{
|
||||
@@ -827,7 +919,7 @@ xheader_print_n (struct xheader *xhdr, char const *keyword,
|
||||
|
||||
x_obstack_grow (xhdr, np, n);
|
||||
x_obstack_1grow (xhdr, ' ');
|
||||
- x_obstack_grow (xhdr, keyword, strlen (keyword));
|
||||
+ x_obstack_grow (xhdr, keyword, klen);
|
||||
x_obstack_1grow (xhdr, '=');
|
||||
x_obstack_grow (xhdr, value, vsize);
|
||||
x_obstack_1grow (xhdr, '\n');
|
||||
@@ -1613,11 +1705,20 @@ static void
|
||||
xattr_decoder (struct tar_stat_info *st,
|
||||
char const *keyword, char const *arg, size_t size)
|
||||
{
|
||||
- char *xstr = NULL;
|
||||
+ char *xstr, *xkey;
|
||||
+
|
||||
+ /* copy keyword */
|
||||
+ size_t klen_raw = strlen (keyword);
|
||||
+ xkey = alloca (klen_raw + 1);
|
||||
+ memcpy (xkey, keyword, klen_raw + 1) /* including null-terminating */;
|
||||
+
|
||||
+ /* copy value */
|
||||
+ xstr = alloca (size + 1);
|
||||
+ memcpy (xstr, arg, size + 1); /* separator included, for GNU tar '\n' */;
|
||||
+
|
||||
+ xattr_decode_keyword (xkey);
|
||||
|
||||
- xstr = xmemdup(arg, size + 1);
|
||||
- xheader_xattr_add(st, keyword + strlen("SCHILY.xattr."), xstr, size);
|
||||
- free(xstr);
|
||||
+ xheader_xattr_add (st, xkey + strlen("SCHILY.xattr."), xstr, size);
|
||||
}
|
||||
|
||||
static void
|
||||
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
||||
index 88942b3..449bbb4 100644
|
||||
--- a/tests/Makefile.am
|
||||
+++ b/tests/Makefile.am
|
||||
@@ -177,6 +177,7 @@ TESTSUITE_AT = \
|
||||
xattr/xattr02.at\
|
||||
xattr/xattr03.at\
|
||||
xattr/xattr04.at\
|
||||
+ xattr/xattr05.at\
|
||||
xattr/acls01.at\
|
||||
xattr/acls02.at\
|
||||
xattr/selnx01.at\
|
||||
diff --git a/tests/testsuite.at b/tests/testsuite.at
|
||||
index 63be9f0..d943e1f 100644
|
||||
--- a/tests/testsuite.at
|
||||
+++ b/tests/testsuite.at
|
||||
@@ -343,6 +343,7 @@ m4_include([xattr/xattr01.at])
|
||||
m4_include([xattr/xattr02.at])
|
||||
m4_include([xattr/xattr03.at])
|
||||
m4_include([xattr/xattr04.at])
|
||||
+m4_include([xattr/xattr05.at])
|
||||
|
||||
m4_include([xattr/acls01.at])
|
||||
m4_include([xattr/acls02.at])
|
||||
diff --git a/tests/xattr/xattr05.at b/tests/xattr/xattr05.at
|
||||
new file mode 100644
|
||||
index 0000000..d36efbe
|
||||
--- /dev/null
|
||||
+++ b/tests/xattr/xattr05.at
|
||||
@@ -0,0 +1,52 @@
|
||||
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
+#
|
||||
+# Test suite for GNU tar.
|
||||
+# Copyright (C) 2012 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, see <http://www.gnu.org/licenses/>.
|
||||
+#
|
||||
+# Test description: Test for archiving/extracting of extended attributes
|
||||
+# having the '=' character in its keyword.
|
||||
+#
|
||||
+# Test for the regression caused by tar update from 1.23 to
|
||||
+# 1.26, Red Hat xattr patch was not ready for open->openat conversion.
|
||||
+#
|
||||
+# Relevant mailing list thread:
|
||||
+#
|
||||
+# http://lists.gnu.org/archive/html/bug-tar/2012-10/msg00017.html
|
||||
+
|
||||
+AT_SETUP([xattrs: keywords with '=' and '%'])
|
||||
+AT_KEYWORDS([xattrs xattr05])
|
||||
+
|
||||
+AT_TAR_CHECK([
|
||||
+AT_XATTRS_PREREQ
|
||||
+
|
||||
+mkdir dir
|
||||
+mkdir output
|
||||
+genfile --file dir/file
|
||||
+
|
||||
+setfattr -n user.=NAME%3D= -v value dir/file
|
||||
+getfattr -d dir/file | grep -v '# ' > before
|
||||
+
|
||||
+# archive whole directory including binary xattrs
|
||||
+tar --xattrs -cf archive.tar -C dir .
|
||||
+
|
||||
+tar --xattrs -xf archive.tar -C output
|
||||
+getfattr -d output/file | grep -v '# ' > after
|
||||
+diff before after
|
||||
+],
|
||||
+[0],
|
||||
+[])
|
||||
+
|
||||
+AT_CLEANUP
|
4
tar.spec
4
tar.spec
@ -5,7 +5,7 @@ Summary: A GNU file archiving program
|
||||
Name: tar
|
||||
Epoch: 2
|
||||
Version: 1.26
|
||||
Release: 12%{?dist}
|
||||
Release: 13%{?dist}
|
||||
License: GPLv3+
|
||||
Group: Applications/Archiving
|
||||
URL: http://www.gnu.org/software/tar/
|
||||
@ -39,6 +39,7 @@ Patch10: tar-1.26-stdio.in.patch
|
||||
# Prepare gnulib for xattrs and apply xattrs & acls & selinux (#850291)
|
||||
Patch11: tar-1.26-xattrs-gnulib-prepare.patch
|
||||
Patch12: tar-1.26-xattrs.patch
|
||||
Patch13: tar-1.26-xattrs-equal-sign.patch
|
||||
|
||||
BuildRequires: autoconf automake texinfo gettext libacl-devel rsh
|
||||
# allow proper tests for extended attributes
|
||||
@ -76,6 +77,7 @@ the rmt package.
|
||||
%patch10 -p1 -b .gets %{?_rawbuild}
|
||||
%patch11 -p1 -b .xattrs_gnulib_prep
|
||||
%patch12 -p1 -b .xattrs2
|
||||
%patch13 -p1 -b .xattrs-equal-sign
|
||||
|
||||
autoreconf
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user