diff --git a/.jazzy.yaml b/.jazzy.yaml
index 0b6549cb..6fa59613 100644
--- a/.jazzy.yaml
+++ b/.jazzy.yaml
@@ -3,11 +3,11 @@ sourcekitten_sourcefile: docs.json
clean: true
author: Timofey Solomko
module: SWCompression
-module_version: 4.5.6
+module_version: 4.5.7
copyright: '© 2020 Timofey Solomko'
readme: README.md
github_url: https://github.com/tsolomko/SWCompression
-github_file_prefix: https://github.com/tsolomko/SWCompression/tree/4.5.6
+github_file_prefix: https://github.com/tsolomko/SWCompression/tree/4.5.7
theme: fullwidth
custom_categories:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fae75d4a..269a0fd7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,16 @@
# Changelog
+## 4.5.7
+
+- Fixed a crash when trying to open a very small file as a 7-Zip container, a BZip2 "archive", a GZip archive (both when
+ using `unarchive` and `multiUnarchive`), a LZMA "archive", a XZ archive (both when using `unarchive` and `splitUnarchive`),
+ a ZIP container, or a Zlib archive.
+- Fixed a crash when trying to open an unexpectedly truncated file as a GZip or XZ archive.
+- Fixed a crash when trying to open an invalid file as a ZIP container. The `ZipError.notFoundCentralDirectoryEnd` error
+ is now thrown instead as was originally intended.
+- Fixed a crash when trying to read a GZip or Zlib header from a very small file.
+- Fixed a compilation warning in BZip2.
+
## 4.5.6
- Fixed a compiling issue on Linux with Swift 5.3.
diff --git a/SWCompression.podspec b/SWCompression.podspec
index 8d3a1fe9..f9c3caf0 100644
--- a/SWCompression.podspec
+++ b/SWCompression.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "SWCompression"
- s.version = "4.5.6"
+ s.version = "4.5.7"
s.summary = "A framework with functions for working with compression, archives and containers."
s.description = "A framework with (de)compression algorithms and functions for processing various archives and containers."
diff --git a/SWCompression.xcodeproj/SWCompression.plist b/SWCompression.xcodeproj/SWCompression.plist
index 518b2856..46a41309 100644
--- a/SWCompression.xcodeproj/SWCompression.plist
+++ b/SWCompression.xcodeproj/SWCompression.plist
@@ -15,9 +15,9 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 4.5.6
+ 4.5.7
CFBundleVersion
- 73
+ 74
NSHumanReadableCopyright
Copyright © 2020 Timofey Solomko. All rights reserved.
diff --git a/SWCompression.xcodeproj/TestSWCompression.plist b/SWCompression.xcodeproj/TestSWCompression.plist
index 46874253..a8ecec80 100644
--- a/SWCompression.xcodeproj/TestSWCompression.plist
+++ b/SWCompression.xcodeproj/TestSWCompression.plist
@@ -15,8 +15,8 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 4.5.6
+ 4.5.7
CFBundleVersion
- 73
+ 74
diff --git a/SWCompression.xcodeproj/project.pbxproj b/SWCompression.xcodeproj/project.pbxproj
index aee91300..da0e0662 100644
--- a/SWCompression.xcodeproj/project.pbxproj
+++ b/SWCompression.xcodeproj/project.pbxproj
@@ -213,6 +213,8 @@
06F066771FFB763400312A82 /* test8.bz2 in Resources */ = {isa = PBXBuildFile; fileRef = 06F066111FFB763300312A82 /* test8.bz2 */; };
06F276DF1F2BAB4A00E67335 /* 7zEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F276DE1F2BAB4900E67335 /* 7zEntry.swift */; };
06FEAD921F54B9CD00AD016E /* EncodingTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06FEAD911F54B9CD00AD016E /* EncodingTree.swift */; };
+ E66F36242538726E00076A6E /* test_empty.lzma in Resources */ = {isa = PBXBuildFile; fileRef = E66F36232538726E00076A6E /* test_empty.lzma */; };
+ E66F362C2538E2B700076A6E /* test_empty.zlib in Resources */ = {isa = PBXBuildFile; fileRef = E66F362B2538E2B700076A6E /* test_empty.zlib */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -433,6 +435,8 @@
06F276DE1F2BAB4900E67335 /* 7zEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 7zEntry.swift; sourceTree = ""; };
06FEAD911F54B9CD00AD016E /* EncodingTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EncodingTree.swift; path = Sources/Common/CodingTree/EncodingTree.swift; sourceTree = SOURCE_ROOT; };
06FED40B1DD7717E0013DFB2 /* BZip2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BZip2.swift; sourceTree = ""; };
+ E66F36232538726E00076A6E /* test_empty.lzma */ = {isa = PBXFileReference; lastKnownFileType = file; path = test_empty.lzma; sourceTree = ""; };
+ E66F362B2538E2B700076A6E /* test_empty.zlib */ = {isa = PBXFileReference; lastKnownFileType = file; path = test_empty.zlib; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -745,6 +749,7 @@
children = (
06F065C41FFB763300312A82 /* test.zlib */,
06F065C51FFB763300312A82 /* random_file.zlib */,
+ E66F362B2538E2B700076A6E /* test_empty.zlib */,
);
path = Zlib;
sourceTree = "";
@@ -838,6 +843,7 @@
06F065F41FFB763300312A82 /* test9.lzma */,
06F065F31FFB763300312A82 /* test10.lzma */,
06F065F21FFB763300312A82 /* test11.lzma */,
+ E66F36232538726E00076A6E /* test_empty.lzma */,
);
path = LZMA;
sourceTree = "";
@@ -1032,9 +1038,11 @@
06F066391FFB763400312A82 /* test8.xz in Resources */,
06F0662F1FFB763400312A82 /* test9.gz in Resources */,
064DF453245618A300D285F3 /* bad_cd_ext_ts.zip in Resources */,
+ E66F36242538726E00076A6E /* test_empty.lzma in Resources */,
06F066751FFB763400312A82 /* test1.bz2 in Resources */,
064D01A920FD071300CAE058 /* текстовый файл.answer in Resources */,
06F0662D1FFB763400312A82 /* test6.gz in Resources */,
+ E66F362C2538E2B700076A6E /* test_empty.zlib in Resources */,
06F0664D1FFB763400312A82 /* test_ustar.tar in Resources */,
06F0665A1FFB763400312A82 /* test11.lzma in Resources */,
06F066401FFB763400312A82 /* test_zip_bzip2.zip in Resources */,
@@ -1241,7 +1249,7 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CURRENT_PROJECT_VERSION = 73;
+ CURRENT_PROJECT_VERSION = 74;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@@ -1300,7 +1308,7 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CURRENT_PROJECT_VERSION = 73;
+ CURRENT_PROJECT_VERSION = 74;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
"FRAMEWORK_SEARCH_PATHS[sdk=appletvos*]" = "\"$(SRCROOT)/Carthage/Build/tvOS\"";
@@ -1340,7 +1348,7 @@
APPLICATION_EXTENSION_API_ONLY = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 73;
+ DYLIB_CURRENT_VERSION = 74;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = SWCompression.xcodeproj/SWCompression.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@@ -1367,7 +1375,7 @@
APPLICATION_EXTENSION_API_ONLY = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 73;
+ DYLIB_CURRENT_VERSION = 74;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = SWCompression.xcodeproj/SWCompression.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
diff --git a/Sources/7-Zip/7zContainer.swift b/Sources/7-Zip/7zContainer.swift
index c0c3e4f9..d9fa1794 100644
--- a/Sources/7-Zip/7zContainer.swift
+++ b/Sources/7-Zip/7zContainer.swift
@@ -202,6 +202,10 @@ public class SevenZipContainer: Container {
}
private static func readHeader(_ data: Data) throws -> SevenZipHeader? {
+ // Valid 7-Zip container must contain at least a SignatureHeader, which is 32 bytes long.
+ guard data.count >= 32
+ else { throw SevenZipError.wrongSignature }
+
let bitReader = MsbBitReader(data: data)
// **SignatureHeader**
@@ -223,19 +227,18 @@ public class SevenZipContainer: Container {
let nextHeaderSize = bitReader.int(fromBytes: 8)
let nextHeaderCRC = bitReader.uint32()
- bitReader.offset = 12
+ bitReader.offset -= 20
guard CheckSums.crc32(bitReader.bytes(count: 20)) == startHeaderCRC
else { throw SevenZipError.wrongCRC }
// **Header**
bitReader.offset += nextHeaderOffset
- let headerStartIndex = bitReader.offset
- let headerEndIndex: Int
-
if bitReader.isFinished {
return nil // In case of completely empty container.
}
+ let headerStartIndex = bitReader.offset
+ let headerEndIndex: Int
let type = bitReader.byte()
let header: SevenZipHeader
diff --git a/Sources/BZip2/BZip2.swift b/Sources/BZip2/BZip2.swift
index ad717fbe..aed1442f 100644
--- a/Sources/BZip2/BZip2.swift
+++ b/Sources/BZip2/BZip2.swift
@@ -26,6 +26,10 @@ public class BZip2: DecompressionAlgorithm {
}
static func decompress(_ bitReader: MsbBitReader) throws -> Data {
+ // Valid BZip2 "archive" must contain at least 14 bytes of data.
+ guard bitReader.bitsLeft >= 14 * 8
+ else { throw BZip2Error.wrongMagic }
+
/// An array for storing output data
var out = Data()
diff --git a/Sources/GZip/GzipArchive.swift b/Sources/GZip/GzipArchive.swift
index a5b1cad4..648e1f35 100644
--- a/Sources/GZip/GzipArchive.swift
+++ b/Sources/GZip/GzipArchive.swift
@@ -77,6 +77,10 @@ public class GzipArchive: Archive {
}
private static func processMember(_ bitReader: LsbBitReader) throws -> Member {
+ // Valid GZip archive must contain at least 33 bytes of data.
+ guard bitReader.bitsLeft >= 33 * 8
+ else { throw GzipError.wrongMagic }
+
let header = try GzipHeader(bitReader)
let memberData = try Deflate.decompress(bitReader)
diff --git a/Sources/GZip/GzipHeader.swift b/Sources/GZip/GzipHeader.swift
index 74401b1e..b2f85de5 100644
--- a/Sources/GZip/GzipHeader.swift
+++ b/Sources/GZip/GzipHeader.swift
@@ -58,6 +58,10 @@ public struct GzipHeader {
}
init(_ reader: LsbBitReader) throws {
+ // Valid GZip header must contain at least 2 bytes of data.
+ guard reader.bytesLeft >= 10
+ else { throw GzipError.wrongMagic }
+
// First two bytes should be correct 'magic' bytes
let magic = reader.uint16()
guard magic == 0x8b1f else { throw GzipError.wrongMagic }
diff --git a/Sources/LZMA/LZMA.swift b/Sources/LZMA/LZMA.swift
index ad86fb42..06a922e3 100644
--- a/Sources/LZMA/LZMA.swift
+++ b/Sources/LZMA/LZMA.swift
@@ -23,6 +23,10 @@ public class LZMA: DecompressionAlgorithm {
- Returns: Decompressed data.
*/
public static func decompress(data: Data) throws -> Data {
+ // Valid LZMA "archive" must contain at least 13 bytes of data with properties and uncompressed size.
+ guard data.count >= 13
+ else { throw LZMAError.wrongProperties }
+
let byteReader = LittleEndianByteReader(data: data)
let properties = try LZMAProperties(byteReader)
let uncompSize = byteReader.int(fromBytes: 8)
diff --git a/Sources/LZMA/LZMADecoder.swift b/Sources/LZMA/LZMADecoder.swift
index 9512e4ee..a18f5a95 100644
--- a/Sources/LZMA/LZMADecoder.swift
+++ b/Sources/LZMA/LZMADecoder.swift
@@ -255,8 +255,7 @@ final class LZMADecoder {
// Middle bits of distance are decoded as direct bits from RangeDecoder.
dist += rangeDecoder.decode(directBits: (numDirectBits - LZMAConstants.numAlignBits))
<< LZMAConstants.numAlignBits
- // Low 4 bits are decoded with a bit tree decoder (called 'AlignDecoder')...
- // ...with "Reverse" scheme.
+ // Low 4 bits are decoded with a bit tree decoder (called 'AlignDecoder') using "Reverse" scheme.
dist += alignDecoder.reverseDecode(with: rangeDecoder)
}
rep0 = dist
diff --git a/Sources/LZMA/LZMARangeDecoder.swift b/Sources/LZMA/LZMARangeDecoder.swift
index fde97a95..3521c213 100644
--- a/Sources/LZMA/LZMARangeDecoder.swift
+++ b/Sources/LZMA/LZMARangeDecoder.swift
@@ -19,6 +19,10 @@ final class LZMARangeDecoder {
}
init?(_ byteReader: LittleEndianByteReader) {
+ // To initialize rande decoder at least 5 bytes are necessary.
+ guard byteReader.bytesLeft >= 5
+ else { return nil }
+
self.byteReader = byteReader
let byte = self.byteReader.byte()
diff --git a/Sources/TAR/TarEntryInfo.swift b/Sources/TAR/TarEntryInfo.swift
index 88daba26..36a12873 100644
--- a/Sources/TAR/TarEntryInfo.swift
+++ b/Sources/TAR/TarEntryInfo.swift
@@ -264,7 +264,7 @@ public struct TarEntryInfo: ContainerEntryInfo {
let linkName = byteReader.tarCString(maxLength: 100)
// There are two different formats utilizing this section of TAR header: GNU format and POSIX (aka "ustar";
- // also PAX containers can also be considered POSIX). They differ in the value of magic field as well as what
+ // PAX containers can also be considered as POSIX). They differ in the value of magic field as well as what
// comes after deviceMinorNumber field. While "ustar" format may contain prefix for file name, GNU format
// uses this place for storing atime/ctime and fields related to sparse-files. In practice, these fields are
// rarely used by GNU tar and only present if "incremental backups" options were used. Thus, GNU format TAR
@@ -309,7 +309,7 @@ public struct TarEntryInfo: ContainerEntryInfo {
if local != nil || global != nil {
self.format = .pax
- } else if magic == 0x00_20_20_72_61_74_73_75 || longName != nil || longLinkName != nil {
+ } else if magic == 0x0020207261747375 || longName != nil || longLinkName != nil {
self.format = .gnu
} else if magic == 0x3030007261747375 || magic == 0x3030207261747375 {
self.format = .ustar
diff --git a/Sources/XZ/XZArchive.swift b/Sources/XZ/XZArchive.swift
index ca6aea6e..3a6c605f 100644
--- a/Sources/XZ/XZArchive.swift
+++ b/Sources/XZ/XZArchive.swift
@@ -35,6 +35,10 @@ public class XZArchive: Archive {
var result = Data()
while !byteReader.isFinished {
+ // Valid XZ archive must contain at least 32 bytes of data.
+ guard byteReader.bytesLeft >= 32
+ else { throw XZError.wrongMagic }
+
let streamResult = try processStream(byteReader)
result.append(streamResult.data)
guard !streamResult.checkError
@@ -68,6 +72,10 @@ public class XZArchive: Archive {
var result = [Data]()
while !byteReader.isFinished {
+ // Valid XZ archive must contain at least 32 bytes of data.
+ guard byteReader.bytesLeft >= 32
+ else { throw XZError.wrongMagic }
+
let streamResult = try processStream(byteReader)
result.append(streamResult.data)
guard !streamResult.checkError
diff --git a/Sources/ZIP/ZipContainer.swift b/Sources/ZIP/ZipContainer.swift
index 736ed7a0..020d6239 100644
--- a/Sources/ZIP/ZipContainer.swift
+++ b/Sources/ZIP/ZipContainer.swift
@@ -141,6 +141,10 @@ public class ZipContainer: Container {
}
private static func infoWithHelper(_ data: Data) throws -> [ZipEntryInfoHelper] {
+ // Valid ZIP container must contain at least an End of Central Directory record, which is at least 22 bytes long.
+ guard data.count >= 22
+ else { throw ZipError.notFoundCentralDirectoryEnd }
+
let byteReader = LittleEndianByteReader(data: data)
var entries = [ZipEntryInfoHelper]()
@@ -152,7 +156,7 @@ public class ZipContainer: Container {
// We found it!
break
}
- if byteReader.offset == 0 {
+ if byteReader.offset == 4 {
throw ZipError.notFoundCentralDirectoryEnd
}
byteReader.offset -= 5
diff --git a/Sources/Zlib/ZlibArchive.swift b/Sources/Zlib/ZlibArchive.swift
index 8e6b8593..e7d5084a 100644
--- a/Sources/Zlib/ZlibArchive.swift
+++ b/Sources/Zlib/ZlibArchive.swift
@@ -23,6 +23,10 @@ public class ZlibArchive: Archive {
- Returns: Unarchived data.
*/
public static func unarchive(archive data: Data) throws -> Data {
+ // Valid Zlib archive must contain at least 8 bytes of data.
+ guard data.count >= 8
+ else { throw ZlibError.wrongCompressionMethod }
+
/// Object with input data which supports convenient work with bit shifts.
let bitReader = LsbBitReader(data: data)
diff --git a/Sources/Zlib/ZlibHeader.swift b/Sources/Zlib/ZlibHeader.swift
index 72c3e54b..f71c8218 100644
--- a/Sources/Zlib/ZlibHeader.swift
+++ b/Sources/Zlib/ZlibHeader.swift
@@ -45,6 +45,10 @@ public struct ZlibHeader {
}
init(_ reader: LsbBitReader) throws {
+ // Valid Zlib header must contain at least 2 bytes of data.
+ guard reader.bytesLeft >= 2
+ else { throw ZlibError.wrongCompressionMethod }
+
// compressionMethod and compressionInfo combined are needed later for integrity check.
let cmf = reader.byte()
// First four bits are compression method.
@@ -65,7 +69,7 @@ public struct ZlibHeader {
// fcheck, fdict and compresionLevel together make flags byte which is used in integrity check.
let flags = reader.byte()
- // First five bits are fcheck bits which are supposed to be integrity check:
+ // First five bits are fcheck bits which are used for integrity check:
// let fcheck = flags & 0x1F
// Sixth bit indicate if archive contain Adler-32 checksum of preset dictionary.
diff --git a/Sources/swcomp/main.swift b/Sources/swcomp/main.swift
index e90ac2a3..f7c62315 100644
--- a/Sources/swcomp/main.swift
+++ b/Sources/swcomp/main.swift
@@ -7,7 +7,7 @@ import Foundation
import SWCompression
import SwiftCLI
-let cli = CLI(name: "swcomp", version: "4.5.6",
+let cli = CLI(name: "swcomp", version: "4.5.7",
description: """
swcomp - a small command-line client for SWCompression framework.
Serves as an example of SWCompression usage.
diff --git a/Tests/BZip2Tests.swift b/Tests/BZip2Tests.swift
index 4db58c1d..3107c973 100644
--- a/Tests/BZip2Tests.swift
+++ b/Tests/BZip2Tests.swift
@@ -54,4 +54,13 @@ class BZip2Tests: XCTestCase {
try self.perform(test: "test9")
}
+ func testBadFile_short() {
+ XCTAssertThrowsError(try BZip2.decompress(data: Data([0])))
+ }
+
+ func testBadFile_invalid() throws {
+ let testData = try Constants.data(forAnswer: "test6")
+ XCTAssertThrowsError(try BZip2.decompress(data: testData))
+ }
+
}
diff --git a/Tests/GzipTests.swift b/Tests/GzipTests.swift
index 13fc74e0..8f662df5 100644
--- a/Tests/GzipTests.swift
+++ b/Tests/GzipTests.swift
@@ -139,4 +139,16 @@ class GzipTests: XCTestCase {
XCTAssertEqual(data, answerData)
}
+ func testBadFile_short() {
+ XCTAssertThrowsError(try GzipArchive.unarchive(archive: Data([0])))
+ XCTAssertThrowsError(try GzipArchive.multiUnarchive(archive: Data([0])))
+ XCTAssertThrowsError(try GzipHeader(archive: Data([0])))
+ }
+
+ func testBadFile_invalid() throws {
+ let testData = try Constants.data(forAnswer: "test6")
+ XCTAssertThrowsError(try GzipArchive.unarchive(archive: testData))
+ XCTAssertThrowsError(try GzipArchive.multiUnarchive(archive: testData))
+ }
+
}
diff --git a/Tests/LzmaTests.swift b/Tests/LzmaTests.swift
index 63a0c68d..1081a273 100644
--- a/Tests/LzmaTests.swift
+++ b/Tests/LzmaTests.swift
@@ -34,4 +34,22 @@ class LzmaTests: XCTestCase {
try self.perform(test: "test11")
}
+ func testLzmaEmpty() throws {
+ let testData = try Constants.data(forTest: "test_empty", withType: LzmaTests.testType)
+ XCTAssertEqual(try LZMA.decompress(data: testData), Data())
+ }
+
+ func testBadFile_short() {
+ // Not enough data for LZMA properties.
+ XCTAssertThrowsError(try LZMA.decompress(data: Data([0, 1, 2, 3])))
+ // Not enough data to initialize range decoder.
+ XCTAssertThrowsError(try LZMA.decompress(data: Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])))
+ }
+
+ func testBadFile_invalid() throws {
+ let testData = try Constants.data(forAnswer: "test7")
+ XCTAssertThrowsError(try LZMA.decompress(data: testData))
+ }
+
+
}
diff --git a/Tests/SevenZipTests.swift b/Tests/SevenZipTests.swift
index 049a4fbe..affbe2c2 100644
--- a/Tests/SevenZipTests.swift
+++ b/Tests/SevenZipTests.swift
@@ -10,6 +10,15 @@ class SevenZipTests: XCTestCase {
private static let testType: String = "7z"
+ func testBadFile_short() {
+ XCTAssertThrowsError(try SevenZipContainer.open(container: Data([0, 1, 2])))
+ }
+
+ func testBadFile_invalid() throws {
+ let testData = try Constants.data(forAnswer: "test6")
+ XCTAssertThrowsError(try SevenZipContainer.open(container: testData))
+ }
+
func test1() throws {
let testData = try Constants.data(forTest: "test1", withType: SevenZipTests.testType)
let entries = try SevenZipContainer.open(container: testData)
diff --git a/Tests/TarTests.swift b/Tests/TarTests.swift
index 2debc652..17ccce19 100644
--- a/Tests/TarTests.swift
+++ b/Tests/TarTests.swift
@@ -10,6 +10,17 @@ class TarTests: XCTestCase {
private static let testType: String = "tar"
+ func testBadFile_short() {
+ XCTAssertThrowsError(try TarContainer.open(container: Data([0, 1, 2])))
+ }
+
+ func testBadFile_invalid() throws {
+ // This is potentially a misleading test, since there is no way to guarantee that a file is not a TAR container.
+ // We use randomly generated data, since the 0-filled data is processed as an empty container.
+ let testData = try Constants.data(forAnswer: "test7")
+ XCTAssertThrowsError(try TarContainer.open(container: testData))
+ }
+
func test() throws {
let testData = try Constants.data(forTest: "test", withType: TarTests.testType)
diff --git a/Tests/Test Files b/Tests/Test Files
index b2f6a804..073da4e0 160000
--- a/Tests/Test Files
+++ b/Tests/Test Files
@@ -1 +1 @@
-Subproject commit b2f6a8042c372fab86e185e3d7000436dea6d769
+Subproject commit 073da4e01c87d9c1e599e507d1bb21e307c564ad
diff --git a/Tests/XzTests.swift b/Tests/XzTests.swift
index 558c7bf3..af7a1de9 100644
--- a/Tests/XzTests.swift
+++ b/Tests/XzTests.swift
@@ -110,4 +110,14 @@ class XZTests: XCTestCase {
XCTAssertEqual(decompressedData, answerData)
}
+ func testBadFile_short() {
+ XCTAssertThrowsError(try XZArchive.unarchive(archive: Data([0, 1, 2])))
+ XCTAssertThrowsError(try XZArchive.splitUnarchive(archive: Data([0, 1, 2])))
+ }
+
+ func testBadFile_invalid() throws {
+ let testData = try Constants.data(forAnswer: "test6")
+ XCTAssertThrowsError(try XZArchive.unarchive(archive: testData))
+ }
+
}
diff --git a/Tests/ZipTests.swift b/Tests/ZipTests.swift
index baf3a3db..69fd3ec6 100644
--- a/Tests/ZipTests.swift
+++ b/Tests/ZipTests.swift
@@ -10,6 +10,15 @@ class ZipTests: XCTestCase {
private static let testType: String = "zip"
+ func testBadFile_short() {
+ XCTAssertThrowsError(try ZipContainer.open(container: Data([0, 1, 2, 3, 4, 5, 6, 7])))
+ }
+
+ func testBadFile_invalid() throws {
+ let testData = try Constants.data(forAnswer: "test6")
+ XCTAssertThrowsError(try ZipContainer.open(container: testData))
+ }
+
func testBigContainer() throws {
let testData = try Constants.data(forTest: "SWCompressionSourceCode", withType: ZipTests.testType)
diff --git a/Tests/ZlibTests.swift b/Tests/ZlibTests.swift
index d24dfa56..5040f746 100644
--- a/Tests/ZlibTests.swift
+++ b/Tests/ZlibTests.swift
@@ -37,4 +37,19 @@ class ZlibTests: XCTestCase {
XCTAssertEqual(testData, reextractedData)
}
+ func testZlibEmpty() throws {
+ let testData = try Constants.data(forTest: "test_empty", withType: ZlibTests.testType)
+ XCTAssertEqual(try ZlibArchive.unarchive(archive: testData), Data())
+ }
+
+ func testBadFile_short() {
+ XCTAssertThrowsError(try ZlibArchive.unarchive(archive: Data([0x78])))
+ XCTAssertThrowsError(try ZlibHeader(archive: Data([0x78])))
+ }
+
+ func testBadFile_invalid() throws {
+ let testData = try Constants.data(forAnswer: "test6")
+ XCTAssertThrowsError(try ZlibArchive.unarchive(archive: testData))
+ }
+
}