Several posts on Ru.Board forum address problems in TAR archives created by 7-Zip. One of such problems is that device number fields in UStar format are filled with binary zeros, while the standard expects ASCII data. The problem is caused by the following lines in COutArchive::WriteHeaderReal (TarOut.cpp):
memset(record, 0, NFileHeader::kRecordSize);
/* skipped some lines of code */
if (item.DeviceMajorDefined) RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.DeviceMajor)); cur += 8;
if (item.DeviceMinorDefined) RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.DeviceMinor)); cur += 8;
I suggest a patch for fixing that (it has already been suggested for 7-Zip-zstd). The most obvious one is to fill these fields anyway:
RETURN_IF_NOT_TRUE(WriteOctal_8(cur,item.DeviceMajorDefined ? item.DeviceMajor : 0)); cur += 8;
RETURN_IF_NOT_TRUE(WriteOctal_8(cur,item.DeviceMinorDefined ? item.DeviceMinor : 0)); cur += 8;
The operator ?: can also be rewritten as follows:
(item.DeviceMinorDefined ? ~0 : 0) & item.DeviceMinor
which has an efficient x86 assembly implementation with SBB.
Maybe the filling can be specified differently instead:
memset(record, 0, NFileHeader::kNameSize);
memset(record, '0', NFileHeader::kRecordSize-NFileHeader::kNameSize);
/* do the job */
memset(record, 0, NFileHeader::kRecordSize-(cur-record));
RINOK(WriteBytes(record, NFileHeader::kRecordSize));
when I call
tar
in ubuntu linux with the command:It also writes binary zeros to these fields.
So 7-Zip is consistent with
tar
program for these fields.Last edit: Igor Pavlov 2021-05-16