Skip to content

Commit bca9a66

Browse files
committed
Merge branch 'develop'
2 parents 6fe73cb + cbb34a1 commit bca9a66

14 files changed

Lines changed: 63 additions & 34 deletions

.jazzy.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ sourcekitten_sourcefile: docs.json
33
clean: false
44
author: Timofey Solomko
55
module: SWCompression
6-
module_version: 4.8.3
6+
module_version: 4.8.4
77
copyright: '© 2022 Timofey Solomko'
88
readme: README.md
99
github_url: https://github.com/tsolomko/SWCompression
10-
github_file_prefix: https://github.com/tsolomko/SWCompression/tree/4.8.3
10+
github_file_prefix: https://github.com/tsolomko/SWCompression/tree/4.8.4
1111
theme: fullwidth
1212

1313
custom_categories:

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## 4.8.4
4+
5+
- Fixed an issue where in some cases BZip2 compression would produce incorrect output.
6+
- `TarReader` methods now always return `nil` after reaching the end of a TAR container.
7+
38
## 4.8.3
49

510
- There are now minimum deployment targets specified in Swift Package Manager manifest.

SWCompression.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Pod::Spec.new do |s|
22

33
s.name = "SWCompression"
4-
s.version = "4.8.3"
4+
s.version = "4.8.4"
55
s.summary = "A framework with functions for working with compression, archives and containers."
66

77
s.description = "A framework with (de)compression algorithms and functions for processing various archives and containers."

SWCompression.xcodeproj/SWCompression.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
<key>CFBundlePackageType</key>
1616
<string>FMWK</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>4.8.3</string>
18+
<string>4.8.4</string>
1919
<key>CFBundleVersion</key>
20-
<string>88</string>
20+
<string>89</string>
2121
<key>NSHumanReadableCopyright</key>
2222
<string>Copyright © 2022 Timofey Solomko</string>
2323
</dict>

SWCompression.xcodeproj/TestSWCompression.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
<key>CFBundlePackageType</key>
1616
<string>BNDL</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>4.8.3</string>
18+
<string>4.8.4</string>
1919
<key>CFBundleVersion</key>
20-
<string>88</string>
20+
<string>89</string>
2121
</dict>
2222
</plist>

