Commit Graph

3415 Commits

Author SHA1 Message Date
Paul Eggert
d479b2cc91 Use mkdtempat instead of mkdtemp
This fixes an interaction of -C with incremental 'X'.
Problem reported by Pavel Cahyna.
* gnulib.modules: Remove mkdtemp.
Add tempname, since our mkdtempat uses it.
* lib/mkdtempat.c, lib/mkdtempat.h: New files.
* lib/Makefile.am (noinst_HEADERS): Add mkdtempat.h.
(libtar_a_SOURCES): Add mkdtempat.c.
* src/incremen.c: Include mkdtempat.h.
(purge_directory): Use mkdtempat, not mkdtemp.
2026-04-13 00:02:17 -07:00
Paul Eggert
0470c109c0 tar: comment struct fdbase
* src/common.h (struct fdbase): Add comment.
2026-04-13 00:02:17 -07:00
Paul Eggert
55e8233438 tar: ENFILE is like EMFILE
* src/create.c (open_failure_recover):
* src/misc.c (fdbase_opendir):
Treat ENFILE like EMFILE.
2026-04-13 00:02:17 -07:00
Paul Eggert
79d61af0e1 tar: incremental 'X' follows --one-top-level
* src/incremen.c (purge_directory):
Also respect --one-top-level when handling 'X'.
2026-04-08 09:07:12 -07:00
Paul Eggert
67c8dff696 Simplify one_top_level_dir logic
* src/tar.c (one_top_level_option): Remove.  All uses removed.
All external uses changed to equivalent of !!one_top_level_dir.
(decode_options): Set one_top_level_dir to be consistent with
the old one_top_level_option.
2026-04-08 09:07:12 -07:00
Paul Eggert
90dec1cc53 --one-top-level now keeps "../" and ".../"
* src/list.c (enforce_one_top_level): Do not strip prefixes like
"../" (which should not be allowed unless -P) and ".../" (which
are ordinary file names).  The "../" not being allowed should be
addressed in a different way.
2026-04-08 09:07:12 -07:00
Paul Eggert
b4fc9ca136 Disallow --one-top-level=''.
* src/tar.c (decode_options): Do not accept an empty string
as a relative file name.
2026-04-08 09:07:12 -07:00
Paul Eggert
3e4279db96 Prefer signed int in sparse.c
* src/sparse.c (pax_dump_header_0, floorlog10)
(pax_dump_header_1, struct ok_n_block_ptr, decode_num)
(pax_decode_header): Prefer signed to unsigned integers
where either will do, as this allows for better runtime
checking for overflow.  The integers in question cannot
be negative or greater than INTMAX_MAX anyway.
2026-04-06 14:04:48 -07:00
Paul Eggert
0714d2f082 tar: strip '/' from incremental 'X' entries
Problem identified by Michał Majchrowicz and Marcin Wyczechowski,
members of the AFINE Team.
* gnulib.modules: Add mempcpy, which we were already using anyway.
* src/incremen.c (purge_directory):
Use a safer suffix for 'X' entries, too.
Also, do not turn "/" to "//" or "//" to "///" (possible only if -P).
2026-04-04 10:51:40 -07:00
Paul Eggert
9280aa3807 Prefer UNNAMED to MAYBE_UNUSED
* src/buffer.c, src/compare.c, src/exclist.c, src/extract.c:
* src/sparse.c, src/tar.c, src/xheader.c:
UNNAMED is for when an identifier is never used and so does not
need a name.  Prefer it to MAYBE_UNUSED when that is the case.
Also, drop MAYBE_UNUSED in some places where the identifier
is always used.
2026-03-22 12:23:55 -07:00
Paul Eggert
9e22dde2df Update tar.h comments
* src/tar.h: Update comments.
2026-03-22 12:23:55 -07:00
Paul Eggert
b8d8a61b25 Fix more -t/-x discrepancies
Problem reported by Guillermo de Angel in:
https://lists.gnu.org/r/bug-tar/2026-03/msg00007.html
* THANKS: Add him, and sort.
* src/extract.c (extract_dir, extract_file):
* src/incremen.c (purge_directory):
Do not call skip_member, as the caller now does that, and does it
more reliably.
* src/extract.c (extract_file):
Mark file as skipped when we’ve read it.
(extract_archive): Always call skip_member after extracting,
as it suppresses the skip as needed.
* src/incremen.c (try_purge_directory): Remove; no longer
needed.  Move internals to purge_directory.
* src/list.c (read_header): Do not treat LNKTYPE header as having
size zero, as it can be nonzero (e.g., ‘pax -o linkdata’).
Set info->skipped field according to how the header was read.
(member_is_dir): Remove; no longer needed.
(skim_member): Skip directory data too, unless it’s already been
skipped (i.e., read).
* tests/extrac32.at: New file.
* tests/Makefile.am (TESTSUITE_AT):
* tests/testsuite.at:
Add it.
* tests/skipdir.at (skip directory members):
Fix test to match the correct behavior.
This fixes a bug introduced in commit
b009124ffd
dated 2025-05-12 17:17:21 +0300.
2026-03-22 12:23:55 -07:00
Paul Eggert
e06a880a91 build: update gnulib submodule to latest 2026-03-22 12:23:55 -07:00
Paul Eggert
a7526eb3f0 Update NEWS for previous patch 2026-03-12 12:31:55 -07:00
Marco Nenciarini
dcb8c5f932 Respect --ignore-failed-read in file_removed_diag (bug#68075)
* src/misc.c (file_removed_diag): Guard set_exit_status call
with !ignore_failed_read_option, consistent with stat_diag and
other diagnostic functions.
* tests/filerem03.at: New test.
* tests/testsuite.at: Include it.
* tests/Makefile.am: Add it.
Copyright-paperwork-exempt: yes

Signed-off-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
2026-03-12 12:31:55 -07:00
Paul Eggert
dda26d5c53 Update NEWS for previous patch 2026-03-10 09:46:42 -07:00
Weixie Cui
af552a0769 Fix wrong fd in restore_parent_fd fallback path
Use fstat(origfd) instead of fstat(parentfd) when verifying the
alternatively-opened directory; parentfd is invalid in this branch.

Copyright-paperwork-exempt: yes
2026-03-10 09:46:42 -07:00
Paul Eggert
c8f2800b9b Document timestamp resolution more accurately 2026-02-18 12:43:06 -08:00
Paul Eggert
678dbc679a tar: --one-top-level=DIR must be relative
* src/tar.c (decode_options): Require --one-top-level operand
to be relative.
2026-01-30 12:56:30 -08:00
Paul Eggert
8fca6143ea maint: pacify -Wzero-as-null-pointer-constant
Recent Gnulib enables this warning, and it did find a bug
in GNU Tar, so pacify GCC everywhere else by preferring
NULL to 0 for pointers.
2026-01-23 17:38:38 -08:00
Paul Eggert
29bb75ed65 Fix EOF return from wordsplit_finish
* lib/wordsplit.c (wordsplit_finish):
Fix typo caught by -Wzero-as-null-pointer-constant
2026-01-23 17:38:38 -08:00
Paul Eggert
bd20771003 Sync bootstrap from gnulib 2026-01-23 17:38:38 -08:00
Paul Eggert
f1efd80ebe build: update gnulib and paxutils submodules to latest
* src/extract.c: Include issymlinkat.h, not issymlink.h.
2026-01-23 17:38:38 -08:00
Paul Eggert
d55c5fd2c5 Update copyright years
UPDATE_COPYRIGHT_USE_INTERVALS=1 \
$HOME/src/gnu/gnulib/build-aux/update-copyright \
  $(git ls-files | sed -e '/^gnulib$/d
			   /^paxutils$/d
			   /^COPYING$/d
			   /\/fdl.texi$/d')
sed -i '2000,${
    /^Copyright @copyright/d
    s/^[0-9]*--\(2026 Free Software Foundation, Inc.\)/Copyright (C) \1/
  }' doc/tar.texi
2026-01-23 17:38:38 -08:00
Paul Eggert
505cf47a0a Fix commit typo when bringing back placeholders
Problem reported by Pavel Raiskup in:
https://lists.gnu.org/r/bug-tar/2025-11/msg00028.html
* src/extract.c (contains_dot_dot): Bring back this function here,
from its former location in src/names.c.  Make it static since
it is used only in this compilation unit.
2025-11-27 11:21:49 -08:00
Paul Eggert
f83a120c58 Bring back placeholders
They can still be useful if -h is used.  See Pavel Cahyna in:
https://lists.gnu.org/r/bug-tar/2025-11/msg00026.html
while we’re at it bring them back if -P is used,
as they can still be useful there too.
* src/extract.c (HAVE_BIRTHTIME, BIRTHTIME_EQ):
Bring back these macros.
(struct delayed_link, struct string_list):
Bring back these structs.
(delayed_link_table, delayed_link_head, delayed_link_tail):
Bring back these static vars.
(dl_hash, dl_compare, find_direct_ancestor)
(find_delayed_link_source, create_placeholder_file)
(apply_delayed_link, apply_delayed_links):
Bring back these static functions.
(mark_metadata_set): Rename from mark_after_links.  All uses changed.
(extract_link, extract_symlink):
Create placeholders as before, except only if -P or -h are used.
(extract_finish): Deal with delayed links, as before.
2025-11-26 20:49:38 -08:00
Paul Eggert
2bbc58bf0b Support gnulib-style timestamps in checkpoint logs
* gnulib.modules: Add nstrftime-limited, time_rz.  Sort.
* src/checkpoint.c: Include <strftime.h>.
(format_checkpoint_string): Use nstrftime instead of strftime.
Also fix an obscure bug on platforms that lack tm_gmtoff+tm_zone by
calling tzalloc on those platforms; if it fails, fall back on gmtime.
Also, use fwrite instead of fprintf, since we typically know the
length already and this gives us a more-accurate byte count
in case there are partial writes.
2025-11-23 09:51:31 -08:00
Paul Eggert
85d99f18af build: update gnulib submodule to latest 2025-11-23 09:51:31 -08:00
Paul Eggert
db65c2dd68 Port to C23 qualifier-generic fns like strchr
* src/checkpoint.c (getarg):
* src/tar.c (expand_pax_option):
Const-qualify results of strchr etc. if args are const-qualified.
2025-11-23 09:51:31 -08:00
Paul Eggert
28556dddae build: update gnulib submodule to latest 2025-11-17 16:40:18 -08:00
Paul Eggert
cdc541ad52 Prefer countof to sizeof / sizeof
C2y plans to introduce a new countof operator that will be
convenient for GNU tar, so start using it now via Gnulib.
* gnulib.modules: Add stdcountof-h.
* lib/wordsplit.c, src/buffer.c, src/suffix.c, src/tar.c:
Include stdcountof.h, and prefer countof (X) to sizeof X / sizeof *X.
2025-11-15 15:50:05 -08:00
Paul Eggert
2e243986c7 Port new extraction test to FreeBSD 15
* tests/extrac31.at (extracting untrusted incremental):
Port to FreeBSD 15 wording.
2025-11-15 15:10:48 -08:00
Paul Eggert
db9ca8d754 Port to compilers where COMMON_INLINE is static
Problem found with clang 15.0 on CheriBSD.
* src/names.c (namelist_match, register_match):
Now plain static, not static COMMON_INLINE, since the later
could mean the declaration is ‘static static’ which is not allowed.
2025-11-15 15:10:48 -08:00
Paul Eggert
b53b39209e Pacify clang 14 -Wbitwise-conditional-parentheses
* src/common.h (add_printf):
* src/sparse.c (decode_num):
Parenthesize to pacify Apple clang version 14.0.0 (clang-1400.0.29.202).
2025-11-15 15:10:48 -08:00
Paul Eggert
8d8e441bb5 Skip sparse test on non-sparse file systems
* tests/sparse05.at (listing sparse files bigger than 2^33 B):
If there were problems generating BIGFILE remove it,
as it has likely exhausted the file system.
Problem found on Darwin 21.6 APFS.
2025-11-15 15:10:48 -08:00
Paul Eggert
453d903de9 Adjust to Gnulib strftime changes for macOS
Stop using the fprintftime module, as as with recent Gnulib changes
it breaks the build on macOS, and fixing this would drag in threading
libraries and macOS-specific libraries that are overkill for tar.
Instead, just use strftime; that’s good enough here and arguably
better in case someone attacks tar with a huge time format string.
* gnulib.modules: Remove fprintftime.
* src/checkpoint.c: Do not include fprintftime.
(format_checkpoint_string): Always output some useful info (a decimal
seconds count), even if localtime fails. Do not output more than
256 bytes of time info, as that’s likely a DoS attack.  Stick with
plain strftime, as fprintftime’s extra features are overkill here.
2025-11-15 15:10:48 -08:00
Paul Eggert
0521528cdf Port intmax macro to strict C11
Needed for Apple clang version 14.0.0 (clang-1400.0.29.202).
* src/common.h (intmax): Define macro only if _Generic works, and
use _Generic in it rather that using EXPR_SIGNED.  This is needed
to make the first argument of verify_expr an integer constant
expression, which is required for strict C11.  Although GCC is
smart enough to treat (1 ? 0 : V) as an integer constant
expression even if V is an integer variable, C11 does not require
support for this sort of thing.
2025-11-15 15:10:48 -08:00
Paul Eggert
4e548d150c Port new tests to Solaris 10 strerror
* tests/extrac31.at: Adjust to Solaris 10 diagnostics.
2025-11-15 15:10:48 -08:00
Paul Eggert
50b559c3d7 Do not create empty placeholder files
* src/extract.c (HAVE_BIRTHTIME, BIRTHTIME_EQ, struct delayed_link)
(delayed_link_table, delayed_link_head delayed_link_tail)
(struct string_list, dl_hash, dl_compare, find_direct_ancestor)
(find_delayed_link_source, create_placeholder_file, apply_delayed_link)
(apply_delayed_links): Remove.  All uses removed.
(struct delayed_set_stat): New member metadata_set,
replacing after_links.  All uses changed.
(apply_nonancestor_delayed_set_stat): Arg METADATA_SET replaces
the old AFTER_LINKS.  All callers changed.
(extract_archive): Do not worry about "..", since openat2
now does that for us.
* src/names.c (first_dot_dot): Remove.  All uses removed.
2025-11-15 15:10:48 -08:00
Paul Eggert
75b03fdff4 Use openat2 to jailify the extraction directory
This addresses CVE-2025-45582.
* gnulib.modules: Add openat2.
* src/misc.c (open_subdir): New static function.
(fdbase_opendir): Use it.
* src/tar.c (open_searchdir_how): New var, replacing and
augmenting open_searchdir_flags.  All uses changed.
* tests/extrac31.at: New file.
* tests/Makefile (TESTSUITE_AT), tests/testuite.at: Add it.
2025-11-15 15:10:48 -08:00
Paul Eggert
aec5d77437 Omit trailing white space and empty lines 2025-11-15 15:10:48 -08:00
Paul Eggert
8ba9e244e8 Standardize on “working directory” 2025-11-15 15:10:48 -08:00
Paul Eggert
e1445cfdf0 Use fewer flags when opening directories
This doesn’t change behavior; it is a refactoring for
compatibility with a future patch that will use Linux’s
openat2 syscall, which is pickier about flags.
* src/tar.c (decode_options): When searching directories,
do not use O_NOCTTY, O_NONBLOCK, and O_NOATIME.
openat2 rejects all three flags if O_PATH is used.
The first two flags are definitely irrelevant for directories,
and O_NOATIME probably doesn’t matter either.
2025-11-15 15:10:48 -08:00
Paul Eggert
915a8077af Improve performance of relative opendir
* src/misc.c (fdbase_opendir): When the new directory is a
subdirectory of the old one, open relative to the old one rather
than relative all the way back to chdir_fd, and if that open fails
for a non-EMFILE reason, keep rather than discard the old directory.
2025-11-15 15:10:48 -08:00
Paul Eggert
cdb586803b Work around Oracle Developer Studio compiler bug
* src/create.c (dump_file0): Reword.
2025-11-15 15:10:48 -08:00
Paul Eggert
bdd773d028 Cache parent directories
Although this might help (or hurt) performance, the main
motivation is to make it easier in future commits
to prevent tarballs from escaping the extraction directory.
* src/common.h: (BADFD): New constant.
(struct fdbase): New type.
* src/create.c (dump_file0): Use parent->fd instead of caching
it into a local, as the latter approach is now awkward.
* src/extract.c (extract_link): Don’t save errno unless needed.
* src/misc.c (safer_rmdir): New arg F.  All callers changed.
(maybe_backup_file): Construct full after_backup_name, now
that find_backup_file_name no longer does that for us.
(chdir_fd): Now static not extern, as other modules now use fdbase.
(fdbase_cache): New static var.
(fdbase_clear): New function.  Call it whenever removing
or renaming directories or symlinks to directories.
(fdbase_opendir): New static function.
(fdbase, fdbase1): New functions.  Call them whenever the
code formerly passed chdir_fd to a syscall.
2025-11-15 15:10:48 -08:00
Paul Eggert
382a47f2fd Prefer issymlinkat
* gnulib.modules: Add issymlinkat, already an indirect dependency.
* src/extract.c: Include issymlink.h.
(is_directory_link, open_output_file):
Prefer issymlinkat to doing it by hand.
2025-11-15 15:10:48 -08:00
Paul Eggert
a109947a78 Make xclose static
* src/buffer.c (xclose): Move from here ...
* src/system.c: ... to here, and make it static.
2025-11-15 15:10:48 -08:00
Paul Eggert
8fca2d35e8 Prefer O_PATH to O_SEARCH on Linux kernels
* src/tar.c (decode_options): Prefer O_PATH to an O_SEARCH that is
actually O_RDONLY.
2025-11-15 15:10:48 -08:00
Paul Eggert
238250f19e Prefer streq/memeq when they will do
Gnulib’s new streq and memeq functions make code a bit more
readable and, we hope, a bit more reliable and easy to maintain.
* gnulib.modules: Add stringeq.
* lib/wordsplit.c (wordsplit_find_env):
* src/buffer.c (check_compressed_archive, check_tty)
(_open_archive, new_volume, try_new_volume)
(drop_volume_label_suffix):
* src/checkpoint.c (checkpoint_compile_action):
* src/compare.c (process_rawdata, diff_symlink):
* src/create.c (cachedir_file_p):
* src/delete.c (delete_archive_members):
* src/exclist.c (hg_addfn, get_vcs_ignore_file):
* src/extract.c (ds_compare, remove_delayed_set_stat)
(fixup_delayed_set_stat, apply_nonancestor_delayed_set_stat)
(extract_link):
* src/incremen.c (nfs_file_stat, compare_directory_canonical_names)
(procdir):
* src/list.c (read_header, decode_header):
* src/misc.c (replace_prefix):
* src/names.c (uname_to_uid, gname_to_gid, read_next_name)
(name_compare):
* src/sparse.c (check_data_region):
* src/suffix.c (find_compression_suffix):
* src/system.c (sys_detect_dev_null_output)
(sys_child_open_for_compress, sys_child_open_for_uncompress):
* src/tar.c (set_archive_format, tar_set_quoting_style)
(optloc_eq, set_use_compress_program_option, decode_signal)
(report_textual_dates, decode_options):
* src/update.c (update_archive):
* src/warning.c (set_warning_option):
* src/xattrs.c (xattrs_xattrs_set):
* src/xheader.c (xheader_keyword_override_p)
(xheader_set_keyword_equal, locate_handler)
(xheader_protected_keyword_p):
Prefer memeq/streq to memcmp/strcmp when either will do.
2025-11-15 15:10:48 -08:00