From 307a7e8975257b3750b776fb367dc4e33d8b9d9d Mon Sep 17 00:00:00 2001 From: Timofey Solomko Date: Sun, 30 Apr 2017 20:33:38 +0300 Subject: [PATCH] Added check for CRC32 in bzip2 archives. --- Sources/BZip2.swift | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Sources/BZip2.swift b/Sources/BZip2.swift index 88520cd4..05ae161e 100644 --- a/Sources/BZip2.swift +++ b/Sources/BZip2.swift @@ -41,6 +41,11 @@ public enum BZip2Error: Error { case WrongHuffmanLengthCode /// Symbol was not found in Huffman tree. case SymbolNotFound + /** + Computed CRC of uncompressed data didn't match the value stored in the archive. + Associated value contains already decompressed data. + */ + case WrongCRC(Data) } /// Provides function to decompress data, which were compressed using BZip2. @@ -60,7 +65,7 @@ public final class BZip2: DecompressionAlgorithm { */ public static func decompress(compressedData data: Data) throws -> Data { /// An array for storing output data - var out: [UInt8] = [] + var out = Data() /// Object with input data which supports convenient work with bit shifts. var pointerData = DataWithPointer(data: data, bitOrder: .straight) @@ -82,18 +87,21 @@ public final class BZip2: DecompressionAlgorithm { let blockType: Int64 = Int64(pointerData.intFromBits(count: 48)) // TODO: Add CRC check. // Next 32 bits are crc (which currently is not checked). - _ = pointerData.intFromBits(count: 32) + let blockCRC32 = UInt32(truncatingBitPattern: pointerData.intFromBits(count: 32)) if blockType == 0x314159265359 { - try out.append(contentsOf: decode(data: &pointerData)) + let blockData = Data(bytes: try decode(data: &pointerData)) + guard CheckSums.bzip2CRC32(blockData) == blockCRC32 else { throw BZip2Error.WrongCRC(out) } + out.append(blockData) } else if blockType == 0x177245385090 { + guard CheckSums.bzip2CRC32(out) == blockCRC32 else { throw BZip2Error.WrongCRC(out) } break } else { throw BZip2Error.WrongBlockType } } - return Data(bytes: out) + return out } private static func decode(data: inout DataWithPointer) throws -> [UInt8] {