From: Paul Eggert Date: Fri, 30 Jan 2026 20:48:48 +0000 (-0800) Subject: tar: --one-top-level=DIR must be relative X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=678dbc679a1478da58c884de509ab2844eb04cdb;p=thirdparty%2Ftar.git tar: --one-top-level=DIR must be relative * src/tar.c (decode_options): Require --one-top-level operand to be relative. --- diff --git a/NEWS b/NEWS index 99a22896..083d5831 100644 --- 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 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). -* 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 @@ -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. +** --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 diff --git a/doc/tar.texi b/doc/tar.texi index 211b5960..c1b6f7d2 100644 --- a/doc/tar.texi +++ b/doc/tar.texi @@ -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 -(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 diff --git a/src/tar.c b/src/tar.c index 9c53bdbd..9376b59b 100644 --- a/src/tar.c +++ b/src/tar.c @@ -2675,7 +2675,7 @@ decode_options (int argc, char **argv) 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. */ @@ -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")); } + + 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. */