mirror of
https://git.savannah.gnu.org/git/tar.git
synced 2026-08-21 16:56:06 +00:00
tar: reject -C x --one-top-dir=/abs/olute
It’s not clear what ‘-C x --one-top-dir=/abs/olute’ should mean, so for now let’s play it safe and reject that combination. * src/misc.c (chdir_arg): Diagnose attempts to combine -C with --one-top-level=/abs/olute. * tests/onetop06.at: Move last test to onetop07.at, since it now differs in behavior and it’s better to test it separately. * tests/onetop07.at: New file. * tests/Makefile.am (TESTSUITE_AT): Add it. * tests/testsuite.at: Include it.
This commit is contained in:
@@ -38,10 +38,11 @@ option.
|
||||
** The --one-top-level option now requires either -x or -d mode.
|
||||
Previously the behavior was unspecified in other operation modes.
|
||||
|
||||
** If DIR is absolute, the --one-top-level=DIR option now extracts all
|
||||
files relative to DIR, without stripping leading DIR from file names.
|
||||
Any -C options are ignored. Formerly, the behavior was
|
||||
undocumented and differed from one tar version to the next.
|
||||
** If DIR is absolute, the --one-top-level=DIR option is now incompatible
|
||||
with the --directory (-C) option, and it now extracts all files
|
||||
relative to DIR, without stripping leading DIR from file names.
|
||||
Formerly, the behavior was undocumented and differed from one tar
|
||||
version to the next.
|
||||
|
||||
* Bug fixes
|
||||
|
||||
|
||||
+5
-5
@@ -3291,8 +3291,7 @@ Extract files relative to @var{dir},
|
||||
ignoring any @var{dir} prefixes in the archive.
|
||||
An absent @var{dir} defaults to
|
||||
the base name of the archive minus any recognized archive suffix.
|
||||
If @var{dir} is relative, it is relative to the working directory;
|
||||
if absolute, any @option{--directory} (@option{-C}) options are irrelevant.
|
||||
If @var{dir} is relative, it is relative to the working directory.
|
||||
@xref{directory}.
|
||||
|
||||
@opsummary{overwrite}
|
||||
@@ -9465,8 +9464,7 @@ Recognized file name suffixes are @samp{.tar},
|
||||
and any compression suffixes recognizable by @xref{--auto-compress}.
|
||||
|
||||
If @var{dir} is absolute, extract all files under that directory;
|
||||
any @option{-C} options are irrelevant,
|
||||
and @var{dir} itself is exempt from the usual safety rules
|
||||
@var{dir} itself is exempt from the usual safety rules
|
||||
prohibiting extraction outside the working directory.
|
||||
The two main differences between @samp{--one-top-level=/abs/olute}
|
||||
and @samp{-C /abs/olute} are that the former affects all files
|
||||
@@ -9477,7 +9475,9 @@ whereas in the latter @file{/abs/olute} must already exist.
|
||||
|
||||
The @option{--one-top-level} option can be used only when extracting,
|
||||
comparing, or reading from the archive.
|
||||
It is incompatible with the @option{--absolute-names} (@option{-P}) option.
|
||||
It is incompatible with the @option{--absolute-names} (@option{-P}) option,
|
||||
and if @var{dir} is absolute it is incompatible with the
|
||||
@option{--directory} (@option{-C}) option.
|
||||
@end table
|
||||
|
||||
All filename arguments appearing after a
|
||||
|
||||
+12
-8
@@ -979,7 +979,10 @@ struct wd
|
||||
directory. Ordinarily the remaining entries are for -C options.
|
||||
But if --one-top-level, each entry is followed by another entry for
|
||||
its --one-top-level counterpart, so that ordinary entries are
|
||||
even-numbered and --one-top-level entries are odd-numbered. */
|
||||
even-numbered and --one-top-level entries are odd-numbered.
|
||||
And if --one-top-level specifies an absolute directory,
|
||||
there are just two entries, one for the initial working directory
|
||||
and one for the absolute directory. */
|
||||
static struct wd *wd;
|
||||
|
||||
/* The number of working directories in the vector. */
|
||||
@@ -1046,13 +1049,18 @@ ensure_wd (void)
|
||||
}
|
||||
|
||||
/* DIR is the operand of a -C option; add it to vector of chdir targets,
|
||||
and return the index of its location. If --one-top-level-dir, add
|
||||
two targets to the vector. However, if DIR is "." or an equivalent,
|
||||
or if --one-top-level-dir is an absolute file name,
|
||||
and return the index of its location. If --one-top-level-dir=ONETOP
|
||||
is specified, add two targets to the vector if ONETOP is relative
|
||||
and report an error otherwise. However, if DIR is "." or an equivalent,
|
||||
just reuse the last item in the vector. */
|
||||
idx_t
|
||||
chdir_arg (char *dir)
|
||||
{
|
||||
/* Unless this is the trivial chdir_arg (".") at start, this is an
|
||||
error when combined with --one-top-level=X where X is absolute. */
|
||||
if (wd && one_top_level_dir && IS_ABSOLUTE_FILE_NAME (one_top_level_dir))
|
||||
paxfatal (0, _("-C and --one-top-level='/...' are incompatible"));
|
||||
|
||||
ensure_wd ();
|
||||
|
||||
/* Optimize the common special case of the working directory,
|
||||
@@ -1064,10 +1072,6 @@ chdir_arg (char *dir)
|
||||
return wd_count - 1;
|
||||
}
|
||||
|
||||
/* Optimize --one-top-level=X where X is an absolute file name. */
|
||||
if (one_top_level_dir && IS_ABSOLUTE_FILE_NAME (one_top_level_dir))
|
||||
return wd_count - 1;
|
||||
|
||||
ptrdiff_t shortage = 1 + !!one_top_level_dir - (wd_alloc - wd_count);
|
||||
if (0 < shortage)
|
||||
wd = xpalloc (wd, &wd_alloc, shortage, -1, sizeof *wd);
|
||||
|
||||
@@ -205,6 +205,7 @@ TESTSUITE_AT = \
|
||||
onetop04.at\
|
||||
onetop05.at\
|
||||
onetop06.at\
|
||||
onetop07.at\
|
||||
opcomp01.at\
|
||||
opcomp02.at\
|
||||
opcomp03.at\
|
||||
|
||||
@@ -32,8 +32,6 @@ diff d e/d/d || exit
|
||||
tar -cf test1.tar e/c || exit
|
||||
tar -xf test1.tar -C f --one-top-level=e/c || exit
|
||||
diff e/c/d f/e/c/d || exit
|
||||
tar -xf test1.tar -C f --one-top-level=$PWD/g || exit
|
||||
diff e/c/d g/e/c/d || exit
|
||||
])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
#
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2026 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
AT_SETUP([tar -C and --one-top-level=/abs/olute])
|
||||
AT_KEYWORDS([extract onetop onetop07])
|
||||
|
||||
AT_TAR_CHECK([
|
||||
mkdir d f && genfile --file d/file || framework_failure_
|
||||
tar -cf test.tar d || exit
|
||||
tar -xf test.tar -C f --one-top-level=$PWD/g
|
||||
],
|
||||
[2],
|
||||
[],
|
||||
[tar: -C and --one-top-level='/...' are incompatible
|
||||
tar: Error is not recoverable: exiting now
|
||||
])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -544,6 +544,7 @@ m4_include([onetop03.at])
|
||||
m4_include([onetop04.at])
|
||||
m4_include([onetop05.at])
|
||||
m4_include([onetop06.at])
|
||||
m4_include([onetop07.at])
|
||||
|
||||
AT_BANNER([Star tests])
|
||||
m4_include([star/gtarfail.at])
|
||||
|
||||
Reference in New Issue
Block a user