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.
This commit is contained in:
Timofey Solomko
2017-07-09 13:29:33 +03:00
parent 9a4e1d6219
commit a9cdb50e85
12 changed files with 65 additions and 79 deletions
-5
View File
@@ -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)
+5 -5
View File
@@ -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..<array.count {
s1 = (s1 + array[i].toInt()) % base
s1 = (s1 + UInt32(array[i])) % base
s2 = (s2 + s1) % base
}
return (s2 << 16) + s1
-9
View File
@@ -42,15 +42,6 @@ class DataWithPointer {
return result
}
func intFromAlignedBytes(count: Int) -> Int {
var result = 0
for i in 0..<count {
result |= self.data[self.index].toInt() << (8 * i)
self.index += 1
}
return result
}
func uint64(count: UInt64 = 8) -> UInt64 {
precondition(count <= 8, "UInt64 cannot store more than 8 bytes of data!")
var result: UInt64 = 0
+2 -2
View File
@@ -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)
}
+9 -5
View File
@@ -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..<xlen {
headerBytes.append(pointerData.byte())
+2 -2
View File
@@ -204,11 +204,11 @@ class LZMADecoder {
func decodeLZMA(_ externalUncompressedSize: Int? = nil) throws {
// Firstly, we need to parse LZMA properties.
try self.resetProperties()
let dictSize = pointerData.intFromAlignedBytes(count: 4)
let dictSize = pointerData.uint32().toInt()
dictionarySize = dictSize < (1 << 12) ? 1 << 12 : dictSize
/// Size of uncompressed data. -1 means it is unknown/undefined.
var uncompressedSize = pointerData.intFromAlignedBytes(count: 8)
var uncompressedSize = pointerData.uint64().toInt()
uncompressedSize = Double(uncompressedSize) == pow(Double(2), Double(64)) - 1 ? -1 : uncompressedSize
if let extUncompSize = externalUncompressedSize {
+1 -1
View File
@@ -358,7 +358,7 @@ public class XZArchive: Archive {
else { throw XZError.fieldReservedValue }
// Check footer's magic number
guard pointerData.intFromAlignedBytes(count: 2) == 0x5A59
guard pointerData.bytes(count: 2) == [0x59, 0x5A]
else { throw XZError.wrongMagic }
}
+21 -23
View File
@@ -7,12 +7,12 @@ import Foundation
struct ZipCentralDirectoryEntry {
let versionMadeBy: Int
let versionNeeded: Int
let generalPurposeBitFlags: Int
let compressionMethod: Int
let lastModFileTime: Int
let lastModFileDate: Int
let versionMadeBy: UInt16
let versionNeeded: UInt16
let generalPurposeBitFlags: UInt16
let compressionMethod: UInt16
let lastModFileTime: UInt16
let lastModFileDate: UInt16
let crc32: UInt32
private(set) var compSize: UInt64
private(set) var uncompSize: UInt64
@@ -22,40 +22,40 @@ struct ZipCentralDirectoryEntry {
private(set) var diskNumberStart: UInt32
let internalFileAttributes: Int
let internalFileAttributes: UInt16
let externalFileAttributes: UInt32
private(set) var offset: UInt64
private(set) var modificationTimestamp: Int?
private(set) var modificationTimestamp: UInt32?
init(_ pointerData: DataWithPointer, _ currentDiskNumber: UInt32) throws {
// Check signature.
guard pointerData.uint32() == 0x02014b50
else { throw ZipError.wrongSignature }
self.versionMadeBy = pointerData.intFromAlignedBytes(count: 2)
self.versionNeeded = pointerData.intFromAlignedBytes(count: 2)
self.versionMadeBy = pointerData.uint16()
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 fileCommentLength = pointerData.intFromAlignedBytes(count: 2)
let fileNameLength = pointerData.uint16().toInt()
let extraFieldLength = pointerData.uint16().toInt()
let fileCommentLength = pointerData.uint16().toInt()
self.diskNumberStart = pointerData.uint32(count: 2)
self.internalFileAttributes = pointerData.intFromAlignedBytes(count: 2)
self.internalFileAttributes = pointerData.uint16()
self.externalFileAttributes = pointerData.uint32()
self.offset = pointerData.uint64(count: 4)
@@ -68,10 +68,8 @@ struct ZipCentralDirectoryEntry {
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: // Zip64
if self.uncompSize == 0xFFFFFFFF {
@@ -90,7 +88,7 @@ struct ZipCentralDirectoryEntry {
let flags = pointerData.byte()
guard flags & 0xF8 == 0 else { break }
if flags & 0x01 != 0 {
self.modificationTimestamp = pointerData.intFromAlignedBytes(count: 4)
self.modificationTimestamp = pointerData.uint32()
}
default:
pointerData.index += size
+1 -1
View File
@@ -39,7 +39,7 @@ struct ZipEndOfCentralDirectory {
// There is also a .ZIP file comment, but we don't need it.
// Here's how it can be processed:
// let zipCommentLength = pointerData.intFromAlignedBytes(count: 2)
// let zipCommentLength = pointerData.uint16().toInt()
// let zipComment = String(data: Data(bytes: pointerData.bytes(count: zipCommentLength)),
// encoding: .utf8)
+2 -2
View File
@@ -159,13 +159,13 @@ public class ZipEntry: ContainerEntry {
var attributesDict = [FileAttributeKey: Any]()
// Modification time
let dosDate = cdEntry.lastModFileDate
let dosDate = cdEntry.lastModFileDate.toInt()
let day = dosDate & 0x1F
let month = (dosDate & 0x1E0) >> 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
+21 -23
View File
@@ -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
+1 -1
View File
@@ -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)