Hello! While backporting the upstream commit a5afb367 to Meta's internal version of tar, an LLM reviewer detected a bug in the fixup_delayed_set_stat function in src/extract.c. I've confirmed this bug is real, and I have established a reproducible test case at the end of this email.
The function fixup_delayed_set_stat changes the file_name of a delayed_set_stat record. The hash table delayed_set_stat_table uses the file_name as its key. The function does not remove the record from the table before it changes the name, so lookups for the new name will fail and cause a new record to be created. At the same time, the data->file_name of the previous record is updated to the new file_name. The function apply_nonancestor_delayed_set_stat processes the records in reverse order of insertion, so it applies the new metadata first and old metadata last. Since the record is not removed upon renaming, the old metadata is applied after the new metadata, which leads to stale file attributes from the original pre-rename dump. Affected versions: Released version 1.35 does show the correct mtime of dir2, so this bug was introduced after the release. This bug was reproduced on the latest master revision d1df7f40. Potential cause of bug: Commit a5afb367 replaced a linear search of delay_set_stat_head with a hash table to avoid O(n^2) lookups. That commit updated delay_set_stat, remove_delayed_set_stat, apply_nonancestor_delayed_set_stat, and extract_finish, but it did not update fixup_delayed_set_stat. Test procedure (in repo root after building with the latest master revision): Create an empty directory with an old mtime and make a tar of it: 1. mkdir -p data/dir 2. echo "hello" > data/dir/file 3. touch -d "2000-01-01 00:00" data/dir 4. ./build/src/tar -cf full.tar -g snap -C data . Move the directory, touch it to update mtime, and make an incremental: 1. mv data/dir data/dir2 2. touch -d "2026-01-01 00:00" data/dir2 3 ./build/src/tar -cf inc.tar -g snap -C data . Concatenate the archives and extract them: 1. mkdir out 2. ./build/src/tar -Af full.tar inc.tar 3. ./build/src/tar -xf full.tar -g snap -C out 4. ls -ld out/dir2 Expected result: Timestamp of dir2 should be 2026-01-01 00:00 after extraction. Actual result: Timestamp of dir2 is 2000-01-01 00:00.
