]> git.ipfire.org Git - thirdparty/tar.git/commitdiff
tar: --one-top-level=DIR must be relative master
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 30 Jan 2026 20:48:48 +0000 (12:48 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 30 Jan 2026 20:56:30 +0000 (12:56 -0800)
* src/tar.c (decode_options): Require --one-top-level operand
to be relative.

NEWS
doc/tar.texi
src/tar.c

diff --git a/NEWS b/NEWS
index 99a22896844363887e40c2ce9a28941232895f0e..083d5831fe9c44c7381cbdf71cbae52ab3f9d7e0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU tar NEWS - User visible changes. 2025-11-26
+GNU tar NEWS - User visible changes. 2026-01-30
 Please send GNU tar bug reports to <bug-tar@gnu.org>
 \f
 version 1.35.90 (git)
 Please send GNU tar bug reports to <bug-tar@gnu.org>
 \f
 version 1.35.90 (git)
@@ -24,7 +24,9 @@ as argument to --mtime option (see GNU tar manual, chapter 4
 Defines output format for the COMMAND set by the above option.  If
 used, command output will be parsed using strptime(3).
 
 Defines output format for the COMMAND set by the above option.  If
 used, command output will be parsed using strptime(3).
 
-* Skip file or archive member if transformed name is empty
+* Changes to behavior
+
+** Skip file or archive member if transformed name is empty
 
 If applying file name transformations (--transform and
 --strip-component options) to a file or member name results in an
 
 If applying file name transformations (--transform and
 --strip-component options) to a file or member name results in an
@@ -33,6 +35,9 @@ empty string that file or member is skipped and a warning is printed.
 The warning can be suppressed using the --warning=empty-transform
 option.
 
 The warning can be suppressed using the --warning=empty-transform
 option.
 
+** --one-top-level=DIR now requires DIR to be relative.
+   Previously this restriction was alluded to in the manual but not enforced.
+
 * Bug fixes
 
 ** When extracting, tar no longer follows symbolic links to targets
 * Bug fixes
 
 ** When extracting, tar no longer follows symbolic links to targets
index 211b5960e64b96464f5307b994f01715513e5709..c1b6f7d2eb1a6a22e54b8624202d7234d72cf39d 100644 (file)
@@ -3274,10 +3274,14 @@ directory.
 @opsummary{one-top-level}
 @item --one-top-level[=@var{dir}]
 Tells @command{tar} to create a new directory beneath the extraction directory
 @opsummary{one-top-level}
 @item --one-top-level[=@var{dir}]
 Tells @command{tar} to create a new directory beneath the extraction directory
-(or the one passed to @option{-C}) and use it to guard against
-tarbombs.  In the absence of @var{dir} argument, the name of the new directory
-will be equal to the base name of the archive (file name minus the
-archive suffix, if recognized).  Any member names that do not begin
+(or the one passed to @option{-C}) and use it to prevent @command{tar}
+from modifying files outside that directory.
+If @var{dir} is present, it must be a relative file name.
+If it is absent, the name of the new directory
+is the base name of the archive minus any recognized archive suffix.
+If multiple @option{-C} options are present,
+each has its own subdirectory with the same name.
+Any member names that do not begin
 with that directory name (after
 transformations from @option{--transform} and
 @option{--strip-components}) will be prefixed with it.  Recognized
 with that directory name (after
 transformations from @option{--transform} and
 @option{--strip-components}) will be prefixed with it.  Recognized
index 9c53bdbd77f21e0815591deb4f5a3769c221a0c0..9376b59b74e57f1770c3209de7c3f5ad92e938df 100644 (file)
--- a/src/tar.c
+++ b/src/tar.c
@@ -2675,7 +2675,7 @@ decode_options (int argc, char **argv)
            one_top_level_option = false;
        }
 
            one_top_level_option = false;
        }
 
-      if (one_top_level_option && !one_top_level_dir)
+      if (!one_top_level_dir && one_top_level_option)
        {
          /* If the user wants to guarantee that everything is under one
             directory, determine its name now and let it be created later.  */
        {
          /* If the user wants to guarantee that everything is under one
             directory, determine its name now and let it be created later.  */
@@ -2687,6 +2687,9 @@ decode_options (int argc, char **argv)
            paxusage (_("Cannot deduce top-level directory name; "
                        "please set it explicitly with --one-top-level=DIR"));
        }
            paxusage (_("Cannot deduce top-level directory name; "
                        "please set it explicitly with --one-top-level=DIR"));
        }
+
+      if (one_top_level_dir && !IS_RELATIVE_FILE_NAME (one_top_level_dir))
+       paxusage(_("--one-top-level=DIR must use a relative file name"));
     }
 
   /* If ready to unlink hierarchies, so we are for simpler files.  */
     }
 
   /* If ready to unlink hierarchies, so we are for simpler files.  */