From a9cdb50e85703fd09257592c2806afc499d22ff4 Mon Sep 17 00:00:00 2001 From: Timofey Solomko Date: Sun, 9 Jul 2017 13:29:33 +0300 Subject: [PATCH] Remove intFromAlignedBytes function Also changes were made to adopt this removal. This was done to improve behavior in some corner cases as well as enforce intentional usage of particular integer types. --- Sources/BitReader.swift | 5 --- Sources/CheckSums.swift | 10 +++--- Sources/DataWithPointer.swift | 9 ------ Sources/GzipArchive.swift | 4 +-- Sources/GzipHeader.swift | 14 +++++--- Sources/LZMADecoder.swift | 4 +-- Sources/XZArchive.swift | 2 +- Sources/ZipCentralDirectoryEntry.swift | 44 ++++++++++++-------------- Sources/ZipEndOfCentralDirectory.swift | 2 +- Sources/ZipEntry.swift | 4 +-- Sources/ZipLocalHeader.swift | 44 ++++++++++++-------------- Sources/ZlibArchive.swift | 2 +- 12 files changed, 65 insertions(+), 79 deletions(-) diff --git a/Sources/BitReader.swift b/Sources/BitReader.swift index b5baa04a..987f0953 100644 --- a/Sources/BitReader.swift +++ b/Sources/BitReader.swift @@ -148,11 +148,6 @@ class BitReader: DataWithPointer { return super.bytes(count: count) } - override func intFromAlignedBytes(count: Int) -> Int { - self.skipUntilNextByte() - return super.intFromAlignedBytes(count: count) - } - override func uint64(count: UInt64 = 8) -> UInt64 { self.skipUntilNextByte() return super.uint64(count: count) diff --git a/Sources/CheckSums.swift b/Sources/CheckSums.swift index 9b35f120..99867391 100644 --- a/Sources/CheckSums.swift +++ b/Sources/CheckSums.swift @@ -45,12 +45,12 @@ struct CheckSums { return ~crc } - static func adler32(_ array: [UInt8]) -> Int { - let base = 65521 - var s1 = 1 - var s2 = 0 + static func adler32(_ array: [UInt8]) -> UInt32 { + let base: UInt32 = 65521 + var s1: UInt32 = 1 + var s2: UInt32 = 0 for i in 0.. Int { - var result = 0 - for i in 0.. UInt64 { precondition(count <= 8, "UInt64 cannot store more than 8 bytes of data!") var result: UInt64 = 0 diff --git a/Sources/GzipArchive.swift b/Sources/GzipArchive.swift index 07f5fe46..50587a09 100644 --- a/Sources/GzipArchive.swift +++ b/Sources/GzipArchive.swift @@ -80,8 +80,8 @@ public class GzipArchive: Archive { let crc32 = bitReader.uint32() guard CheckSums.crc32(memberData) == crc32 else { throw GzipError.wrongCRC(memberData) } - let isize = bitReader.intFromAlignedBytes(count: 4) - guard UInt64(memberData.count) % UInt64(1) << 32 == UInt64(isize) else { throw GzipError.wrongISize } + let isize = bitReader.uint64(count: 4) + guard UInt64(memberData.count) % (UInt64(1) << 32) == isize else { throw GzipError.wrongISize } return Member(header: header, data: memberData) } diff --git a/Sources/GzipHeader.swift b/Sources/GzipHeader.swift index cab3d161..56f6c5a7 100644 --- a/Sources/GzipHeader.swift +++ b/Sources/GzipHeader.swift @@ -79,7 +79,7 @@ public struct GzipHeader { init(_ pointerData: DataWithPointer) throws { // First two bytes should be correct 'magic' bytes - let magic = pointerData.intFromAlignedBytes(count: 2) + let magic = pointerData.uint16() guard magic == 0x8b1f else { throw GzipError.wrongMagic } var headerBytes: [UInt8] = [0x1f, 0x8b] @@ -94,9 +94,11 @@ public struct GzipHeader { guard (flags & 0x20 == 0) && (flags & 0x40 == 0) && (flags & 0x80 == 0) else { throw GzipError.wrongFlags } headerBytes.append(flags) - let mtime = pointerData.intFromAlignedBytes(count: 4) + var mtime = 0 for i in 0..<4 { - headerBytes.append(((mtime & (0xFF << (i * 8))) >> (i * 8)).toUInt8()) + let byte = pointerData.byte() + mtime |= byte.toInt() << (8 * i) + headerBytes.append(byte) } self.modificationTime = mtime == 0 ? nil : Date(timeIntervalSince1970: TimeInterval(mtime)) @@ -110,9 +112,11 @@ public struct GzipHeader { // Some archives may contain extra fields if flags & Flags.fextra != 0 { - let xlen = pointerData.intFromAlignedBytes(count: 2) + var xlen = 0 for i in 0..<2 { - headerBytes.append(((xlen & (0xFF << (i * 8))) >> (i * 8)).toUInt8()) + let byte = pointerData.byte() + xlen |= byte.toInt() << (8 * i) + headerBytes.append(byte) } for _ in 0..> 5 let year = 1980 + ((dosDate & 0xFE00) >> 9) - let dosTime = cdEntry.lastModFileTime + let dosTime = cdEntry.lastModFileTime.toInt() let seconds = 2 * (dosTime & 0x1F) let minutes = (dosTime & 0x7E0) >> 5 diff --git a/Sources/ZipLocalHeader.swift b/Sources/ZipLocalHeader.swift index dab01a91..1aab9c75 100644 --- a/Sources/ZipLocalHeader.swift +++ b/Sources/ZipLocalHeader.swift @@ -7,11 +7,11 @@ import Foundation struct ZipLocalHeader { - let versionNeeded: Int - let generalPurposeBitFlags: Int - let compressionMethod: Int - let lastModFileTime: Int - let lastModFileDate: Int + let versionNeeded: UInt16 + let generalPurposeBitFlags: UInt16 + let compressionMethod: UInt16 + let lastModFileTime: UInt16 + let lastModFileDate: UInt16 let crc32: UInt32 private(set) var compSize: UInt64 @@ -21,31 +21,31 @@ struct ZipLocalHeader { let fileName: String - private(set) var modificationTimestamp: Int? - private(set) var accessTimestamp: Int? - private(set) var creationTimestamp: Int? + private(set) var modificationTimestamp: UInt32? + private(set) var accessTimestamp: UInt32? + private(set) var creationTimestamp: UInt32? init(_ pointerData: DataWithPointer) throws { // Check signature. guard pointerData.uint32() == 0x04034b50 else { throw ZipError.wrongSignature } - self.versionNeeded = pointerData.intFromAlignedBytes(count: 2) + self.versionNeeded = pointerData.uint16() - self.generalPurposeBitFlags = pointerData.intFromAlignedBytes(count: 2) + self.generalPurposeBitFlags = pointerData.uint16() - self.compressionMethod = pointerData.intFromAlignedBytes(count: 2) + self.compressionMethod = pointerData.uint16() - self.lastModFileTime = pointerData.intFromAlignedBytes(count: 2) - self.lastModFileDate = pointerData.intFromAlignedBytes(count: 2) + self.lastModFileTime = pointerData.uint16() + self.lastModFileDate = pointerData.uint16() self.crc32 = pointerData.uint32() self.compSize = pointerData.uint64(count: 4) self.uncompSize = pointerData.uint64(count: 4) - let fileNameLength = pointerData.intFromAlignedBytes(count: 2) - let extraFieldLength = pointerData.intFromAlignedBytes(count: 2) + let fileNameLength = pointerData.uint16().toInt() + let extraFieldLength = pointerData.uint16().toInt() guard let fileName = String(data: Data(bytes: pointerData.bytes(count: fileNameLength)), encoding: .utf8) @@ -55,12 +55,10 @@ struct ZipLocalHeader { let extraFieldStart = pointerData.index while pointerData.index - extraFieldStart < extraFieldLength { // There are a lot of possible extra fields. - // But we are (currently) only interested in Zip64 related fields (with headerID = 0x0001), - // because they directly impact further extraction process. - let headerID = pointerData.intFromAlignedBytes(count: 2) - let size = pointerData.intFromAlignedBytes(count: 2) + let headerID = pointerData.uint16() + let size = pointerData.uint16().toInt() switch headerID { - case 0x0001: + case 0x0001: // Zip64 // In local header both uncompressed size and compressed size fields are required. self.uncompSize = pointerData.uint64() self.compSize = pointerData.uint64() @@ -70,13 +68,13 @@ struct ZipLocalHeader { let flags = pointerData.byte() guard flags & 0xF8 == 0 else { break } if flags & 0x01 != 0 { - self.modificationTimestamp = pointerData.intFromAlignedBytes(count: 4) + self.modificationTimestamp = pointerData.uint32() } if flags & 0x02 != 0 { - self.accessTimestamp = pointerData.intFromAlignedBytes(count: 4) + self.accessTimestamp = pointerData.uint32() } if flags & 0x04 != 0 { - self.creationTimestamp = pointerData.intFromAlignedBytes(count: 4) + self.creationTimestamp = pointerData.uint32() } default: pointerData.index += size diff --git a/Sources/ZlibArchive.swift b/Sources/ZlibArchive.swift index 5ecd595c..0310a7b2 100644 --- a/Sources/ZlibArchive.swift +++ b/Sources/ZlibArchive.swift @@ -33,7 +33,7 @@ public class ZlibArchive: Archive { let out = try Deflate.decompress(bitReader) - let adler32 = bitReader.intFromAlignedBytes(count: 4).reverseBytes() + let adler32 = bitReader.uint32().reverseBytes() guard CheckSums.adler32(out) == adler32 else { throw ZlibError.wrongAdler32(Data(bytes: out)) } return Data(bytes: out)