Skip to content

Commit 6fe73cb

Browse files
committed
Merge branch 'develop'
2 parents 5419717 + c7f4665 commit 6fe73cb

32 files changed

Lines changed: 879 additions & 252 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,6 @@ docs/
7878

7979
# Vscode launch.json generated by Swift extension
8080
.vscode/launch.json
81+
82+
# API baselines generate by swift package diagnose-api-breaking-changes
83+
api_baseline/

.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.2
6+
module_version: 4.8.3
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.2
10+
github_file_prefix: https://github.com/tsolomko/SWCompression/tree/4.8.3
1111
theme: fullwidth
1212

1313
custom_categories:

CHANGELOG.md

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

3+
## 4.8.3
4+
5+
- There are now minimum deployment targets specified in Swift Package Manager manifest.
6+
- The properties of `GzipHeader` are now `var`-properties (instead of `let`).
7+
- GZip extra fields are now supported.
8+
- Added `GzipHeader.ExtraField` struct.
9+
- Added `GzipHeader.extraFields` property.
10+
- Added a new `extraFields` argument to `GzipArchive.archive` function (with a default array empty value).
11+
- Fixed potential crashes that could occur when processing GZip archives truncated in a header or a "footer".
12+
- Some non-well-formed values of PAX extended header records no longer cause `TarError.wrongPaxHeaderEntry` to be thrown.
13+
- The record values with newline characters are now fully processed.
14+
- The record values that do not contain UTF-8 strings are now ignored.
15+
- swcomp changes:
16+
- The symbolic links are now extracted with the values recorded in the containers.
17+
- The hard links are now extracted from TAR containers instead of being ignored.
18+
- Fixed build issues on Linux and Windows.
19+
- `benchmark` is now a command group with two commands, `run` and `show`.
20+
- Added `-a`, `--append` option to the `benchmark run` command.
21+
- Added `-d`, `--description` option to the `benchmark run` command.
22+
- Added `-t`, `--preserve-timestamp` option to the `benchmark run` command.
23+
- The file format of saved results is now more flexible and allows multi-way comparisons.
24+
- Improved precision of time measurements in benchmarks.
25+
326
## 4.8.2
427

528
- Swift 5.1 is no longer supported.

Package.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ import PackageDescription
33

