When an entry name is longer than the 100 byte USTAR name field,
TarHeader splits it into the 155 byte prefix field and the name field
at a directory separator. The existing tests only covered short paths
and long names without any separator.
Add sync and async tests that write a 186 byte path (with '/' and
'\' separators as input) using the USTAR format and read it back.
On Windows these tests fail with InvalidFormatException ("Directory
separator not found!"), which the next commit fixes. They pass on
Linux and macOS.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An LZMA2 chunk header properties byte of 225 or more cannot occur in
valid data, but it reached Decoder.SetDecoderProperties and surfaced as
InvalidParamException. EncryptedDecoderStream only maps DataErrorException
to CryptographicException, so a wrong 7z password occasionally leaked the
internal codec exception, making
SevenZipWriter_Encrypted_WrongPasswordFails flaky.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SevenZipWriterOptions gains Password and EncryptHeader (#1472). With a
password, each folder is written as 7zAES -> LZMA/LZMA2 in the same
layout 7-Zip uses: AES is coder 0 and reads the packed stream, the
codec is coder 1 and reads AES's output. AES properties match 7-Zip's
defaults (NumCyclesPower 19, no salt, random 16-byte IV per folder), so
the key is derived once per archive. EncryptHeader runs the header
through the same chain; an encrypted header is always LZMA-compressed.
Empty files have no stream and stay unencrypted, as in 7-Zip.
- SevenZipAesKey: the 7zAES KDF, moved unchanged from AesDecoderStream
so the encoder and decoder share it.
- AesEncoderStream: AES-256-CBC, zero-fills the last block on Finish.
- SevenZipAesEncryption: per-archive key and per-folder IV/properties.
- EncryptHeader without a password, or an empty password, throws
ArgumentException.
Uses only Aes (CBC) and SHA256, available on every target framework and
Native AOT safe. Verified with 7-Zip 26.05 (7z t, 7z x, 7z l -slt) and
WinRAR for LZMA and LZMA2, with and without header encryption.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7-Zip writes 7zAES as the first coder of an encrypted folder, in front
of the codec. SevenZipFilePart.GetCompression() looked at the first
coder only, so CompressionType threw InvalidFormatException for every
entry of a 7-Zip-made encrypted archive. Skip the AES filter and report
the first real coder.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7-Zip writes 7zAES as the first coder of an encrypted folder, in front
of the codec. SevenZipFilePart.GetCompression() looked at the first
coder only, so CompressionType threw InvalidFormatException for every
entry of a 7-Zip-made encrypted archive. Skip the AES filter and report
the first real coder.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>