[ZIP] Replace stored local header and cd entry in ZipEntryInfo with separate actually required properties

This commit is contained in:
Timofey Solomko
2018-08-13 11:38:42 +03:00
parent ffd47c3528
commit c9115f367b
2 changed files with 24 additions and 19 deletions
+8 -12
View File
@@ -57,17 +57,13 @@ public class ZipContainer: Container {
}
private static func getEntryData(from data: Data, using info: ZipEntryInfo) throws -> (data: Data, crcError: Bool) {
let hasDataDescriptor = info.localHeader.generalPurposeBitFlags & 0x08 != 0
// If file has data descriptor, then some values in local header are absent.
// So we need to use values from CD entry.
var uncompSize = hasDataDescriptor ? info.cdEntry.uncompSize : info.localHeader.uncompSize
var compSize = hasDataDescriptor ? info.cdEntry.compSize : info.localHeader.compSize
var crc32 = hasDataDescriptor ? info.cdEntry.crc32 : info.localHeader.crc32
var uncompSize = info.uncompSize
var compSize = info.compSize
var crc32 = info.crc
let fileData: Data
let byteReader = ByteReader(data: data)
byteReader.offset = info.localHeader.dataOffset
byteReader.offset = info.dataOffset
switch info.compressionMethod {
case .copy:
fileData = Data(bytes: byteReader.bytes(count: uncompSize.toInt()))
@@ -100,9 +96,9 @@ public class ZipContainer: Container {
default:
throw ZipError.compressionNotSupported
}
let realCompSize = byteReader.offset - info.localHeader.dataOffset
let realCompSize = byteReader.offset - info.dataOffset
if hasDataDescriptor {
if info.hasDataDescriptor {
// Now we need to parse data descriptor itself.
// First, it might or might not have signature.
let ddSignature = byteReader.uint32()
@@ -111,7 +107,7 @@ public class ZipContainer: Container {
}
// Now, let's update with values from data descriptor.
crc32 = byteReader.uint32()
if info.localHeader.zip64FieldsArePresent {
if info.zip64FieldsArePresent {
compSize = byteReader.uint64()
uncompSize = byteReader.uint64()
} else {
@@ -175,7 +171,7 @@ public class ZipContainer: Container {
let info = try ZipEntryInfo(byteReader, endOfCD.currentDiskNumber)
entries.append(info)
// Move to the next Central Directory entry.
byteReader.offset = info.cdEntry.nextEntryOffset
byteReader.offset = info.nextCdEntryOffset
}
return entries
+16 -7
View File
@@ -102,20 +102,22 @@ public struct ZipEntryInfo: ContainerEntryInfo {
/// CRC32 of entry's data.
public let crc: UInt32
let cdEntry: ZipCentralDirectoryEntry
let localHeader: ZipLocalHeader
let hasDataDescriptor: Bool
let zip64FieldsArePresent: Bool
let nextCdEntryOffset: Int
let dataOffset: Int
let compSize: UInt64
let uncompSize: UInt64
init(_ byteReader: ByteReader, _ currentDiskNumber: UInt32) throws {
// Load and save Central Directory entry.
// Read Central Directory entry.
let cdEntry = try ZipCentralDirectoryEntry(byteReader)
self.cdEntry = cdEntry
// Move to the location of Local Header.
byteReader.offset = cdEntry.localHeaderOffset.toInt()
// Load and save Local Header.
// Read Local Header.
let localHeader = try ZipLocalHeader(byteReader)
try localHeader.validate(with: cdEntry, currentDiskNumber)
self.localHeader = localHeader
// If file has data descriptor, then some properties are only present in CD entry.
self.hasDataDescriptor = localHeader.generalPurposeBitFlags & 0x08 != 0
@@ -172,7 +174,7 @@ public struct ZipEntryInfo: ContainerEntryInfo {
}
// Size
self.size = cdEntry.uncompSize.toInt()
self.size = (hasDataDescriptor ? cdEntry.uncompSize : localHeader.uncompSize).toInt()
// External file attributes.
self.externalFileAttributes = cdEntry.externalFileAttributes
@@ -206,6 +208,13 @@ public struct ZipEntryInfo: ContainerEntryInfo {
var customExtraFields = cdEntry.customExtraFields
customExtraFields.append(contentsOf: localHeader.customExtraFields)
self.customExtraFields = customExtraFields
// Save some properties from CD entry and Local Header.
self.zip64FieldsArePresent = localHeader.zip64FieldsArePresent
self.nextCdEntryOffset = cdEntry.nextEntryOffset
self.dataOffset = localHeader.dataOffset
self.compSize = hasDataDescriptor ? cdEntry.compSize : localHeader.compSize
self.uncompSize = hasDataDescriptor ? cdEntry.uncompSize : localHeader.uncompSize
}
}