44
let package = Package(
55
name: "SWCompression",
6+
platforms: [
7+
.macOS(.v10_13),
8+
.iOS(.v11),
9+
.tvOS(.v11),
10+
.watchOS(.v4)
11+
],
612
products: [
713
.library(
814
name: "SWCompression",

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ Every function or type of SWCompression's public API is documented. This documen
171171
There is a small command-line program, "swcomp", which is included in this repository in "Sources/swcomp". It can be
172172
built using Swift Package Manager.
173173

174+
__IMPORTANT:__ The "swcomp" command-line tool is NOT intended for general use.
175+
174176
## Contributing
175177

176178
Whether you find a bug, have a suggestion, idea, feedback or something else, please

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.2"
4+
s.version = "4.8.3"
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.2</string>
18+
<string>4.8.3</string>
1919
<key>CFBundleVersion</key>
20-
<string>87</string>
20+
<string>88</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.2</string>
18+
<string>4.8.3</string>
1919
<key>CFBundleVersion</key>
20-
<string>87</string>
20+
<string>88</string>
2121
</dict>
2222
</plist>

SWCompression.xcodeproj/project.pbxproj

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@
213213
06F066771FFB763400312A82 /* test8.bz2 in Resources */ = {isa = PBXBuildFile; fileRef = 06F066111FFB763300312A82 /* test8.bz2 */; };
214214
06F276DF1F2BAB4A00E67335 /* 7zEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F276DE1F2BAB4900E67335 /* 7zEntry.swift */; };
215215
06FEAD921F54B9CD00AD016E /* EncodingTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06FEAD911F54B9CD00AD016E /* EncodingTree.swift */; };
216+
E6023B1B28F9B60000D6F3DC /* test4_extra_field.gz in Resources */ = {isa = PBXBuildFile; fileRef = E6023B1A28F9B60000D6F3DC /* test4_extra_field.gz */; };
217+
E6023B1D28F9C92200D6F3DC /* GzipHeader+ExtraField.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6023B1C28F9C92200D6F3DC /* GzipHeader+ExtraField.swift */; };
216218
E604F3C22700C75F004BD38A /* test_dict_B5.lz4 in Resources */ = {isa = PBXBuildFile; fileRef = E604F3BF2700C75F004BD38A /* test_dict_B5.lz4 */; };
217219
E604F3C32700C75F004BD38A /* test_dict_B5_BD.lz4 in Resources */ = {isa = PBXBuildFile; fileRef = E604F3C02700C75F004BD38A /* test_dict_B5_BD.lz4 */; };
218220
E604F3C42700C75F004BD38A /* lz4_dict in Resources */ = {isa = PBXBuildFile; fileRef = E604F3C12700C75F004BD38A /* lz4_dict */; };
@@ -266,6 +268,7 @@
266268
E6791E1826FD001A003852A9 /* DataError.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6791E1726FD001A003852A9 /* DataError.swift */; };
267269
E6791E1B26FD0094003852A9 /* LZ4.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6791E1A26FD0094003852A9 /* LZ4.swift */; };
268270
E6791E3326FD05EC003852A9 /* LZ4Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6791E3226FD05EC003852A9 /* LZ4Tests.swift */; };
271+
E68DA766290420BC00259CB4 /* test_pax_record_newline.tar in Resources */ = {isa = PBXBuildFile; fileRef = E68DA765290420BC00259CB4 /* test_pax_record_newline.tar */; };
269272
E694694327480EA6009C897A /* TarReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = E694694227480EA6009C897A /* TarReader.swift */; };
270273
E6974C5B2701AC2600E06C60 /* test_dict_B5_dictID.lz4 in Resources */ = {isa = PBXBuildFile; fileRef = E6974C5A2701AC2600E06C60 /* test_dict_B5_dictID.lz4 */; };
271274
E69FAC922729ACD900D3C406 /* test_dos_latin_us.zip in Resources */ = {isa = PBXBuildFile; fileRef = E69FAC912729ACD900D3C406 /* test_dos_latin_us.zip */; };
@@ -497,6 +500,8 @@
497500
06F276DE1F2BAB4900E67335 /* 7zEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 7zEntry.swift; sourceTree = "<group>"; };
498501
06FEAD911F54B9CD00AD016E /* EncodingTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EncodingTree.swift; path = Sources/Common/CodingTree/EncodingTree.swift; sourceTree = SOURCE_ROOT; };
499502
06FED40B1DD7717E0013DFB2 /* BZip2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BZip2.swift; sourceTree = "<group>"; };
503+
E6023B1A28F9B60000D6F3DC /* test4_extra_field.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; path = test4_extra_field.gz; sourceTree = "<group>"; };
504+
E6023B1C28F9C92200D6F3DC /* GzipHeader+ExtraField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GzipHeader+ExtraField.swift"; sourceTree = "<group>"; };
500505
E604F3BF2700C75F004BD38A /* test_dict_B5.lz4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = test_dict_B5.lz4; sourceTree = "<group>"; };
501506
E604F3C02700C75F004BD38A /* test_dict_B5_BD.lz4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = test_dict_B5_BD.lz4; sourceTree = "<group>"; };
502507
E604F3C12700C75F004BD38A /* lz4_dict */ = {isa = PBXFileReference; lastKnownFileType = file; path = lz4_dict; sourceTree = "<group>"; };
@@ -551,6 +556,7 @@
551556
E6791E1726FD001A003852A9 /* DataError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataError.swift; sourceTree = "<group>"; };
552557
E6791E1A26FD0094003852A9 /* LZ4.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LZ4.swift; sourceTree = "<group>"; };
553558
E6791E3226FD05EC003852A9 /* LZ4Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LZ4Tests.swift; sourceTree = "<group>"; };
559+
E68DA765290420BC00259CB4 /* test_pax_record_newline.tar */ = {isa = PBXFileReference; lastKnownFileType = archive.tar; path = test_pax_record_newline.tar; sourceTree = "<group>"; };
554560
E694694227480EA6009C897A /* TarReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TarReader.swift; sourceTree = "<group>"; };
555561
E6974C5A2701AC2600E06C60 /* test_dict_B5_dictID.lz4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = test_dict_B5_dictID.lz4; sourceTree = "<group>"; };
556562
E69FAC912729ACD900D3C406 /* test_dos_latin_us.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = test_dos_latin_us.zip; sourceTree = "<group>"; };
@@ -714,6 +720,7 @@
714720
children = (
715721
063364E21DC52979007E313F /* GzipArchive.swift */,
716722
061C062A1F0E8A1D00832F0C /* GzipHeader.swift */,
723+
E6023B1C28F9C92200D6F3DC /* GzipHeader+ExtraField.swift */,
717724
061C06251F0E8A0300832F0C /* GzipError.swift */,
718725
0686A63F1FA4C18800E89C9E /* FileSystemType+Gzip.swift */,
719726
);
@@ -875,6 +882,7 @@
875882
06F065BF1FFB763300312A82 /* test2.gz */,
876883
06F065BC1FFB763300312A82 /* test3.gz */,
877884
06F065BB1FFB763300312A82 /* test4.gz */,
885+
E6023B1A28F9B60000D6F3DC /* test4_extra_field.gz */,
878886
06F065B91FFB763300312A82 /* test5.gz */,
879887
06F065BE1FFB763300312A82 /* test6.gz */,
880888
06F065BD1FFB763300312A82 /* test7.gz */,
@@ -953,6 +961,7 @@
953961
0698B10A2104E11200A7C551 /* test_gnu_inc_format.tar */,
954962
0698B10C2106136500A7C551 /* test_big_num_field.tar */,
955963
0698B10E2106344200A7C551 /* test_negative_mtime.tar */,
964+
E68DA765290420BC00259CB4 /* test_pax_record_newline.tar */,
956965
);
957966
path = TAR;
958967
sourceTree = "<group>";
@@ -1213,6 +1222,7 @@
12131222
E652FEE027009BDD006BC312 /* test5_legacy.lz4 in Resources */,
12141223
06F066721FFB763400312A82 /* test7.bz2 in Resources */,
12151224
06F0665B1FFB763400312A82 /* test10.lzma in Resources */,
1225+
E68DA766290420BC00259CB4 /* test_pax_record_newline.tar in Resources */,
12161226
E652FEFE2700A028006BC312 /* test_B7_BD.lz4 in Resources */,
12171227
06F0663C1FFB763400312A82 /* test3.xz in Resources */,
12181228
06F066591FFB763400312A82 /* test_win.tar in Resources */,
@@ -1278,6 +1288,7 @@
12781288
E652FED6270091B6006BC312 /* test_skippable_frame.lz4 in Resources */,
12791289
06F0665A1FFB763400312A82 /* test11.lzma in Resources */,
12801290
E652FEE427009BDD006BC312 /* test3_legacy.lz4 in Resources */,
1291+
E6023B1B28F9B60000D6F3DC /* test4_extra_field.gz in Resources */,
12811292
06F066401FFB763400312A82 /* test_zip_bzip2.zip in Resources */,
12821293
06F066461FFB763400312A82 /* test_empty_file.zip in Resources */,
12831294
06F066331FFB763400312A82 /* random_file.zlib in Resources */,
@@ -1406,6 +1417,7 @@
14061417
06A9606A1F1E7E0D0078E6D1 /* 7zSubstreamInfo.swift in Sources */,
14071418
E6C4150726FE230A00F9D36F /* XxHash32.swift in Sources */,
14081419
0694A74D1F7C0DF00023BC99 /* BurrowsWheeler.swift in Sources */,
1420+
E6023B1D28F9C92200D6F3DC /* GzipHeader+ExtraField.swift in Sources */,
14091421
06CC3FDD1F8AAE8B00BD576D /* MsbBitReader+7z.swift in Sources */,
14101422
06A3933B1DE0709300182E12 /* Deflate.swift in Sources */,
14111423
06092A1A1FA4CB0300DE9FD5 /* CompressionMethod.swift in Sources */,
@@ -1516,7 +1528,7 @@
15161528
CLANG_WARN_SUSPICIOUS_MOVE = YES;
15171529
CLANG_WARN_UNREACHABLE_CODE = YES;
15181530
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
1519-
CURRENT_PROJECT_VERSION = 87;
1531+
CURRENT_PROJECT_VERSION = 88;
15201532
DEAD_CODE_STRIPPING = YES;
15211533
DEBUG_INFORMATION_FORMAT = dwarf;
15221534
EAGER_LINKING = YES;
@@ -1601,7 +1613,7 @@
16011613
CLANG_WARN_SUSPICIOUS_MOVE = YES;
16021614
CLANG_WARN_UNREACHABLE_CODE = YES;
16031615
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
1604-
CURRENT_PROJECT_VERSION = 87;
1616+
CURRENT_PROJECT_VERSION = 88;
16051617
DEAD_CODE_STRIPPING = YES;
16061618
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
16071619
EAGER_LINKING = YES;
@@ -1666,7 +1678,7 @@
16661678
APPLICATION_EXTENSION_API_ONLY = YES;
16671679
DEFINES_MODULE = YES;
16681680
DYLIB_COMPATIBILITY_VERSION = 1;
1669-
DYLIB_CURRENT_VERSION = 87;
1681+
DYLIB_CURRENT_VERSION = 88;
16701682
DYLIB_INSTALL_NAME_BASE = "@rpath";
16711683
INFOPLIST_FILE = SWCompression.xcodeproj/SWCompression.plist;
16721684
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@@ -1693,7 +1705,7 @@
16931705
APPLICATION_EXTENSION_API_ONLY = YES;
16941706
DEFINES_MODULE = YES;
16951707
DYLIB_COMPATIBILITY_VERSION = 1;
1696-
DYLIB_CURRENT_VERSION = 87;
1708+
DYLIB_CURRENT_VERSION = 88;
16971709
DYLIB_INSTALL_NAME_BASE = "@rpath";
16981710
INFOPLIST_FILE = SWCompression.xcodeproj/SWCompression.plist;
16991711
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";

