ZipFile constructor
ZipFile([
- InputStreamBase? input,
- ZipFileHeader? header,
- String? password
Implementation
ZipFile([InputStreamBase? input, this.header, String? password]) {
if (input != null) {
signature = input.readUint32();
if (signature != zipFileSignature) {
throw ArchiveException('Invalid Zip Signature');
}
version = input.readUint16();
flags = input.readUint16();
compressionMethod = input.readUint16();
lastModFileTime = input.readUint16();
lastModFileDate = input.readUint16();
crc32 = input.readUint32();
compressedSize = input.readUint32();
uncompressedSize = input.readUint32();
final fnLen = input.readUint16();
final exLen = input.readUint16();
filename = input.readString(size: fnLen);
extraField = input.readBytes(exLen).toUint8List();
// Use the compressedSize and uncompressedSize from the CFD header.
// For Zip64, the sizes in the local header will be 0xFFFFFFFF.
compressedSize = header?.compressedSize ?? compressedSize;
uncompressedSize = header?.uncompressedSize ?? uncompressedSize;
_encryptionType =
(flags & 0x1) != 0 ? encryptionZipCrypto : encryptionNone;
_password = password;
// Read compressedSize bytes for the compressed data.
_rawContent = input.readBytes(header!.compressedSize!);
if (_encryptionType != 0 && exLen > 2) {
final extra = InputStream(extraField);
while (!extra.isEOS) {
final id = extra.readUint16();
final size = extra.readUint16();
final extraBytes = extra.readBytes(size);
if (id == AesHeader.signature) {
final vendorVersion = extraBytes.readUint16();
final vendorId = extraBytes.readString(size: 2);
final encryptionStrength = extraBytes.readByte();
final compressionMethod = extraBytes.readUint16();
_encryptionType = encryptionAes;
_aesHeader = AesHeader(
vendorVersion, vendorId, encryptionStrength, compressionMethod);
// compressionMethod in the file header will be 99 for aes encrypted
// files. The compressionMethod value in the AES extraField stores
// the actual compressionMethod.
this.compressionMethod = _aesHeader!.compressionMethod;
}
}
}
if (_encryptionType == 1 && password != null) {
_initKeys(password);
}
// If bit 3 (0x08) of the flags field is set, then the CRC-32 and file
// sizes are not known when the header is written. The fields in the
// local header are filled with zero, and the CRC-32 and size are
// appended in a 12-byte structure (optionally preceded by a 4-byte
// signature) immediately after the compressed data:
if (flags & 0x08 != 0) {
final sigOrCrc = input.readUint32();
if (sigOrCrc == 0x08074b50) {
crc32 = input.readUint32();
} else {
crc32 = sigOrCrc;
}
compressedSize = input.readUint32();
uncompressedSize = input.readUint32();
}
}
// Make sure to use the Central Directory filename to avoid filename
// spoofing. https://github.com/brendan-duncan/archive/issues/266
filename = header?.filename ?? filename;
}