SWCompression.xcodeproj/project.pbxproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,7 +1147,7 @@
11471147
isa = PBXProject;
11481148
attributes = {
11491149
LastSwiftUpdateCheck = 0920;
1150-
LastUpgradeCheck = 1400;
1150+
LastUpgradeCheck = 1420;
11511151
ORGANIZATIONNAME = "Timofey Solomko";
11521152
TargetAttributes = {
11531153
06BE1AC71DB410F100EE0F59 = {
@@ -1528,7 +1528,7 @@
15281528
CLANG_WARN_SUSPICIOUS_MOVE = YES;
15291529
CLANG_WARN_UNREACHABLE_CODE = YES;
15301530
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
1531-
CURRENT_PROJECT_VERSION = 88;
1531+
CURRENT_PROJECT_VERSION = 89;
15321532
DEAD_CODE_STRIPPING = YES;
15331533
DEBUG_INFORMATION_FORMAT = dwarf;
15341534
EAGER_LINKING = YES;
@@ -1613,7 +1613,7 @@
16131613
CLANG_WARN_SUSPICIOUS_MOVE = YES;
16141614
CLANG_WARN_UNREACHABLE_CODE = YES;
16151615
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
1616-
CURRENT_PROJECT_VERSION = 88;
1616+
CURRENT_PROJECT_VERSION = 89;
16171617
DEAD_CODE_STRIPPING = YES;
16181618
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
16191619
EAGER_LINKING = YES;
@@ -1678,7 +1678,7 @@
16781678
APPLICATION_EXTENSION_API_ONLY = YES;
16791679
DEFINES_MODULE = YES;
16801680
DYLIB_COMPATIBILITY_VERSION = 1;
1681-
DYLIB_CURRENT_VERSION = 88;
1681+
DYLIB_CURRENT_VERSION = 89;
16821682
DYLIB_INSTALL_NAME_BASE = "@rpath";
16831683
INFOPLIST_FILE = SWCompression.xcodeproj/SWCompression.plist;
16841684
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@@ -1705,7 +1705,7 @@
17051705
APPLICATION_EXTENSION_API_ONLY = YES;
17061706
DEFINES_MODULE = YES;
17071707
DYLIB_COMPATIBILITY_VERSION = 1;
1708-
DYLIB_CURRENT_VERSION = 88;
1708+
DYLIB_CURRENT_VERSION = 89;
17091709
DYLIB_INSTALL_NAME_BASE = "@rpath";
17101710
INFOPLIST_FILE = SWCompression.xcodeproj/SWCompression.plist;
17111711
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";

SWCompression.xcodeproj/xcshareddata/xcschemes/SWCompression.xcscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1400"
3+
LastUpgradeVersion = "1420"
44
version = "1.7">
55
<BuildAction
66
parallelizeBuildables = "YES"

Sources/BZip2/BurrowsWheeler.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ enum BurrowsWheeler {
1212
let suffixArray = SuffixArray.make(from: doubleBytes, with: 256)
1313
var bwt = [Int]()
1414
bwt.reserveCapacity(bytes.count)
15+
// Pointer is an index in the transformed array, `bwt`, where the EOF marker would have been if we had used it.
1516
var pointer = 0
1617
for i in 1..<suffixArray.count {
1718
if suffixArray[i] < bytes.count {
@@ -21,7 +22,7 @@ enum BurrowsWheeler {
2122
bwt.append(bytes.last!)
2223
}
2324
} else if suffixArray[i] == bytes.count {
24-
pointer = (i - 1) / 2
25+
pointer = bwt.count
2526
}
2627
}
2728
return (bwt, pointer)

Sources/GZip/GzipHeader+ExtraField.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ extension GzipHeader {
1717
/// Binary content of the extra field.
1818
public var bytes: [UInt8]
1919

20-
/// Initializes and extra field with the specified extra field (subfield) ID bytes and its binary content.
20+
/// Initializes an extra field with the specified extra field (subfield) ID bytes and its binary content.
2121
public init(_ si1: UInt8, _ si2: UInt8, _ bytes: [UInt8]) {
2222
self.si1 = si1
2323
self.si2 = si2

Sources/TAR/TarReader.swift

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,12 @@ public struct TarReader {
5353
}
5454

5555
/**
56-
Processes the next TAR entry by reading it from the container and calling the provided closure on the result.
56+
Processes the next TAR entry by reading it from the container and calling the provided closure on the result. If
57+
the argument supplied to the closure is `nil` this indicates that the end of the input was reached.
5758

5859
On Darwin platforms both the reading and the call to the closure are performed inside the `autoreleasepool` which
5960
allows to reduce the peak memory usage.
6061

61-
If the argument supplied to the closure is `nil` this indicates that the end of the input was reached. After that
62-
the repeated `TarReader.process(_:)` or `TarReader.read()` calls will result in the `DataError.truncated` being
63-
thrown.
64-
6562
- Throws: `DataError.truncated` if the input is truncated. `TarError` is thrown in case of malformed input. Errors
6663
thrown by `FileHandle` operations are also propagated.
6764
*/
@@ -81,8 +78,7 @@ public struct TarReader {
8178
- Throws: `DataError.truncated` if the input is truncated. `TarError` is thrown in case of malformed input. Errors
8279
thrown by `FileHandle` operations are also propagated.
8380

84-
- Returns: The next entry from the container or `nil` if the end of the input has been reached. After that the
85-
repeated `TarReader.process(_:)` or `TarReader.read()` calls will result in the `DataError.truncated` being thrown.
81+
- Returns: The next entry from the container or `nil` if the end of the input has been reached.
8682
*/
8783
public mutating func read() throws -> TarEntry? {
8884
let headerData = try getData(size: 512)
@@ -94,6 +90,10 @@ public struct TarReader {
9490
if try getData(size: 512) == Data(count: 512) {
9591
return nil
9692
} else {
93+
// In this case we have a zero-filled block immediately followed by a non-zero-filled block which do not
94+
// match the EOF marker signature. In practice, this indicates a malformed TAR container, since a
95+
// zero-filled block is not a valid TAR header (and in fact the end result is an error being thrown in
96+
// TarHeader initializer later down the line).
9797
try set(offset: offset)
9898
}
9999
} else if headerData.count < 512 {
@@ -162,12 +162,18 @@ public struct TarReader {
162162

163163
private func getData(size: Int) throws -> Data {
164164
assert(size >= 0, "TarReader.getData(size:): negative size.")
165-
guard size > 0
166-
else { return Data() }
167165
if #available(macOS 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4, *) {
168-
guard let chunkData = try handle.read(upToCount: size)
169-
else { throw DataError.truncated }
170-
return chunkData
166+
// The documentation for FileHandle.read(upToCount:) is a bit misleading. This method does "return the data
167+
// obtained by reading length bytes starting at the current file pointer" even if the requested amount is
168+
// larger than the available data. What is not clear is when the method returns nil. Apparently, there are
169+
// (at least) two cases when it happens:
170+
// - the file pointer is at the EOF regardless of the argument value,
171+
// - the argument is zero.
172+
// It is also unclear what happens when the argument is negative (it seems that it reads everything until
173+
// the EOF), but the assertion above takes care of this. In any case, instead of returning nil we return
174+
// empty data since both of these situations logically seem equivalent for our purposes. This also allows us
175+
// to eliminate additional guard-check for the size parameter.
176+
return try handle.read(upToCount: size) ?? Data()
171177
} else {
172178
// Technically, this can throw NSException, but since it is ObjC exception we cannot handle it in Swift.
173179
return handle.readData(ofLength: size)

0 commit comments

Comments
 (0)