Sources/GZip/GzipArchive.swift

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,18 @@ public class GzipArchive: Archive {
7878

7979
private static func processMember(_ bitReader: LsbBitReader) throws -> Member {
8080
// Valid GZip archive must contain at least 20 bytes of data (10 for the header, 2 for an empty Deflate block,
81-
// and 8 for checksums).
82-
guard bitReader.bitsLeft >= 20 * 8
81+
// and 8 for checksums). In addition, since GZip format is "byte-oriented" we should ensure that members are
82+
// byte-aligned.
83+
guard bitReader.isAligned && bitReader.bytesLeft >= 20
8384
else { throw GzipError.wrongMagic }
8485

8586
let header = try GzipHeader(bitReader)
8687

8788
let memberData = try Deflate.decompress(bitReader)
8889
bitReader.align()
8990

91+
guard bitReader.bytesLeft >= 8
92+
else { throw GzipError.wrongMagic }
9093
let crc32 = bitReader.uint32()
9194
let isize = bitReader.uint64(fromBytes: 4)
9295
guard UInt64(truncatingIfNeeded: memberData.count) % (UInt64(truncatingIfNeeded: 1) << 32) == isize
@@ -110,14 +113,20 @@ public class GzipArchive: Archive {
110113
- Parameter isTextFile: Set to true, if the file which will be archived is text file or ASCII-file.
111114
- Parameter osType: Type of the system on which this archive will be created.
112115
- Parameter modificationTime: Last time the file was modified.
116+
- Parameter extraFields: Any extra fields. Note that no extra field is allowed to have second byte of the extra
117+
field (subfield) ID equal to zero. In addition, the length of a field's binary content must be less than
118+
`UInt16.max`, while the total sum of the binary content length of all extra fields plus 4 for each field must also
119+
not exceed `UInt16.max`. See GZip format specification for more details.
113120

114-
- Throws: `GzipError.cannotEncodeISOLatin1` if file name of comment cannot be encoded with ISO-Latin-1 encoding.
121+
- Throws: `GzipError.cannotEncodeISOLatin1` if a file name or a comment cannot be encoded with ISO-Latin-1 encoding
122+
or if the total sum of the binary content length of all extra fields plus 4 for each field exceeds `UInt16.max`.
115123

116124
- Returns: Resulting archive's data.
117125
*/
118126
public static func archive(data: Data, comment: String? = nil, fileName: String? = nil,
119127
writeHeaderCRC: Bool = false, isTextFile: Bool = false,
120-
osType: FileSystemType? = nil, modificationTime: Date? = nil) throws -> Data {
128+
osType: FileSystemType? = nil, modificationTime: Date? = nil,
129+
extraFields: [GzipHeader.ExtraField] = []) throws -> Data {
121130
var flags: UInt8 = 0
122131

123132
var commentData = Data()
@@ -146,6 +155,10 @@ public class GzipArchive: Archive {
146155
}
147156
}
148157

158+
if !extraFields.isEmpty {
159+
flags |= 1 << 2
160+
}
161+
149162
if writeHeaderCRC {
150163
flags |= 1 << 1
151164
}
@@ -167,14 +180,35 @@ public class GzipArchive: Archive {
167180
var headerBytes: [UInt8] = [
168181
0x1f, 0x8b, // 'magic' bytes.
169182
8, // Compression method (DEFLATE).
170-
flags // Flags; currently no flags are set.
183+
flags
171184
]
172185
for i in 0..<4 {
173186
headerBytes.append(mtimeBytes[i])
174187
}
175188
headerBytes.append(2) // Extra flags; 2 means that DEFLATE used slowest algorithm.
176189
headerBytes.append(os)
177190

191+
if !extraFields.isEmpty {
192+
let xlen = extraFields.reduce(0) { $0 + 4 + $1.bytes.count }
193+
guard xlen <= UInt16.max
194+
else { throw GzipError.cannotEncodeISOLatin1 }
195+
headerBytes.append((xlen & 0xFF).toUInt8())
196+
headerBytes.append(((xlen >> 8) & 0xFF).toUInt8())
197+
198+
for extraField in extraFields {
199+
headerBytes.append(extraField.si1)
200+
headerBytes.append(extraField.si2)
201+
202+
let len = extraField.bytes.count
203+
headerBytes.append((len & 0xFF).toUInt8())
204+
headerBytes.append(((len >> 8) & 0xFF).toUInt8())
205+
206+
for byte in extraField.bytes {
207+
headerBytes.append(byte)
208+
}
209+
}
210+
}
211+
178212
var outData = Data(headerBytes)
179213

180214
outData.append(fileNameData)

0 commit comments

Comments
 (0)