From b31b5032b14deb4e45bc035c7794a04c62ece060 Mon Sep 17 00:00:00 2001 From: Timofey Solomko Date: Sun, 30 Oct 2016 21:21:59 +0300 Subject: [PATCH 01/11] Update podspec and travis. --- .travis.yml | 8 +++++++- SWCompression.podspec | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 41f69940..94b8831e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,10 @@ +branches: + - develop + - master + osx_image: xcode8 language: objective-c xcode_project: SWCompression.xcodeproj -xcode_scheme: SWCompression +xcode_scheme: SWCompressionTests +script: +- xcodebuild clean build test -project SWCompression.xcodeproj -scheme SWCompressionTests diff --git a/SWCompression.podspec b/SWCompression.podspec index 4664e770..721dbe5a 100644 --- a/SWCompression.podspec +++ b/SWCompression.podspec @@ -17,6 +17,11 @@ Pod::Spec.new do |s| s.author = { "Timofey Solomko" => "tsolomko@gmail.com" } + s.ios.deployment_target = "10.1" + s.osx.deployment_target = "10.12" + s.tvos.deployment_target = "10.0" + s.watchos.deployment_target = "3.1" + s.source = { :git => "https://github.com/tsolomko/SWCompression.git", :tag => "v#{s.version}" } s.source_files = "Sources" From 264ff1e1c3e939e32c3b5a63883aae54612ebb16 Mon Sep 17 00:00:00 2001 From: Timofey Solomko Date: Sun, 30 Oct 2016 21:26:02 +0300 Subject: [PATCH 02/11] Another travis update. --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 94b8831e..be4fdb89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,8 @@ branches: osx_image: xcode8 language: objective-c xcode_project: SWCompression.xcodeproj -xcode_scheme: SWCompressionTests +xcode_scheme: SWCompression script: -- xcodebuild clean build test -project SWCompression.xcodeproj -scheme SWCompressionTests +- xcodebuild clean build test -project SWCompression.xcodeproj -scheme SWCompression +notifications: + email: false From 309a2a4d876f6420ab795ea0c161bee38298a6e6 Mon Sep 17 00:00:00 2001 From: Timofey Solomko Date: Sun, 30 Oct 2016 21:32:12 +0300 Subject: [PATCH 03/11] Added travis badge. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d83b2d2d..43ddf4c2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # SWCompression -[![GitHub license](https://img.shields.io/badge/license-MIT-lightgrey.svg)](https://raw.githubusercontent.com/tsolomko/SWCompression/master/LICENSE) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![GitHub license](https://img.shields.io/badge/license-MIT-lightgrey.svg)](https://raw.githubusercontent.com/tsolomko/SWCompression/master/LICENSE) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![Build Status](https://travis-ci.org/tsolomko/SWCompression.svg?branch=develop)](https://travis-ci.org/tsolomko/SWCompression) A framework which contains native (*written in Swift*) implementations of some compression algorithms. From 0d6764f5f7e3ccf14f72c3e815fcc1e6cfc3f451 Mon Sep 17 00:00:00 2001 From: Timofey Solomko Date: Mon, 31 Oct 2016 00:00:21 +0300 Subject: [PATCH 04/11] Added more complicated zlib test. --- SWCompression.xcodeproj/project.pbxproj | 11 ++++ Tests/Constants.swift | 5 ++ Tests/SWCompressionTests.swift | 14 +++++ Tests/Test Files/secondtest.zlib | Bin 0 -> 688 bytes Tests/Test Files/secondtest.zlib.answer | 79 ++++++++++++++++++++++++ 5 files changed, 109 insertions(+) create mode 100644 Tests/Test Files/secondtest.zlib create mode 100644 Tests/Test Files/secondtest.zlib.answer diff --git a/SWCompression.xcodeproj/project.pbxproj b/SWCompression.xcodeproj/project.pbxproj index 66362314..874d7e07 100644 --- a/SWCompression.xcodeproj/project.pbxproj +++ b/SWCompression.xcodeproj/project.pbxproj @@ -42,6 +42,8 @@ 065569791DC65C2B00A47E66 /* HuffmanTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06E961C91DBD5FA1008C47F2 /* HuffmanTable.swift */; }; 0655697A1DC65C2B00A47E66 /* HuffmanLength.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06AC9B0C1DC1027900A5066B /* HuffmanLength.swift */; }; 0655697B1DC65C2B00A47E66 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 061FCE301DBCC8BF0052F7BE /* Extensions.swift */; }; + 0655697D1DC6963F00A47E66 /* secondtest.zlib in Resources */ = {isa = PBXBuildFile; fileRef = 0655697C1DC6963F00A47E66 /* secondtest.zlib */; }; + 0655697F1DC6966300A47E66 /* secondtest.zlib.answer in Resources */ = {isa = PBXBuildFile; fileRef = 0655697E1DC6966300A47E66 /* secondtest.zlib.answer */; }; 06AC9B0D1DC1027900A5066B /* HuffmanLength.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06AC9B0C1DC1027900A5066B /* HuffmanLength.swift */; }; 06BE1AD21DB410F100EE0F59 /* SWCompression.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 06BE1AC81DB410F100EE0F59 /* SWCompression.framework */; }; 06BE1AD71DB410F100EE0F59 /* SWCompressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06BE1AD61DB410F100EE0F59 /* SWCompressionTests.swift */; }; @@ -79,6 +81,8 @@ 065569611DC65B1B00A47E66 /* Info-iOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; }; 065569621DC65B1B00A47E66 /* Info-tvOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = ""; }; 065569631DC65B1B00A47E66 /* Info-watchOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-watchOS.plist"; sourceTree = ""; }; + 0655697C1DC6963F00A47E66 /* secondtest.zlib */ = {isa = PBXFileReference; lastKnownFileType = file; path = secondtest.zlib; sourceTree = ""; }; + 0655697E1DC6966300A47E66 /* secondtest.zlib.answer */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = secondtest.zlib.answer; sourceTree = ""; }; 06AC9B0C1DC1027900A5066B /* HuffmanLength.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HuffmanLength.swift; sourceTree = ""; }; 06BE1AC81DB410F100EE0F59 /* SWCompression.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SWCompression.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 06BE1ACB1DB410F100EE0F59 /* SWCompression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SWCompression.h; sourceTree = ""; }; @@ -141,6 +145,8 @@ 0644925B1DC6121800F10981 /* helloworld.txt.zlib */, 06E63DB21DC3B8BD00D3A7C8 /* secondtest.txt */, 06E63DB31DC3B8BD00D3A7C8 /* secondtest.txt.gz */, + 0655697C1DC6963F00A47E66 /* secondtest.zlib */, + 0655697E1DC6966300A47E66 /* secondtest.zlib.answer */, ); path = "Test Files"; sourceTree = ""; @@ -418,7 +424,9 @@ files = ( 063364DF1DC51D33007E313F /* empty.txt.gz in Resources */, 061FCE2B1DBCC6070052F7BE /* helloworld.txt.gz in Resources */, + 0655697D1DC6963F00A47E66 /* secondtest.zlib in Resources */, 06E63DB41DC3B8BD00D3A7C8 /* secondtest.txt in Resources */, + 0655697F1DC6966300A47E66 /* secondtest.zlib.answer in Resources */, 0644925D1DC6121800F10981 /* helloworld.txt.zlib in Resources */, 06E63DB51DC3B8BD00D3A7C8 /* secondtest.txt.gz in Resources */, 061FCE2A1DBCC6070052F7BE /* helloworld.txt in Resources */, @@ -831,6 +839,7 @@ 065569451DC659FF00A47E66 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; 065569511DC65A8000A47E66 /* Build configuration list for PBXNativeTarget "SWCompression watchOS" */ = { isa = XCConfigurationList; @@ -839,6 +848,7 @@ 065569531DC65A8000A47E66 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; 0655695E1DC65A9500A47E66 /* Build configuration list for PBXNativeTarget "SWCompression tvOS" */ = { isa = XCConfigurationList; @@ -847,6 +857,7 @@ 065569601DC65A9500A47E66 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; 06BE1AC21DB410F100EE0F59 /* Build configuration list for PBXProject "SWCompression" */ = { isa = XCConfigurationList; diff --git a/Tests/Constants.swift b/Tests/Constants.swift index b84aaf5d..bdc0eeb1 100644 --- a/Tests/Constants.swift +++ b/Tests/Constants.swift @@ -26,4 +26,9 @@ struct Constants { static let helloWorldZlibPath = testBundle.url(forResource: "helloworld.txt", withExtension: "zlib")! + static let secondZlibTestPath = testBundle.url(forResource: "secondtest", + withExtension: "zlib")! + static let secondZlibTestAnswerPath = testBundle.url(forResource: "secondtest.zlib", + withExtension: "answer")! + } diff --git a/Tests/SWCompressionTests.swift b/Tests/SWCompressionTests.swift index 926ced63..16961547 100644 --- a/Tests/SWCompressionTests.swift +++ b/Tests/SWCompressionTests.swift @@ -58,4 +58,18 @@ class SWCompressionTests: XCTestCase { XCTAssertEqual(decompressedString!, "Hello, World!\n", "Decompression was incorrect") } + func testSecondZlibFile() { + let testData = try? Data(contentsOf: Constants.secondZlibTestPath) + XCTAssertNotNil(testData, "Failed to load test archive") + let decompressedData = try? ZlibArchive.unarchive(archiveData: testData!) + XCTAssertNotNil(decompressedData, "Failed to decompress") + guard decompressedData != nil else { return } + let decompressedString = String(data: decompressedData!, encoding: .utf8) + XCTAssertNotNil(decompressedString, "Failed to convert decompressed data to string") + let answerString = try? String(contentsOf: Constants.secondZlibTestAnswerPath, encoding: .utf8) + XCTAssertNotNil(answerString, "Failed to get the answer") + guard answerString != nil else { return } + XCTAssertEqual(decompressedString!, answerString!, "Decompression was incorrect") + } + } diff --git a/Tests/Test Files/secondtest.zlib b/Tests/Test Files/secondtest.zlib new file mode 100644 index 0000000000000000000000000000000000000000..480593bf2ac51b96a7299fb7ca49959544d5bd67 GIT binary patch literal 688 zcmV;h0#E%&iKUlqZ<{a>$KOxdSBcg(+O(H6QPxU}7L`cTrbv|omvF1G+1Ze#pMHj= zfdn|5?2S2_{}12!{D6Z|n*DzNE?A>Pi(pn^22z^U6jH5LQ$a5itqLH6uKH7_YuxOY zg0^5sY5a!;7n-b)4f8^-Yqyw}n`rkRNBd7bU^Nuc_+nIS>L z{Hk?!GunybGRz}HhP%4M+iSr)9)to5XxVIdq0Z%kzyKA(Vn;(yj}Lh&)GBZqL5GLG zaw3cc>hbHJ{$AqitDyL3a2f7F*zB^*RUP$Zm4*5;dIrr%8+&KL*q(KD&=X3DLPgLp z`2nbj<*zW&(Tnp3ZrNTYLdvBMC_OaP_3w!o7`rKKK*fiL$2{oL^WQIYIcD`S#*R1dnp>fr@*kaVQJtiwpvZI0pDhLw<8J|?Hqr7}=unQqYjH=l- z1z{6@s?4NtTVPdsOq7P&!@ZW;+ZCU+-jegHyd@vA@&|CoZCQB4d9G!@tL45tgOA2# z>Ny&NlHYAwkb4`UkOA>wJSqiLorn{+DiyyhYw^*#N3sbUP6y;Myfw8T_tKX0G_cnF z0P*vw=E|++(?B={8m!*!Pbyyi@hsmH%Nqq8(!S zX!}_0-)D8!u*qDwd7o;^lG>VT1*~hQ%>0e{LONG5>s$vpb7wWGZI}RLL#wU>_sBv= zh(23vFBTyAl3^x?{y(0;0A z$_{6zgYsA%4XV1~J%1egM&$ILJ+-0p-&bpPnquGV{cx>%_grqc Date: Mon, 31 Oct 2016 00:00:45 +0300 Subject: [PATCH 05/11] Fixed incorrect calculation of extraLengthBits. --- Sources/HuffmanTable.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/HuffmanTable.swift b/Sources/HuffmanTable.swift index 4da7a118..f5c69c57 100644 --- a/Sources/HuffmanTable.swift +++ b/Sources/HuffmanTable.swift @@ -25,7 +25,7 @@ class HuffmanTable: CustomStringConvertible { 8193, 12289, 16385, 24577] static func extraLengthBits(n: Int) -> Int { - if (n >= 257 && n <= 256) || n == 285 { + if (n >= 257 && n <= 260) || n == 285 { return 0 } else if n >= 261 && n <= 284 { return ((n - 257) >> 2) - 1 From 385bd2fbfc2ce665717a4edf0c1fe17213c8b721 Mon Sep 17 00:00:00 2001 From: Timofey Solomko Date: Mon, 31 Oct 2016 00:01:29 +0300 Subject: [PATCH 06/11] Fixed incorrect calculation of mainLiterals table in case of dynamic Huffman coding. --- Sources/Deflate.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Deflate.swift b/Sources/Deflate.swift index 6891a7c2..d1953ac7 100644 --- a/Sources/Deflate.swift +++ b/Sources/Deflate.swift @@ -145,7 +145,7 @@ public class Deflate: DecompressionAlgorithm { let end = (index, shift) count = 11 + convertToInt(reversedUint8Array: data.bits(from: start, to: end)) - what = codeLengths.last! + what = 0 } else { throw DeflateError.HuffmanTableError } From 8f7418719f66b32868f0db5671255e09cb576503 Mon Sep 17 00:00:00 2001 From: Timofey Solomko Date: Mon, 31 Oct 2016 00:02:20 +0300 Subject: [PATCH 07/11] Since shift+extraDistance could be greater than 16, it could cause errors. This was fixed. --- Sources/Deflate.swift | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Sources/Deflate.swift b/Sources/Deflate.swift index d1953ac7..32cb9d8d 100644 --- a/Sources/Deflate.swift +++ b/Sources/Deflate.swift @@ -192,9 +192,15 @@ public class Deflate: DecompressionAlgorithm { let start = (index, shift) let extraDistance = HuffmanTable.Constants.extraDistanceBits(n: newSymbol) guard extraDistance != -1 else { throw DeflateError.HuffmanTableError } - index += shift + extraDistance >= 8 ? 1 : 0 - shift = shift + extraDistance >= 8 ? - shift - (8 - extraDistance) : shift + extraDistance + if shift + extraDistance >= 16 { + index += 2 + shift = shift - (16 - extraDistance) + } else if shift + extraDistance >= 8 { + index += 1 + shift = shift - (8 - extraDistance) + } else { + shift += extraDistance + } let end = (index, shift) let distance = HuffmanTable.Constants.distanceBase[newSymbol] + convertToInt(reversedUint8Array: data.bits(from: start, to: end)) From 44cfbbec31b1253647db5fc2402d67c465ad0d46 Mon Sep 17 00:00:00 2001 From: Timofey Solomko Date: Mon, 31 Oct 2016 00:31:49 +0300 Subject: [PATCH 08/11] Added yet another test case. --- Tests/Constants.swift | 7 ++- Tests/SWCompressionTests.swift | 14 +++++ Tests/Test Files/thirdtest.zlib | Bin 0 -> 707 bytes Tests/Test Files/thirdtest.zlib.answer | 74 +++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 Tests/Test Files/thirdtest.zlib create mode 100644 Tests/Test Files/thirdtest.zlib.answer diff --git a/Tests/Constants.swift b/Tests/Constants.swift index bdc0eeb1..37f35293 100644 --- a/Tests/Constants.swift +++ b/Tests/Constants.swift @@ -29,6 +29,11 @@ struct Constants { static let secondZlibTestPath = testBundle.url(forResource: "secondtest", withExtension: "zlib")! static let secondZlibTestAnswerPath = testBundle.url(forResource: "secondtest.zlib", - withExtension: "answer")! + withExtension: "answer")! + + static let thirdZlibTestPath = testBundle.url(forResource: "thirdtest", + withExtension: "zlib")! + static let thirdZlibTestAnswerPath = testBundle.url(forResource: "thirdtest.zlib", + withExtension: "answer")! } diff --git a/Tests/SWCompressionTests.swift b/Tests/SWCompressionTests.swift index 16961547..ce53cdd3 100644 --- a/Tests/SWCompressionTests.swift +++ b/Tests/SWCompressionTests.swift @@ -72,4 +72,18 @@ class SWCompressionTests: XCTestCase { XCTAssertEqual(decompressedString!, answerString!, "Decompression was incorrect") } + func testThirdZlibFile() { + let testData = try? Data(contentsOf: Constants.thirdZlibTestPath) + XCTAssertNotNil(testData, "Failed to load test archive") + let decompressedData = try? ZlibArchive.unarchive(archiveData: testData!) + XCTAssertNotNil(decompressedData, "Failed to decompress") + guard decompressedData != nil else { return } + let decompressedString = String(data: decompressedData!, encoding: .utf8) + XCTAssertNotNil(decompressedString, "Failed to convert decompressed data to string") + let answerString = try? String(contentsOf: Constants.thirdZlibTestAnswerPath, encoding: .utf8) + XCTAssertNotNil(answerString, "Failed to get the answer") + guard answerString != nil else { return } + XCTAssertEqual(decompressedString!, answerString!, "Decompression was incorrect") + } + } diff --git a/Tests/Test Files/thirdtest.zlib b/Tests/Test Files/thirdtest.zlib new file mode 100644 index 0000000000000000000000000000000000000000..7623e24cd892a1b38bbf52e496613d1333f3b888 GIT binary patch literal 707 zcmV;!0zCaliLIAyZ`&Xc$KOxdSE;mpgFH2@lyqB?s&6b+SNj~(VsH;g)_wZnhh!v; z0Y`gd{t$i~2ggA~a$lB`gJx1pp@c2ol-cjEUq&yCGtE#X>k2tn$phOKdd737zl&lD zAKz~Fup5kSfVQZwvf83Svr7;#HYAQB&g2O;C1BC^q!drKDVazjQ)$c&Es=%~{6S1W zX`~SiC*usR@YU>4w9D&O{tF&luN4a1CljVW)+toDge^-~Mxa_qSw+x0w!@xkcB^Mp{L&^IrTJjh)as^kDIGJczi6X?xj# zUYPO)DVf^{AePR#+tjWADr}3MMgKu*G6t5&+buaU$FErU4TW}`O~N_nZ_`4yZhqVm(iO3T*{0a zrCYVI%Kn-%;67(QL*CPJf#Ls{erG1KEN!GV;oxYGl^!BEJD0oVpbF2DO>rj;b;T^t zG4&kJ8kpI$Q~WaUhOKsI#G9 zVmp>xpVqFUmcd;;c3&5)eq5f_$0qN407uZlEsx{-U0*Vr`{}-Z(YSgz;eFzIxG91z phMQ}!Yi))%^{27x)_&^^3~qzdKOCehWFiIX{;SOi{sOCr7@)xBThRaj literal 0 HcmV?d00001 diff --git a/Tests/Test Files/thirdtest.zlib.answer b/Tests/Test Files/thirdtest.zlib.answer new file mode 100644 index 00000000..2da144ae --- /dev/null +++ b/Tests/Test Files/thirdtest.zlib.answer @@ -0,0 +1,74 @@ +n\ImmolationDamage.mdx +Abilities\Spells\NightElf\Immolation\ImmolationDecay1.wav +Abilities\Spells\NightElf\Immolation\ImmolationTarget.mdx +Abilities\Spells\NightElf\Immolation\ImmolationTarget1.wav +Abilities\Spells\NightElf\ManaBurn\ManaBurnTarget.mdx +Abilities\Spells\NightElf\ManaBurn\ManaDrainTarget1.wav +Abilities\Spells\NightElf\MoonWell\CorruptedMoonWellTarget.mdx +Abilities\Spells\NightElf\MoonWell\MoonWellCasterArt.mdx +Abilities\Spells\NightElf\MoonWell\MoonWellTarget.mdx +Abilities\Spells\NightElf\Rejuvenation\RejuvenationTarget.mdx +Abilities\Spells\NightElf\Rejuvenation\RejuvenationTarget1.wav +Abilities\Spells\NightElf\Renew\CityScapeMagicRunesLoop1.wav +Abilities\Spells\NightElf\ReviveNightElf\ReviveNightElf.mdx +Abilities\Spells\NightElf\ReviveNightElf\ReviveNightElf.wav +Abilities\Spells\NightElf\Root\Root.wav +Abilities\Spells\NightElf\ShadowMeld\ShadowMeld1.wav +Abilities\Spells\NightElf\Starfall\Moon_Cresent.blp +Abilities\Spells\NightElf\Starfall\StarfallCaster.mdx +Abilities\Spells\NightElf\Starfall\StarfallCaster1.wav +Abilities\Spells\NightElf\Starfall\StarfallTarget.mdx +Abilities\Spells\NightElf\TargetArtLumber\GenericGlow2.blp +Abilities\Spells\NightElf\TargetArtLumber\TargetArtLumber.mdx +Abilities\Spells\NightElf\TargetArtLumber\WispHarvestLumber1.wav +Abilities\Spells\NightElf\ThornsAura\Thorns.blp +Abilities\Spells\NightElf\ThornsAura\ThornsAura.mdx +Abilities\Spells\NightElf\ThornsAura\ThornsAuraDamage.mdx +Abilities\Spells\NightElf\Tranquility\Tranquility.mdx +Abilities\Spells\NightElf\Tranquility\Tranquility.wav +Abilities\Spells\NightElf\Tranquility\TranquilityHealLoop1.wav +Abilities\Spells\NightElf\Tranquility\TranquilityTarget.mdx +Abilities\Spells\NightElf\Tranquility\TranquilityTarget1.wav +Abilities\Spells\NightElf\TreeofLifeUpgrade\TreeofLifeUpgradeTargetArt.mdx +Abilities\Spells\NightElf\TreeofLifeUpgrade\TreeofLifeUpgradeTargetArtHand.mdx +Abilities\Spells\NightElf\TrueshotAura\quartercircle2.blp +Abilities\Spells\NightElf\TrueshotAura\tjcrosshair.blp +Abilities\Spells\NightElf\TrueshotAura\TrueshotAura.mdx +Abilities\Spells\NightElf\Uproot\Uproot.wav +Abilities\Spells\Orc\BattleStations\OrcBurrowBattleStationsWhat1.wav +Abilities\Spells\Orc\Berserker\Berserkertarget.mdx +Abilities\Spells\Orc\Berserker\BerserkerTarget.wav +Abilities\Spells\Orc\Berserker\BerzerkerCaster.wav +Abilities\Spells\Orc\Berserker\Green_Glow2.blp +Abilities\Spells\Orc\Bloodlust\BloodLustSpecial.mdx +Abilities\Spells\Orc\Bloodlust\BloodLustTarget.mdx +Abilities\Spells\Orc\Bloodlust\BloodlustTarget.wav +Abilities\Spells\Orc\CommandAura\CommandAura.mdx +Abilities\Spells\Orc\CommandAura\CommandAuraTarget.mdx +Abilities\Spells\Orc\CommandAura\Flash.blp +Abilities\Spells\Orc\Devour\DevourEffectArt.mdx +Abilities\Spells\Orc\EarthQuake\EarthquakeLoop1.wav +Abilities\Spells\Orc\EarthQuake\EarthquakeRock.wav +Abilities\Spells\Orc\EarthQuake\EarthquakeTarget.mdx +Abilities\Spells\Orc\Ensnare\ensnare_AirTarget.mdx +Abilities\Spells\Orc\Ensnare\ensnaremissile.mdx +Abilities\Spells\Orc\Ensnare\EnsnareMissile.wav +Abilities\Spells\Orc\Ensnare\ensnareTarget.mdx +Abilities\Spells\Orc\Ensnare\EnsnareTarget.wav +Abilities\Spells\Orc\Ensnare\Tornado2.blp +Abilities\Spells\Orc\FeralSpirit\feralspiritdone.mdx +Abilities\Spells\Orc\FeralSpirit\feralspirittarget.mdx +Abilities\Spells\Orc\FeralSpirit\FeralSpiritTarget1.wav +Abilities\Spells\Orc\LightningBolt\LightningBolt.wav +Abilities\Spells\Orc\LightningBolt\LightningBoltMissile.mdx +Abilities\Spells\Orc\LightningShield\LightningShieldBuff.mdx +Abilities\Spells\Orc\LightningShield\LightningShieldTarget.mdx +Abilities\Spells\Orc\LightningShield\LightningShieldTarget.wav +Abilities\Spells\Orc\MirrorImage\MirrorImage.wav +Abilities\Spells\Orc\MirrorImage\MirrorImageCaster.mdx +Abilities\Spells\Orc\MirrorImage\MirrorImageDeath.wav +Abilities\Spells\Orc\MirrorImage\MirrorImageDeathCaster.mdx +Abilities\Spells\Orc\MirrorImage\MirrorImageMissile.mdx +Abilities\Spells\Orc\Purge\PurgeBuffTarget.mdx +Abilities\Spells\Orc\Purge\PurgeTarget1.wav +Abilities\Spells\Orc\Reincarnation\Gra \ No newline at end of file From 18b1a8c1683cd39cf42cd3828b47cfbcf989ffa1 Mon Sep 17 00:00:00 2001 From: Timofey Solomko Date: Mon, 31 Oct 2016 00:32:10 +0300 Subject: [PATCH 09/11] Fixed another problem with 'overflowing' shift. --- SWCompression.xcodeproj/project.pbxproj | 8 ++++++++ Sources/HuffmanTable.swift | 16 +++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/SWCompression.xcodeproj/project.pbxproj b/SWCompression.xcodeproj/project.pbxproj index 874d7e07..f68c0aec 100644 --- a/SWCompression.xcodeproj/project.pbxproj +++ b/SWCompression.xcodeproj/project.pbxproj @@ -44,6 +44,8 @@ 0655697B1DC65C2B00A47E66 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 061FCE301DBCC8BF0052F7BE /* Extensions.swift */; }; 0655697D1DC6963F00A47E66 /* secondtest.zlib in Resources */ = {isa = PBXBuildFile; fileRef = 0655697C1DC6963F00A47E66 /* secondtest.zlib */; }; 0655697F1DC6966300A47E66 /* secondtest.zlib.answer in Resources */ = {isa = PBXBuildFile; fileRef = 0655697E1DC6966300A47E66 /* secondtest.zlib.answer */; }; + 065569811DC69DD500A47E66 /* thirdtest.zlib.answer in Resources */ = {isa = PBXBuildFile; fileRef = 065569801DC69DD500A47E66 /* thirdtest.zlib.answer */; }; + 065569831DC69DDE00A47E66 /* thirdtest.zlib in Resources */ = {isa = PBXBuildFile; fileRef = 065569821DC69DDE00A47E66 /* thirdtest.zlib */; }; 06AC9B0D1DC1027900A5066B /* HuffmanLength.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06AC9B0C1DC1027900A5066B /* HuffmanLength.swift */; }; 06BE1AD21DB410F100EE0F59 /* SWCompression.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 06BE1AC81DB410F100EE0F59 /* SWCompression.framework */; }; 06BE1AD71DB410F100EE0F59 /* SWCompressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06BE1AD61DB410F100EE0F59 /* SWCompressionTests.swift */; }; @@ -83,6 +85,8 @@ 065569631DC65B1B00A47E66 /* Info-watchOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-watchOS.plist"; sourceTree = ""; }; 0655697C1DC6963F00A47E66 /* secondtest.zlib */ = {isa = PBXFileReference; lastKnownFileType = file; path = secondtest.zlib; sourceTree = ""; }; 0655697E1DC6966300A47E66 /* secondtest.zlib.answer */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = secondtest.zlib.answer; sourceTree = ""; }; + 065569801DC69DD500A47E66 /* thirdtest.zlib.answer */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = thirdtest.zlib.answer; sourceTree = ""; }; + 065569821DC69DDE00A47E66 /* thirdtest.zlib */ = {isa = PBXFileReference; lastKnownFileType = file; path = thirdtest.zlib; sourceTree = ""; }; 06AC9B0C1DC1027900A5066B /* HuffmanLength.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HuffmanLength.swift; sourceTree = ""; }; 06BE1AC81DB410F100EE0F59 /* SWCompression.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SWCompression.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 06BE1ACB1DB410F100EE0F59 /* SWCompression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SWCompression.h; sourceTree = ""; }; @@ -147,6 +151,8 @@ 06E63DB31DC3B8BD00D3A7C8 /* secondtest.txt.gz */, 0655697C1DC6963F00A47E66 /* secondtest.zlib */, 0655697E1DC6966300A47E66 /* secondtest.zlib.answer */, + 065569821DC69DDE00A47E66 /* thirdtest.zlib */, + 065569801DC69DD500A47E66 /* thirdtest.zlib.answer */, ); path = "Test Files"; sourceTree = ""; @@ -429,7 +435,9 @@ 0655697F1DC6966300A47E66 /* secondtest.zlib.answer in Resources */, 0644925D1DC6121800F10981 /* helloworld.txt.zlib in Resources */, 06E63DB51DC3B8BD00D3A7C8 /* secondtest.txt.gz in Resources */, + 065569811DC69DD500A47E66 /* thirdtest.zlib.answer in Resources */, 061FCE2A1DBCC6070052F7BE /* helloworld.txt in Resources */, + 065569831DC69DDE00A47E66 /* thirdtest.zlib in Resources */, 063364DE1DC51D33007E313F /* empty.txt in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Sources/HuffmanTable.swift b/Sources/HuffmanTable.swift index f5c69c57..18d3ce30 100644 --- a/Sources/HuffmanTable.swift +++ b/Sources/HuffmanTable.swift @@ -139,9 +139,19 @@ class HuffmanTable: CustomStringConvertible { } if (reversed && length.reversedSymbol == cached) || (!reversed && length.symbol == cached) { - return (length.code, - shift + cachedLength < 8 ? 0 : 1, - shift + cachedLength < 8 ? shift + cachedLength : shift + cachedLength - 8) + let addToIndex: Int + let newShift: Int + if shift + cachedLength >= 16 { + addToIndex = 2 + newShift = shift - (16 - cachedLength) + } else if shift + cachedLength >= 8 { + addToIndex = 1 + newShift = shift - (8 - cachedLength) + } else { + addToIndex = 0 + newShift = shift + cachedLength + } + return (length.code, addToIndex, newShift) } } return (-1, -1, -1) From 773c32dd442038c6c7696b1fcc54d059337c1da3 Mon Sep 17 00:00:00 2001 From: Timofey Solomko Date: Mon, 31 Oct 2016 00:43:12 +0300 Subject: [PATCH 10/11] Sometimes two bytes are not enough for finding next symbol. --- Sources/Deflate.swift | 6 +++--- Sources/HuffmanTable.swift | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/Deflate.swift b/Sources/Deflate.swift index 32cb9d8d..3dae56ae 100644 --- a/Sources/Deflate.swift +++ b/Sources/Deflate.swift @@ -111,7 +111,7 @@ public class Deflate: DecompressionAlgorithm { var codeLengths: [Int] = [] var n = 0 while n < (literals + distances) { - let tuple = dynamicCodes.findNextSymbol(in: Data(data[index...index + 1]), + let tuple = dynamicCodes.findNextSymbol(in: Data(data[index...index + 2]), withShift: shift) let symbol = tuple.symbol guard symbol != -1 else { throw DeflateError.HuffmanTableError } @@ -159,7 +159,7 @@ public class Deflate: DecompressionAlgorithm { } while true { - let nextSymbol = mainLiterals.findNextSymbol(in: Data(data[index...index + 1]), + let nextSymbol = mainLiterals.findNextSymbol(in: Data(data[index...index + 2]), withShift: shift) let symbol = nextSymbol.symbol guard symbol != -1 else { throw DeflateError.HuffmanTableError } @@ -182,7 +182,7 @@ public class Deflate: DecompressionAlgorithm { convertToInt(reversedUint8Array: data.bits(from: start, to: end)) let newSymbolTuple = mainDistances.findNextSymbol(in: - Data(data[index...index + 1]), withShift: shift) + Data(data[index...index + 2]), withShift: shift) let newSymbol = newSymbolTuple.symbol guard newSymbol != -1 else { throw DeflateError.HuffmanTableError } index += newSymbolTuple.addToIndex diff --git a/Sources/HuffmanTable.swift b/Sources/HuffmanTable.swift index 18d3ce30..635eb236 100644 --- a/Sources/HuffmanTable.swift +++ b/Sources/HuffmanTable.swift @@ -123,7 +123,7 @@ class HuffmanTable: CustomStringConvertible { func findNextSymbol(in data: Data, withShift shift: Int, reversed: Bool = true) -> (symbol: Int, addToIndex: Int, newShift: Int) { - let bitsArray = data.bits(from: (0, shift), to: (1, 8)) + let bitsArray = data.bits(from: (0, shift), to: (2, 8)) let bitsCount = bitsArray.count var cachedLength = -1 From d520249c8d90abdec0aa4e436d12e51abeaf415f Mon Sep 17 00:00:00 2001 From: Timofey Solomko Date: Mon, 31 Oct 2016 00:45:38 +0300 Subject: [PATCH 11/11] Updated podspec and changelog. --- CHANGELOG.md | 4 ++++ SWCompression.podspec | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efe4a794..b1ce87f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +v1.0.1 +---------------- +Fixed several crashes caused by mistyping and shift 'overflow' (when it becomes greater than 15). + v1.0.0 ---------------- Initial release, which features support for Deflate, Gzip and Zlib decompression. diff --git a/SWCompression.podspec b/SWCompression.podspec index 721dbe5a..558de0f0 100644 --- a/SWCompression.podspec +++ b/SWCompression.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "SWCompression" - s.version = "1.0.0" + s.version = "1.0.1" s.summary = "Framework with implementations in Swift of different (de)compression algorithms" s.description = <<-DESC