aboutsummaryrefslogtreecommitdiff
path: root/src/zlib-ng/test
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2022-12-12 21:16:02 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-12-12 21:16:02 +0000
commitca8acc408c13b3fa6a3b7601bc72e65cf773d94b (patch)
tree90ec8fe8b4f7d6b98f5460cf397f85578aef3ded /src/zlib-ng/test
parent55773c55c18b98b75ae923b6829ad703554877b3 (diff)
parent437ffc28c19eeff73c4127ec00f74bf134dbcae2 (diff)
downloadlibz-sys-ca8acc408c13b3fa6a3b7601bc72e65cf773d94b.tar.gz
Merge "Upgrade libz-sys to 1.1.8" am: 37720788c1 am: 437ffc28c1
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/libz-sys/+/2344984 Change-Id: I72c96910ddb4fe41c5ba03ed7ec89291eaef850c Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'src/zlib-ng/test')
-rw-r--r--src/zlib-ng/test/CMakeLists.txt103
-rw-r--r--src/zlib-ng/test/CVE-2003-0107.c22
-rw-r--r--src/zlib-ng/test/CVE-2018-25032/default.txt1
-rw-r--r--src/zlib-ng/test/CVE-2018-25032/fixed.txt1
-rw-r--r--src/zlib-ng/test/GH-979/pigz-2.6.tar.gzbin0 -> 106840 bytes
-rw-r--r--src/zlib-ng/test/Makefile.in58
-rw-r--r--src/zlib-ng/test/README.md11
-rw-r--r--src/zlib-ng/test/abicheck.md4
-rwxr-xr-xsrc/zlib-ng/test/abicheck.sh18
-rw-r--r--src/zlib-ng/test/benchmarks/CMakeLists.txt96
-rw-r--r--src/zlib-ng/test/benchmarks/README.md47
-rw-r--r--src/zlib-ng/test/benchmarks/benchmark_adler32.cc89
-rw-r--r--src/zlib-ng/test/benchmarks/benchmark_adler32_copy.cc117
-rw-r--r--src/zlib-ng/test/benchmarks/benchmark_compare256.cc84
-rw-r--r--src/zlib-ng/test/benchmarks/benchmark_crc32.cc69
-rw-r--r--src/zlib-ng/test/benchmarks/benchmark_main.cc26
-rw-r--r--src/zlib-ng/test/benchmarks/benchmark_png_decode.cc126
-rw-r--r--src/zlib-ng/test/benchmarks/benchmark_png_encode.cc54
-rw-r--r--src/zlib-ng/test/benchmarks/benchmark_png_shared.h146
-rw-r--r--src/zlib-ng/test/benchmarks/benchmark_slidehash.cc86
-rw-r--r--src/zlib-ng/test/data/lcet10.txt8
-rw-r--r--src/zlib-ng/test/deflate_quick_bi_valid.c85
-rw-r--r--src/zlib-ng/test/example.c335
-rw-r--r--src/zlib-ng/test/fuzz/CMakeLists.txt44
-rw-r--r--src/zlib-ng/test/fuzz/fuzzer_checksum.c (renamed from src/zlib-ng/test/fuzz/checksum_fuzzer.c)27
-rw-r--r--src/zlib-ng/test/fuzz/fuzzer_compress.c (renamed from src/zlib-ng/test/fuzz/compress_fuzzer.c)5
-rw-r--r--src/zlib-ng/test/fuzz/fuzzer_example_dict.c (renamed from src/zlib-ng/test/fuzz/example_dict_fuzzer.c)11
-rw-r--r--src/zlib-ng/test/fuzz/fuzzer_example_flush.c (renamed from src/zlib-ng/test/fuzz/example_flush_fuzzer.c)5
-rw-r--r--src/zlib-ng/test/fuzz/fuzzer_example_large.c (renamed from src/zlib-ng/test/fuzz/example_large_fuzzer.c)4
-rw-r--r--src/zlib-ng/test/fuzz/fuzzer_example_small.c (renamed from src/zlib-ng/test/fuzz/example_small_fuzzer.c)5
-rw-r--r--src/zlib-ng/test/fuzz/fuzzer_minigzip.c (renamed from src/zlib-ng/test/fuzz/minigzip_fuzzer.c)14
-rw-r--r--src/zlib-ng/test/fuzz/standalone_fuzz_target_runner.c5
-rw-r--r--src/zlib-ng/test/gh1235.c39
-rw-r--r--src/zlib-ng/test/hash_head_0.c110
-rw-r--r--src/zlib-ng/test/infcover.c18
-rw-r--r--src/zlib-ng/test/minideflate.c117
-rw-r--r--src/zlib-ng/test/minigzip.c3
-rw-r--r--src/zlib-ng/test/pigz/CMakeLists.txt212
-rw-r--r--src/zlib-ng/test/switchlevels.c4
-rwxr-xr-xsrc/zlib-ng/test/testCVEinputs.sh30
-rw-r--r--src/zlib-ng/test/test_adler32.cc (renamed from src/zlib-ng/test/adler32_test.c)356
-rw-r--r--src/zlib-ng/test/test_aligned_alloc.cc46
-rw-r--r--src/zlib-ng/test/test_compare256.cc80
-rw-r--r--src/zlib-ng/test/test_compress.cc33
-rw-r--r--src/zlib-ng/test/test_compress_bound.cc59
-rw-r--r--src/zlib-ng/test/test_crc32.cc219
-rw-r--r--src/zlib-ng/test/test_cve-2003-0107.cc28
-rw-r--r--src/zlib-ng/test/test_deflate_bound.cc90
-rw-r--r--src/zlib-ng/test/test_deflate_copy.cc60
-rw-r--r--src/zlib-ng/test/test_deflate_dict.cc54
-rw-r--r--src/zlib-ng/test/test_deflate_hash_head_0.cc83
-rw-r--r--src/zlib-ng/test/test_deflate_header.cc68
-rw-r--r--src/zlib-ng/test/test_deflate_params.cc143
-rw-r--r--src/zlib-ng/test/test_deflate_pending.cc66
-rw-r--r--src/zlib-ng/test/test_deflate_prime.cc91
-rw-r--r--src/zlib-ng/test/test_deflate_quick_bi_valid.cc80
-rw-r--r--src/zlib-ng/test/test_deflate_quick_block_open.cc (renamed from src/zlib-ng/test/deflate_quick_block_open.c)58
-rw-r--r--src/zlib-ng/test/test_deflate_tune.cc56
-rw-r--r--src/zlib-ng/test/test_dict.cc96
-rw-r--r--src/zlib-ng/test/test_gzio.cc105
-rw-r--r--src/zlib-ng/test/test_inflate_adler32.cc48
-rw-r--r--src/zlib-ng/test/test_inflate_sync.cc75
-rw-r--r--src/zlib-ng/test/test_large_buffers.cc87
-rw-r--r--src/zlib-ng/test/test_main.cc17
-rw-r--r--src/zlib-ng/test/test_shared.h2
-rw-r--r--src/zlib-ng/test/test_small_buffers.cc69
-rw-r--r--src/zlib-ng/test/test_version.cc27
67 files changed, 3623 insertions, 812 deletions
diff --git a/src/zlib-ng/test/CMakeLists.txt b/src/zlib-ng/test/CMakeLists.txt
new file mode 100644
index 0000000..8b250ed
--- /dev/null
+++ b/src/zlib-ng/test/CMakeLists.txt
@@ -0,0 +1,103 @@
+cmake_minimum_required(VERSION 3.12)
+
+include(FetchContent)
+
+enable_language(CXX)
+
+# Google test requires at least C++11
+set(CMAKE_CXX_STANDARD 11)
+
+# Google test requires MSAN instrumented LLVM C++ libraries
+if(WITH_SANITIZER STREQUAL "Memory")
+ if(NOT DEFINED ENV{LLVM_BUILD_DIR})
+ message(FATAL_ERROR "MSAN instrumented C++ libraries required!")
+ endif()
+
+ # Must set include and compile options before fetching googletest
+ include_directories($ENV{LLVM_BUILD_DIR}/include $ENV{LLVM_BUILD_DIR}/include/c++/v1)
+ add_compile_options(-stdlib=libc++ -g)
+endif()
+
+# Prevent overriding the parent project's compiler/linker settings for Windows
+set(gtest_force_shared_crt ON CACHE BOOL
+ "Use shared (DLL) run-time lib even when Google Test is built as static lib." FORCE)
+# Disable pthreads for simplicity
+set(gtest_disable_pthreads ON CACHE BOOL
+ "Disable uses of pthreads in gtest." FORCE)
+
+# Allow specifying alternative Google test repository
+if(NOT DEFINED GTEST_REPOSITORY)
+ set(GTEST_REPOSITORY https://github.com/google/googletest.git)
+endif()
+if(NOT DEFINED GTEST_TAG)
+ # Use older version of Google test to support older versions of GCC
+ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS_EQUAL 5.3)
+ set(GTEST_TAG release-1.10.0)
+ else()
+ set(GTEST_TAG release-1.11.0)
+ endif()
+endif()
+
+# Fetch Google test source code from official repository
+FetchContent_Declare(googletest
+ GIT_REPOSITORY ${GTEST_REPOSITORY}
+ GIT_TAG ${GTEST_TAG})
+
+FetchContent_GetProperties(googletest)
+if(NOT googletest_POPULATED)
+ FetchContent_Populate(googletest)
+ add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL)
+endif()
+
+set(TEST_SRCS
+ test_adler32.cc
+ test_aligned_alloc.cc
+ test_compare256.cc
+ test_compress.cc
+ test_compress_bound.cc
+ test_crc32.cc
+ test_cve-2003-0107.cc
+ test_deflate_bound.cc
+ test_deflate_copy.cc
+ test_deflate_dict.cc
+ test_deflate_hash_head_0.cc
+ test_deflate_header.cc
+ test_deflate_params.cc
+ test_deflate_pending.cc
+ test_deflate_prime.cc
+ test_deflate_quick_bi_valid.cc
+ test_deflate_quick_block_open.cc
+ test_deflate_tune.cc
+ test_dict.cc
+ test_inflate_adler32.cc
+ test_inflate_sync.cc
+ test_large_buffers.cc
+ test_small_buffers.cc
+ test_version.cc
+ )
+
+if(WITH_GZFILEOP)
+ list(APPEND TEST_SRCS test_gzio.cc)
+endif()
+
+add_executable(gtest_zlib test_main.cc ${TEST_SRCS})
+
+target_include_directories(gtest_zlib PRIVATE
+ ${CMAKE_SOURCE_DIR}
+ ${CMAKE_BINARY_DIR})
+
+if(WITH_SANITIZER STREQUAL "Memory")
+ target_link_directories(gtest_zlib PRIVATE $ENV{LLVM_BUILD_DIR}/lib)
+ target_link_options(gtest_zlib PRIVATE
+ -stdlib=libc++
+ -lc++abi
+ -fsanitize=memory
+ -fsanitize-memory-track-origins)
+endif()
+
+target_link_libraries(gtest_zlib zlibstatic gtest)
+
+if(ZLIB_ENABLE_TESTS)
+ add_test(NAME gtest_zlib
+ COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:gtest_zlib>)
+endif()
diff --git a/src/zlib-ng/test/CVE-2003-0107.c b/src/zlib-ng/test/CVE-2003-0107.c
deleted file mode 100644
index 51c79b2..0000000
--- a/src/zlib-ng/test/CVE-2003-0107.c
+++ /dev/null
@@ -1,22 +0,0 @@
-// http://www.securityfocus.com/archive/1/312869 --- originally by Richard Kettlewell
-#include <stdlib.h>
-#include <zlib.h>
-#include <errno.h>
-#include <stdio.h>
-
-int main(void) {
- gzFile f;
- int ret;
-
- if(!(f = gzopen("/dev/null", "w"))) {
- perror("/dev/null");
- exit(1);
- }
-
- ret = gzprintf(f, "%10240s", "");
- printf("gzprintf -> %d\n", ret);
- ret = gzclose(f);
- printf("gzclose -> %d [%d]\n", ret, errno);
-
- exit(0);
-}
diff --git a/src/zlib-ng/test/CVE-2018-25032/default.txt b/src/zlib-ng/test/CVE-2018-25032/default.txt
new file mode 100644
index 0000000..5edbff6
--- /dev/null
+++ b/src/zlib-ng/test/CVE-2018-25032/default.txt
@@ -0,0 +1 @@
+OBXESYMXQLOTSVVWGIMGKKJOVTYKPPMYROFHSCXQPOFVHKBKAFYYAFTWCVOBPXWDSSFZCKBJOJUWPUQHKBNYZMCYEDEBXLAOREOASIEPAISNAZSXQKMWJSABFVSOXNKTGDCZKRSNBTWWGRNRZWGQEHKKQJGSGGFWJCETJVULWEJAQPAILMMQBVWJWMHWBSIOAXOQNEJYAQSPEOACRIFYOFHTBLZFSHOYGQFDGLLCDEHGPRAUFMANGCKZNZJBMEAEDDPZPJMMFEQGEUOHYFEQUKKHTOELBFUVDMNCEGPTLQYPDFTUGGOEUMUIAKAAZNXAEAKZREKXSZZAKFMHDZJFQDLLSILAMUHDQJTVMYIZWFEOPCKWVSXYDEOSGVWACWZNDDTOOYSFCOYHMCUSELFMSBJIUMPFOGDDJGHELQJSUAEEOWQEJMWRRBBAANVFEUMJZRQGDIWXOYXCZZLMDRHPJAYGUUJENSDDGBKDFRXMINPXRZJNAUPBIOAAKLMFUTZWAEWIBUTYOLPPNUWMFYJQIEMJYKVRNKRXGODFFRMMSKDBBKRJGUWOFMNKQPJLCCNDOTIWVGNWVIQINFPLJLEQRMNSVYFGNWMWYGKHBRSLPCCPHUNXIDKDGIELLDUIOXAJOZGIJVKGBJMGSCOHPRFVUPXJREGBMUXNSCBBRASVMNZHELWNHROPZGWIYMKESWGWNANICQTNICGQBJLAONQEEDEYUIGAOQCDTVBLSSACVCUAURKRLCYIHAYHZZCBVMLALYJKNVJTHYTFDDZVOQBUSDTPERXSTYJKCOGGFLBRQIARKTDBQHSFBBEEWYIEOOHUWKUGACNGZQMAHWPFJJOHMJGULPPXYTCIHIAVYTAHIZMBMYYZXBPLTRWNEDAALDOWVQLNFWZEVSDWQBBYHUYNOJYXVFQYGKSHGCRDPPRSVZWXECEXCWOYSBRWIBPZLHJKHWVTZYXEYGUWAXEUONCVLUGHLTCUTVSUQEVBRYYCIZESPFTGKDJKDQYNIXWZZYSCWIULGKVRJOLQNMWMKJKYOZGXFDUHXEFEFHUMHYKYINHXMINEEJAFYQLHEXBTTEBWGWEAWYODLKRFWATZYJXAFECXRPEDRKPJTJBHFQYFWLCYPMTASYYIHDGURAAUJYTKAMDUNZHXYGPHJVJPODIJAXYXONXEULMKEQRKUYAHLJLTVJUPMYUQSEMEKYCYBPNDDXRNZUQYHDBITAYHMBXSOETYJDWDAKRJGBIUSIUIKBQPSHOVDRCNSBUYDPAPAXBKHLIGEPMOUBYFXAMXDEASVXOUIMPVLCQQJRQNLIDVIRYOEXXIUASCSMSTQECGPPHPGDLJLCRJTWSHVOUNQNFTQEHOIQIUWTOFEIKBCWNLDYIJDUWPBIBBERKPKYYUWNIMOCMAUEVBLHBYLQEALQVTQYNTGASZMJWOPCUVKMJEZFKJZMCOORIKNUZQAPHVYTTSJUBBYFJJHTJRYCPRHVLZFPNXSSXXJDWDJQVSJVUKVWUYGPLBGUTBVLMNOFYUKIKIVBDCIKAKVEQIPBPQRLOSZXNIGIDKNGCLILUSTJXYFJZKRAJONNYAANNTWVDXYTIESYFRGQVIOLUBOHGNAGKAKZTRSYYIBADADFBHLJXDYPQKWAVHQGWZKKWUVAFWGXBEBNVPUDWCOMMSXJIVVLDHAWNUTQAPKVFGTYMOKTBDBQZTHHAWGRANXNAVWIOIPILFNUKUFVLNNLAFFPHBLFYMHYOZKABEYKKEDHYMBDIGAFUHTJOOIOWOLLKINJMOPYNNMBMRXNYZAHQYOTDNKWDIDBPSZJOEBQWPYHZZTHSFVJAQDFBJHBOBLOKJKIOEQTWPFSXZCKWWOXNEIDFXVWFPPEFTXLPHMFVPZYRKZVHHDWXVHCASKVDKHWNIUMJUEAAKSFYAGUUKLYGDVDPWMKIDQEUEDLZWQJLRSDMLSHKIOSDUQIDIAGIDEQZBUTVLPUFEXJCCJRGCFXNVXRRNSTWXCXEORNNMFJFJUMOWOSLUUYCOQKLTTUTVGSUCKXQGPHWFZOHALSARGDPDYOIFBXZCDEMHVNTDXTHZOZDOGCZYRXEWLWLPTMCTPCTYWJXNRGSYJDRCFIRRCLFSZMTVXMHASZQGVHHHFLGZKDGMGAHVNHXROKDARLQWIYXXRYTERPSEDVYETTARZTXOTUGAHTOHOOTMCJBZKNBBQHAECEJFUEQQYXNXWBAUIESPQGIOEABZTMSUIVNUIOFYGLSTUVHKPIVBBHAPSDEXZPPAFSLSJSKGEGKXQZGZYYYBFHEKOQUZEMBMTLXLLAJMEFEWLECDLUWLMQLNZDXGDHRMCOOTGWXKTDFKFGEJSLUEYWDGRAONPHKSKCTXQZCEYMQSUIWTNCQLAMABCIZAAOJCLGRBWRFCQKSTYSDDYOZOSEPYBBVEKIFDJOEVAAZBYYKHPKNNWKNIGMIBUDADWHVKSWCMSWBKQAHBNFMWKFPRSBAJMJCAFAENZBVDSYGEPAYDMDRJOUZCGHQNDAQQZHSBMLPWOFGNNODEZZZSJUOOOPBYSEJFZOSJQGTSUBQCOTVNAXIZFMVJUFWGDDJWRBHDUTNQOSYJEWTEZXOYUQXKOZSBYEQKHOAEUEUYOMJLRHGQKKCICCLNIKCMAXLJZEWOYSTVZWXDXSXWVEWJRTDDJIDEWOYXXKGKBHDEPXZFUPVYWJDHXJENZANIEAUIZBXRIZFHMVKOUHRKRUALDIQSAOLIBFSRNBNFZHAUSGGMYSXJROAPNFXOWSFWNRJCAEFJDNDCRQDEOACSMGQQSQIVVVPSTTEPWFLQGJFOXUKFEMTQTUZRNMUPLLQQPNYAIIOMGQETSURJIJDOVGGWQDIKSGZYSJCSVPETTGRKXOXPMRPEMCXAXDDQTVOWDUGPKRCKRRCBRBDEMASKWEPIRHBKGOFGUNVXQMTSKOLAYJKMAGDLLMOPHDAHXBDQMYMGVVREVFLEZPXEXXFORECDRSTSWXGRNRQPSAXXIZXOQPDLEBDHDAUOMAGPFWVMWCQLMXDXKSFAJZBLNQLLRYDBYPWDWXFCTGFHNJVKMYONKAAGXCALJCRHZWYODYFRXVGVIGYJIQMUOUYPGDHFVEUTZRLFILMZXFRXHNELGMKVNYKNITXYHGZDGYGLXJXBODBAIITGQNUJOKJTAUDJFRKLEVFWBARAXPOPPXXDAFZBWAYFAQICNUIRRVRZURUHGWMXELBHDGYVRNEFNEFSPZUNOTCUNGFOAWYCMKVCDTNPIHWLJLWXVORXFNSKJVRAHBJCFMQHVMLKAKBQPMGQYUEPHLQSZJBORIOJAPWJLHYBCXTMZPZUWJIZVRBOYWQIHRWXGYWQQZLTLNHZBSJLIBKJBQNNWSFLYVBYXUZFSGQZZYRPPKHYJCCYZBIEWATBDYLJLJGNCAUHLELJZVYRPJNFQIFLIGLEPQEVOVKASMSJZRUPZNQTWZJHXLVRBCNXKUXZCNQKHIJMBFPXNLPBPYUOWEIINXMUYGYRWPNQPBQPRFCBCIIKWKJWKQNRNZAFQCXUUZFPHBMQDSLYKQJKAJNAHBETGJPYAHMWHMNUJWMUHKZHPNPDZQEPDZZKGDQOUWIUPWSBPJQSBXAVFXJJUFTOCRKJGHKASOTJXBLQRKVOLJTOUUUYXQQNUSJCOILWWGYRJAZXXWCXAZFQITHUYREGZILSHQWSADJRTIVYTZSAGAXQHDZYZERPDHQOLOFAIWNLYACZRXKFKNOHQOFXFIKYWRRDPUFNTSBWQYGGQFNSRBPHBATAWCSVFANTUQIVFSEHGGELSJAUZFRBDEMBFXMFMOTENHPWKEVSIUOEPXPCKMSGDWWORTXBPTAOZPLNCKJUHEPBLCPRRXLGXUHKEKFIYXNJCYTNXMVEXNNAGESQWJGSFBCCQXLSXQJVVJUIZFNIUNAZCVCNUQWFPBCPRSLKIYLDOSOHOPABPMIVLSYIZKJHBCJXBTQHVEFIQHYEGYDMXWSNVWNGSAXBSDBCBDOFVNUFFVWGHHDBIGMNPFLGPGOGSUFYISQESRSSKCEKUTTUTNYYPLKSEYXIZGBPCQVRYGFKYVDYVKKIONENEULDVNMPKFKTAOBDKBCJBIWBKYLYESVCHCSCVVVWXLIMUDNWJQYJQJIGVGJXZQPUEGYTENAMCPDMAVXXOHZCNPWLKGRSQGCNXTPZNTWGFRDJIOSPAFNJHGUHXCDLWSWEHBXHOPAHBQMKECIGDGVGKRYRGLSIVCYQZAZJWGDJWIFUOBIHRENRDKEXQRJCSNMVTFQBJAIAKTPCBINZDYCRLPFSPCNQLDJYSQQWDNZNIEMYZCOIBALBGXXOLLRIVBDQUNXFLMGRIHDFDNCNCFBTKMOOQSLXSONNDFGNWGMAMGIHCDFZZFPAUCOBYJCOCHYVDKNDSOTVGMHSWHOQFCYXYIMFHJCVFCVJGATFWRYPYLEWTNFVTZDATIWNNRYQFTXDGQPPYQYOJJBYSJLADOODZYJIWPIWYQFTGFYESGCCOJFOSQWCQDULHBXAYFDJEJOLOBHTMGXGNFUUFMDIBXDYFVHLQDURYGCSHIYGYJHMJQUFIUBWAKDIFXQEUGYKIFMMSYKOMVNKCMTYXWIBEYNHQHNMYKSPSZTKPTDGMODMAXEHOABRZOSYYLHYWPIQQFMXODEYOAMXDWIFNLAVHTUHSCPJQGRMQNSIZQXNJEEFFVOYAZMQTPNBGKMXYFLYCXQVMXNITCYDMKNTBSNKPGOFRMAGENQZQEPUMRLHFIPOZSJDOBQYSHDETQCBBLXJAMHIPPHQIIBNCAOCVCOHQAPYCYEJBIVWSJVIOFZYAKFYEIXVDVIVAXJZQZKUOCGGBAHHPVOADXHBWEQRMVRBKOONFLPDCKKBFFIZJIKRYMEWWYATRBVIIKBUACMLRTONKOUXMZCGSSYFCYMNTBVIENZQXDTYNZGOKCRENDDTNZOQRXLDVZXLOTFOVYAZEEHKXRDGECGCGXNVMYOKKNIQPCPRWRAHKVPZSKRBMEAAFDAWXXHJUBOUOYQWPLZGTMWWYFBGBNUAQBSRHKNUGGYYJOZNEOWWYZBMREVSOVTWVLUDCJWQGJPFHPTDHFEQVJJIYARMBGCTSKXZQFGOXOXHMWBOHMEFKRWKJPOKUQRQLCHHPNWEPJFIAPSYAHXUPHYOAPABLLDFZOVSJFNNHVDPNWXPXFEYADEXFVRWKVBVCEOVMFIKPMABJUBGOGCDADYIEWZZZCANXEXMMFKHOWOMJRJTKBJPYRPHNKHPSQRJXJNQPORMUKIXNFRIXUGLECEJYZXSUFTROJJRAAHGUDXXSPKOTBUWJPMVUDQGBAPSQOWYDPVVEOISXLDKOPWANASRPSICRGBNHJQGPSFRPFOZYIRYEOFCQRZWCRYAARQBLEAJDQGQVIFGVCPFSEIBAUYXUXFQMNWFNLVYDFFDCVAISNQYGNCXLKXERSQKRJOFLTSOPRPQQONCVGVBLALFFJLSTSGNTHWHHBTNCFRQLWTGKPWIBWSUEVHWFHKAMBOQMZYGAZRAEJCFBEWEFLDGPMAKCQXCLFMBIVDECFIOOXPCTKCCJDZPECXVACPBOQVWNYAZGRIFJETXUABRDPOQOGZLWPLZETFWVYOZHYGSQVMNUMYIAPFCCJNQOVKZCEMMNFRLVTKDRUTDNAQXGPTWYGRCEOTQMLESJDAKGIZNSTADDAIMCUKZQLWYUPHWSQELFHEZOFGRBVUSOYZQMGJFBWWCGYBEFIHCCJKQOAFXAPJEMFJCVZAYESUKQVKHGHGJMTBRECBCLFMCIIBJPIWFRROVXDCPTTEUFOMAFJUHXLAHELLPYCVZDPHKTVGLRVVUXDKISXVAIYEXVWLSQPGKGPYXLXIYQSPYEQZZVHAVHSNASXOWRFMRSLNPUDTWYYPJRFGPJIGTZRTNXDLNAEKRBSZPMZHWPFPGLZVDTSAXANFKOPCNWSRWZMEBVUOCZEMLSYVDURZQUVRZOPKPJMRDQPBGLZCFADBWRWKABRGOMGKIOLZEAJHXIEIPINCETSTKEGEDYJNZBIWISBSDTZREGNOIXNYFQFPUBQLGWKHTJVSCTUHKYWZPSIIBJFKVQPPQCKIKNDEIRXHIBAPDDXYIBMWNUPOISTKFBXDELZFYBRVAMLLPQQXGMBMNBTJRCNCGGZMHIWKJNAFWYYCHEJVYVXPUWZHBWPKHMBJNGWWLXRRKPZHQLTPKGXLWZICJMFIVPRLSXVUOFLWNHFSZAUJTYFRTSPSDOEHFYFHTNZOLRTYIQJQSEEVREMWRKLEVXOGDQMQZQJWTHOYIGOJLJUFBSZJLHGYRRJSZRCNQRCNVBDRCOYENFVWULRBHOGLLRKWMFXEZKBZDMDKYKFJRIHGUZOHBFOPJLMWXECZVXYZPYAIKYDDVWAXCMPKOTEFMIRXDOFFQCNAUBGHGYVFOCONJWNXDMIANMLMJOIAHRPTVNYWLSQBBTNJLBAAQMTJXLXADGYLLMUZPCYFOGJGCJORRTGSRLDXYODWLVGHYBYLHCGPWWEYJPMSAQWNRNHPYLLHUJEZTRQYJVZEJFUQPVTIKFITRVXUODHQDNWOXVHXFWDVRLTKPJVKKEUMYFDOZJOSCHWQQTFKUFMFNQNDCRTVHSVOFPUOMVDEWGUASIKYZPJUGIDUDPTOVAYGMQWLGSUMCWOEKCGYOMZJNRVSUKJGYQBFZMUINTJFOQOVPHHJRNCSUPDAVMSSRCYMJGCGRRIKLAUTKOMWRNKOZETUTSKNRHXRNDOGXBGUGTIXOLEKKOTBAAYFPJHNWKUNMDFZUTRWTLWIBFJGMXMMZLHTJLWVVPAFGJVPKAPPIMTMTOBKXSXWOEWIWIIHPJGKDXCNSYUKAWUCBHJNYHIIDJZRPQPVPYIZZMUFCHOQGNXGAMHEULGHOTRFKFLRPAOYUQYSXLSVVHYXGBLSDOBBZRMXEQCBTNUOATVMYSTKGKQNEUUEWCWBNGWMWIEYDTLBVZHXDUUDXNHJRXOPSLPTTHSOGBGBDSNAJWCBJHZGIABQFONILLESWKMHLIDLBWIDWODZFFKCUHMPMBMYEJUGAIOECPPIYQGFNJCLAHJUQMNTHFJOFOJOTRJDXMGPJYFVDCHLCPRMYRRLMQHQJYQLWMBDYFFZZYWSVVTBFMHXHEAWXYSXTWBNEZKDOUIHUQADPIUKUJXZYHUUUFIGBQIHNLRXUOVMEUSILBUBWEBQRQFQMHOWCEUVUXNNJLNNKGSSEQQZNBDVJYWXLAGGHSBUUFAKMYKRHCATRTMTMNEQHNQWUOPNAWHOCGIEROSOMDJJCQQLSXZVZRVKUALQTFJUOQWMATSZTQBDINTLRDTMHGPIAUONZVDRSFOTAFDNWLUCSYCKAYVCAAYJOZPHPDNIJOGBOGTDLNXHYEJAEECJFZNDMEIDSMGEWTWWSKWSQYEDZFKSRNPQZTGNYRTQVWDBGKJYVAEJZWSQAHWNOHNDRHZAUYXWSAMCNPJBYLNPIPNIFGXQDGRZTQPXETWLZDZVKIQILLEIZDDFLAPQFYFHTUHZIOYZLIGTJMFDATODQNBIHQIOZUTQQGFDCSMSZAFKJFXXYTDGWDVMNLTBZCIDNWXWYXANDDGVPMWGCRHAQOVWPXHVWBQLSCXPPJDYQKLVDBWZBNATRXCPYBOHIGLREODDUVFWLRDSOXYICZPITCQXTJCYGNQPKZXGRHOEKOZTMAYZLUHUYPJKHHFTVSDKELBLVBFNULMMSIERUKEVLCMBRBBHOFGVFBIFFXSYKAMSVXDYUIOGBHLKNNXJTEWNDQJNRGJMKVPFRIJHKFRNTTDSPRECSOIFJUXSIEREFEIMXBMWSBGDJPVIUJUEPAQOOOQZGNZORAKQOVJKDAWSLXSJHQHUIASLQVJDWWXLNPVSWXOGMGUHLKOQUYMGTPKUUEEEHXZVMIBDQJSNRDDFZEOEMMOIJLEYDCDDXGPAYEMXDRXERZYPNHNWOLOTPCDDLLHQPLBHQDKTVJNMFGAWXDHAONUGAWQLTOQSCOMVAHYTYHXQVBKENQKNVOWAGEZVUVWVQKDQPERCLETOCMXIJXDMJRGCVAQUMWHDOUOQQAXOHBXJDRLYGEWUZTIMSTMUCZGOPEBSWIQGPGMTIEGWNGRQAUQQGSLVWKCZTZMOTUOVOCDYLPGZTMNVGHSAGHRGPVTEYZKBVUQNYTHTVMWIEMREKWBVRXLHEGZMHKIWOMOZFPXDPXXPOYFWRLUSBBFXRZWGXAIYYSQFEWQMWRHMYMLFFMBOGAZSDJRENVAQXGDCKMRQYQGWVIDECLOMNZYCCMRCLXWPUIWGNATOQZUYIRDXGCOGZIJRDBYBBNFMOEPYUUJYZJSGICOMXWBAUMEBJVWGTRDRYQGNONJZXSZDJLRAMLJLFTFZUVZZOEOLKFOGFODQBWYBRDMUKEFLKDUADCGKYTZUCVRUULXCXMKAZCBCUQLPAWCHHIFIPIXFZRJHATGQCRWCCMSDXRHASKDKACAVAPMYIYUEXZFJCRPMOTGZJLCFOHJMRRCADBGLMQTBZAMGGLIULVTBOKKZTXRODXTAZXQSXDHPVFFPFLMJKDJNQYGLGUNVIVUWJBCWDYASMCYPTPFZBVUCMUWAOYOUBZZTJEQNIZMPPEHRJPJJKAKHRNGIHUGRGZGRYCOIWXFDDHJKQHSOVNQLYZLABMFFWVQXBPNWNGYMYBLPTLLLFAPTNNBPLCKOIUBNPNCBHJIVUAVRENTTPRWXENQAOUPPEMSOIOLXMQFIAYVPLSCZLYDIOLZIUCBIBYNAWSOUQXDYZPQQHWAQLZCJSRDUUPEKFYWYEFXOHSILHHIJDERCNZEPHGODFOECPZONRLPCFKGUXNFOPVGSQCPWNMAVTPMGSPJRRFIHYXQAGJQWYBBBGTFAAODFFZKDGCEZTHQNZKXKQWFSJKIKTWBZWWRFYIOVWXXZYYMPLUJZETDXGJUASQTPZVBPYKHJLHSCONRZWBUZESWAOXWUMPORTJCQULFBHWIOUOPZIPLZRDCWOCQXHPKNHOYXHTKOFFVIZLGMJMKXQLYEURGMQZRCQGPPLUDLECVBNVBHAWBITJYAVUJKXPAKZDBJGMOFUVOYVAESRHLQVZRDOZPZDWJDWGNXBEQVIKHYIXRIANMIJARWDSAGDKQCYRGZZOFEGXDCMWCNYHDFPOYKSZIGNWIUBSAXPGPDRKERFWILYDILHHXGKKWEWCLLUQDODMHSAHQTOXPLMTTVXRIVIRTJRQFXQHTVREBIXOLZSFNUBXRFSQHSBFHUMMTNVCNRDCAQPSYKEUYHULCSKSYULEQYMQHHKELFXQIPWPEBNBCLVBYEBTQQAZKHWJGIHDVFZHDSHCZPHCWOKRWGSLGCOZEAYLTFJSEBTMOELSJXEGJGCOQPURSZOGOANVZVBTTGLPJYSNUSJUCACWAUTJIAIMIAHLMTVRYONFWCHRYGLSJITEVEFHCQQKLVXMVMAQNEKMKRFJIEUZAPKXDRTHBKEDMSCMNZHOSLFUTXUIDFPKOWRDRADBCWFDZSAJOYSLZMRFLOPUHMXOEECQDNRDPUXFQPOYAKWHIQWIFVNOOAQQHGUYVZRFCLYJYYTROCMSRKXLBHMCBACUNCYLMEWEHTUPFFRJEJAWKHYJUWBUQRKFMHOYSBSMZVIJNRUSEMSMXLPQAKAYVGCFARNHOHWTKINTCYLVNWRGALUZBIQQFMQGBXKAEUFDMVOTJLZGOGMIDGUUSACUMFMGFVDZIRWAWFXDBNJZJAOAMXFVBNMJBEJNMYVOJWLSBFISAKMCOVAKYHBPHHGLYSLZLHPDFCQRPFKUOXKFXZASEPZLMITPDIDENSDCGPFRQKGEZQNBMVWMDGUJMPHMPZAAMSAFRQGYAAGXGUGKMLVMZSSQSREGSOVWUXGQIQXNVIDJDHGSKNCWYOUOEWGVESAKGSMGBGEOZMIUYOPIAJXTBQNXEGCXMVHMOVNHLBFKQFNLOEKISQFNEKNDLGBIBAOEWNBALNSIKGZPWOMLAMTQZPCGLCTPDHFQBNXWFTAPXFRCKHHGLPXKDIXEWPYWOAIAHYJEVXCGFBVROFIVDABRSAHRXGALKMXWARMJZMNBFAMSNXOXOFYMFIXDLEUOBQEHZCXRZYJNEXRDHJZSWZMGAKWIGKYXGQFSEAXTXUWHOKWKINLVBVPTHQULCWKGWKJTWVWODZFFVMTJIATOYRHKRUDKVHJPJJDFJKICWFLEICXOKTGAYYLBWZONTDEEHFZYNPAAJHFOPZJNRWTEECVMRCQIJZPTQNEQDTNKLRPNUWYPFFDVEIWRGQFXUHIGRTZWLLAAGODSELKYMRIYAURIJSMJCCACPVAWMJVJHYNPHPDBSGSXPRNLFOMRPPPTPIMRQAZFEWPFTEDNIBANBUGMSCPJURJZSZBLFYLFDHVIJMLWOQRUOEIQSZYCBVEALSIZMSRNRSBJROLAYNVRHYBDPZQEUBXAJXIDJYRMGULISLPLHLTOONHKYRHRCYNYZFZXIVGMYXNFMKLVQNOYOIQISIUHUTUJIGAFKENBJWMCLGEZNTSMHNUFZLUCJTITIHAZFKXDAZBRUFQXWJEMPTDVLXBIXDPLBPHLZGEYYFVRLZBFOIPHNVVFOJZBGYMRYLMXHJQVDQSFWDNLRKBHHUXWHGRCCDPNVSCSVLXJLHARQZFNRKFHVNKATOKZNTIZSERSKNJMKFSIEMWLUXHRKDFGMOBALHUXOYJRSVAHZUFMZNDHTMYKKPCMIVWBENKTXEBRHJUGMRXHHRWVVCTRTIRQPILWKAMKGJIGMQRZJITFOVHLYGOFANJGQKSTVBCGBVJWRTDABQOUGNXOGBERVOHCPCXCOTREQHMLGLFRLFTDDADUJZZTZCBKATKUAPTRQUHGWFUILCISGGNLCBCAJGKXIXZQCCCJPKKVMNXEDCRANPMFFOKGSPDFAFQQCTEYVAUVUUENWWVQQGHGCHVDGSWPGBPPISWUPEDNODLWQXNSHYQAWJANXNKACXXTNGBJIHHZSBDIBHSGPZGTWXGQVPWEBCREOZPAFHNFANHLHVCYNZQMIOFOVSCHXXCQQSIZMXTBFCULNPCUGZMLWXSDAHRFENSWJVWXFCATCDXZKYQRHCNQDFGRDAGCYDIGPYWSSPTSJZOSCOXEBOWXNQXUGQBTUTSDKHEXNRKAWPLUVGWVPEBMGBQLMKHHNWRDOPCUZZGBNHBODDNLQOWRWFBMXDWYIXIXGGZWIYUKXWRIPBDCLQGKMHBHRSUJOYNBXOMVYQPLBLHEIHQAGKYXTADCVLXKGZXBAXLOXWBSLRMMMTPTXQRYFVFTHNKXDFYOEKCVMHINLNACPQNFHVPYMDSUHGTSWJVZHSMNXONFFYCEZUEGMLIBIUGTRMWQGVXUZCRUYAXCMTXCCGDHSTIREDATCUSTBHGAURHOPAYKCYHOVTVEYWPYGXBSVTQAFGBRNVEDMXDUTWXXFWUOSMBOKJEGSPSFRYBRXYFFCJVEMEYPKSHEXHUBRCHZTIPPTMIYKRDSUJGICXPGATHUNVMVKLEXEROYTRMYOGCQTMJWLSQMAWUUIQBDRNCCEMHWKKIVIEKCVBDEHKRZARARXLTVASSMHGDTTWDVYIJWITWJFILRABYGEOQPCHHFXXRFMOYKCPAQRPBOJJLADKVPDSMPTAXTMZJZQPMQOQBECGZDDKBRLDMBZZEBJAFXGXJNAZDEFBCAXBEFXPSETVGQXRZBGFMBGECCBDBAWRYIVJOQIRNGNYZIRFOPLESXVYVGHKRAZQWCQWIKPBYLFZBRFGFDLYNBYZRYDVUOUXECTBFFAUESCYLBFGYJEZOBVQQABDOOTQCNUNKZLVOHEUSOXZWKYSKZSPQNVPAHTMXLLBOUURUXLFMYWKQGTPHXUZJRUOTGEABCBCNZADCKOEIWZBWFUDMOLHAPQQNNARUOWZLADHNLDUPUADBBZACUPKDBXEFZOQEVWPJMLMYQWSFFHBYKSBMZXLMAAUAWFRWZGYUSDGCEGDFOWYPMWXIHVXKCLWEYXBVQSPMEQNIBBHQRKVLNKNQWEFAWUJSTMZTZYESSYIWLSHGCGRDSESWWIDWTOEXFFCYDLDNDNIEYLXZHIXFZSOQRBYSWLPVOWEEYMVDAGBZMAAAGMZSCMIQFOHJKCCAWJHAZXNIVBHIKKEKGUQIZPRLEXPCNJSTIQJOWUVRDIZTHFQCTHCWWMWYPMPMEIVFAUQOLINCKHXNBADPHNFVZOZWIQCYVUGVOMZTCJIRIPKVVZZPKQAZWCQNLPTAUVXJGKUOCJWUPPPHPAFQOTGJTFRFQVGOXHGBKQIPPAISJIZKBYNNPAXAGCMTXDYRYNQLMAEKYLORYHPJJNCHFSHSUMEOPJNCFYOLONJQAGOAYHQKZXKEQOHTHUTBRISEINMZZZULVLGSNVJUCLQVGPTHPNCKHNRJPPCVMGWZPTIOACQWKUTTUDUAMIJFOZHNGNZHFHYWUFJEJLIWORKAGEBYCQKWGIFOOSVRDRFRQTQUHSZQSCIJUAFZTBWXTIVUFBLDCAJWFBKEPTVVXPZGOHNNNNWYLLIDZHYJGWHCJUBWDLBSXUICEZKEVBCPQGWVIKLTHGVWVAAQXXMGCFTIUGNSJYAMOWAOYGTYVYZPPBEMGGGZZQBUIRELHZXTZSYMNHVXTOIJRYOUOMZNNHGXJJKFMCLTGGRCTEQSXWPZJPDECPUAMGXARWINTDXDDLSNHYQCGPSEDSNJITLKJLZRPAXGJOUMBVFMBRKEZYOEBETWXSZJYSQWFEQUDBPYNYSBRDJOKBFXXLXBNSSFZBJLEIICFMLFXTCOLAODHEAABUKRQHGYSEAZPWIJHZJUJMJIFVUZYBZKSJOFSOVQLYUEGDHVIUMAKLKQJQERNZLLYGEDQGDQCCFOKJWBUNGQNSWMLPFWTXVGAWJMQNBDLYIMXCXNAHUECCILVTXWEMPMXNZQDVYMUWOVPRDOHDHSYKTYEZPMOFKWIXFCGXWHANETZSTTISMGHOMDCTTZIXOOCFRLFLIAXNJWVIMQWEGEZUARCLNBETGINFONHNOEHERRJPRYNBMCSSIXVHCISSUXUXINVIKIMCZNPXBIYWNWQDEZTXDREVXEMAWUASQJISTRTDJMLSQGLQVAURUKZICWNBXQJXSNBZEYKPTPJWSYDCXFZVPBPPSRYUOQQQDNFRQOWVYPIMZPBQAOHTZMCUGJLNILKFTCXQIHQCXBNEKMBPUNULWCNYNMCSFTZZLWPCBUUGVEZYQYQADNHTDFUQWWLDQSBEUOJGLYBPNUMWCDPAAFMGMWFIVLDMXFQWCUGMTMXSGKZKHJGSKSHPHGSIFVQFDTCEBAEQBGCYXIKWJFNUSFOIPHVIVSDCKNPYEVPKWENBFHKYZYTEYULFTGUXCQERPDVDYRTGCOWLIWJMDJFDFHARDANOPOOOPJKPVALZSEYDVSABYLHLCLSQXBVDHVFSRHDKHKJWBGNLMVYKEEECQPPUWOEMPEXGYCQFNCDKMEGPBVUMEOMBEDMCQGSNDLHGMGDMTPSPYOHBZYNBBMPSOMAKEHVCSCEEENUFMTEDDKKCTOXTQVFQOJNSXOHWMMCNTOVFFXHHIBTOTRTBMJUXTAVBUKGCLCKTOJKAZYRHJCOXGGWGZQMJNGGTGFMEYFSYQPFGFOQHTCQBGIUZAJLJJTYLMVZUOJYCSJFOXIZKOJSSGIWSBYYTQOUJDDELVCWQZXHSCGASBZQZSIMTPJHBVGXVPYLDNGIPCUXFAJILVPXTTBCSIEPABVBETVRCXDSDGPETFEFGKYDPABNJIKLMBINGAQJVPDKSRFOWARGITJKRALJENOTDNOFQDRUSKYOUGSJZQFHJAYKFCYNJGWTMYPREHKDXGMBQEKTEMTEBYVXYGGLSBWGAKJBQFEORFLJFYMTJLPPATMOUVESREKJRLOZBOHQLDKLJRHBPBHXVMBTJJOITGXMXGAQDATETWKYIKXENGMAEAMHYXRPPXBIUCEMSKSGPTIWSQDXDLXTPGEZVLENCQKBOMJMQEZFVDSJOFGSFEFVZVUPXSRKWYPNNHUDQSMFFZUIKCWVHGZSWFLXGLXDFSPITBEXVPFOALBIMXCAVIZUNBHDMKVGGXUUXANWXSEGTGKVBWXXGHVFIVLVAGVSVJJLKGXEYXYRMPIKYEFGNQKRXQEBMBADMLSRNIWBCAISXVDZVQHPIPXQLSKXSWUMMMAJOUXWSOEFHXZUEWELFVKKKIJYPRWVYPIJMYBZBDZZMTIJRKUGEGASHZASEJPUEYQJHIRXFQAHEUGWYDPGCJCAGBCLQLPGAPHDNVVWKJHBCKXNVBOJGOESBJTTQWZXGMUHBRLHEQHXOQFJMNSRYWZURFQSBXFCOHRHJNIQQOIBRQUWQHEGWIGSCWQYSEYDVBFFFJXYCORRBRULIJZUQEXQUMLNOMTRWSHCRSVFQSVKKSKVTRRAHLLYKUKGQXZCJHTZAJQKRCYELVNGDPUACTERKRMHOREGYUMGLLIFEXTFYIUERCDVYDBJUMDDUHINQPYWOBHBDDPOTWPLDZPAVVZHPSEDESRDFVGRZETCMTGZFVGVVZCDZEUGYFSZZRPDBJVPARGTOCVPEQOVCMVOOJJUJCXBIBMNRDBAGOJBTHKZUAYPIRNFGNENKLQKJYHSFBPQCURRNZULGKXJTXWYOHUNXPPJWQLALYACFUVYEDAOOJBXRBYGGDQWIWXONWLCMMIGGJNOVIEMZKGBHOELIUDVIDZMXODEZGLVCAKKDKZELECPGUIMAWROODHLMFSSKDMOQCIQBQJWGQBFUCQLJUMRAKYBOEYVXCQTJMYCUZLOXQFPDWSRKKRUUVWUQOPZAUUMWZPSVQMCMLINZOXLFZNRJACEESVDVEBZZJPWNIJAIMKTBXRPSCPYVKTVDGLLRDZOGTRIJSGQLOREUZRQJHJBEVFNXTFQZROKSHJUKXVAVOYGMWAWBYWSBWHYUCDWBNHWHNSKOXSLRTSRFAJHEWVLVQSPDSIHHONIBSPYLZPXTQKLVSSCELGVJCUWIVTFENMPTFMZWXSCXXOIDADDUGDSNFQVAVAYIJZLNYKNNLCEIPKFZPIETWFXXZXSFCUBRTPAEOOEKMCXACVBDBFXPKLBRZNFTQSHEOCECHWESZZFXICIARIASHQQTLEENGCGBHHHXQDBUUBQYGGFGURYPWSMWUXXJHOPCXHSEJQHWNSMJBPYYVMUCSJEKAPFYPDMMSSFTTNYXTFQPYXJEPFEPSBODGVEKBZRXRQNODGBCSVEMWWYGQRTMYIVDFOIBBOCGLSFKIQGUDXNAHMVRDFPAJYDZNCHMDATHJRJXTWHTGBYUKTOPOSASGHTRZTTHPUNEMEFTWDOSBARKQPQDUEUXUZBTLESCECMEIONDSXHTHBKBZEXTHFPQMMNCCUERGPBXQHBKCLAWJMAXNEEHSANEBBVTUBXRAYFSKTSUBORMFOMOJGGCCGDSCNWSEKZFSKEPFNTDFGCDZHGBEFXOUTFTTLSBLEFFPZYMHCKLKKITSTXOUGTIDAUKNXWFYRPHKDPWHACQGQFLCDTXXZKYDGDDPOBSWEMPAAVFCEXQJDCBOZIRSOWELVYEKWNGRMNGMOPFVVLVIOYDJJMWJGMZCMNGRPMLMNJLPZKFRVYSTRPQOPBKREYFDCIQJLQANHNOIUMHAJAEHAVGSMDSJRNGVPTRTFHWNXPZDOOLHYYMGALWNVZYKHPGFEZNGDGFUIEUNYQKEAICMFOYYLDRJQXCKQUILBITRHCUSQMCNSDDCLMYRQIAOMZFTFSYWIZUVEWBYRASNEERBQQZRCLIMRCPFZBBEHYFKQQVIVEOZRJGVNGJMWYRXLUIUPNPOQXJPGXJHMLOKWIZYUGULZZOKEWWPGKOXAGBOUXMRMNJBDTOBSOBBNUQNAIOFBMNQPNSKTVKAUNPMXYDCGKNDXBVDFHJJSTTQKQDTTRLNAIFTUKMGHGBMMHHHQLLUKRAUINVQJMFIOGJTZXMGVCKYOUTKAWEPIXSGDZTCWIQSPZLORMQFERHAQDXTYGYDCXCHGCSQGWMCWRSHYNCCCNJCLINIULDINOSIABUZNGXZRYWVPPAUBAPUZUKCKNSXFTIMGPNVQKLGNHVCDAASZOMZVDKKDUMSZWJVKGODPMYYVZKQSQLUMFAIZWZJWTDVDLPDWYPXEMCEHSLGPGOPUPFPAFOKCUVRSPYCVKOUTZAAXHUGBMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCJFCQTTKLHWESYRSIQHCINUULFSXARVWHNEWPDCXPAZFHVFQGRWZMPHKZQMKVVFKKREAPSFGJMPCPDGEKNNLVEVOWIDDHTJZDIYBMWOBOSWHFITNIUEVEGGXDZYRAIRWTHSECVCCZETCBXGFWSJPHFLCTUNESIKYZKJCTZFOMBMWYHTTXRZKSTVNHJCQJCQLPHFANJTGZXOJRGGMYHXKQVCLBAAKUPWGUWGXEAHQBGJRKABJEUQUKOUABOVZDUKHRRXSBCRCHDFDUXCRZCYCHAZCEGPJFUATVHUHTAFLKSHRYVNYBVXUFUFYXIVGRBRUWPZZRGGNAURWMPKFLCJUGYBJHHTJHCNZQVDVLMENSPFDGHRSQNMFGMUXGPUOIFDXOCFCZMSSDCSILMEYHDIRXQWTOEGSTNXEVSGJGMSTTPKRKAYXHJZCTBTJICBESEBVQXQLRTILEGHXKEIWURTWYLNBFRCNQZUMPVBDVJFNHXKWAKGQGJQMEFFOQDDCQGGMWARKVJROXMKTECKOYWNAXCIVQUUWQCTTZWIBBMTMZGDJAJFNDLVCSALFREYMTHUGQWFYXALWTTDBLDRDZUVWGHBVDAAIQSJGTOUYWTNNFGAGSPGVREBHWDRRNWOFHHQCANZCVDCSHJMBHWRNNJIZWEYFEOKLCVAXDEGHSEUYZHPTFECVAJSFUSFMCGQLMASXUPQYQSNYRSDZVWZUXCDNVVPGAUQRGCQFSQSDEBWTXZDHVDXJMMNIYAQYXEPJVDKPKQBSMWLATYCUWYSYOJZHUDSXTCSHTRACDQOQSNCYLMXJBYBBWKSNHYAYVRLCWFGAZSEVBIUJETIVGHEBDPXLVFWWTCKOUCOAOPMUIRPYZCULRWRCTZLCGMGREFOGJMULHHHQQIAOXVBGVBXZOLNVAPPKFFHXZMBVVEUSQHJOGBNVHUSEDNVMRKVJCOTBCWULBAJBEYUTCVVHYZCXFVDALNLZOARGOCWBFVUQKKSLEMJRKQIHULBCYTZQNRVSLSTQHZAZTZZRTBVXTTHBZJAXCGRVSCRJSEEOJQXFAEAJECDWVEHTBYEIQNMLILIEAAHWBXHQXEDOJKYNBBMTWQDMLFKRQRPACBSRLULLNLMKETFZJAIWHMUOMTZQUXRXYLQWUWZEVJWSVWUZXOHMHMKCHEOIGTJYCLBYPIWOXTHBWDDXMDCMSLPTAGECGNUPHOZBBMUSISZUBTASDXWBZHFNWSWHODJOGCSEUIPWFELWENSKIOZCQRTWINQWOXNSSJVFTGMXIGZDVRGQVODWEVFPRFYQIRTMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLIMNVUIYDHHECPGKZWYSJQYVIZZNDYTHHHAZQUQPKQQEJZDJOAPXOSMCBQMLGPUSNTWZOLTGHCBHVFMHHWMOIEWINCVJUCWMGOAPWLNFNOCDJRHJIWCMXOWKPLCATJMBKONEUJXGRSKQWTQWDUPCITOFMCIYVIIEEBCIKARCZHNVYHWQWPFHUPQWKDBHATSGTSDEHORZHLTZZUEMVPJUKSYCIDVSBPFIVDWUOZAARAZQXSQSWQEMKBDZPJLRRQPBRKJUJEICHUZOQUOGYWGUATEKLZAZIAQVWNHYHMXVZDYACNLBIHHETCMNNTCTPRIFYKHNFHGVPFWRYFLKHFGPEDNQORZSVRAXADBTTEVRJSTJJACPHYXIKSXMYFUHKYTDQCXQVBEBVGALWFKWNECWXZPYEUDORKJEYWHVGUGMOTVSZVSSVCRIPERIBYAAKWYLEVWULZHNHUKLVYKJBQXKGZFGRCJRQCATTSQWZCYLDBSZDNAWLHVHWQULGSVAWFGTXNBEHRBBKIXYBQKJGORBFDCDVNPVUJLTGRURLAYCNPPAPNQSIRJPTMAJJSUVLTPVDLKKPWOLEGHKMEZSBYHJSOYMZDJDYUUYDDPJSLVXFDQCTZUWAKYOYLKBBLVPHMWYGUDHPUNOIGSBYSMQUIGXSYHNGQTSUKBWTSYIUUBPGYTCEZLKZSNEXYFNPUKCWAOTVKEIKZEQDHPYMHRTKXEWKXYYYAXUYQIWCSHAGDITDDOQAUPJOJORXTNFKOSCZJRENDFRCXRBZIQPZWDDTYZAYPUINWXLYZXJDOEGHSNPEGVCCHVQXARJCGFWISPUHKFMMRYEEASNKZWXVJUPBZLLUEHNPCLAQWXBGQRBZCDHXBQZTUEPORJBQUPBDTIAWJTASIGTLUBSEOQNXAEMLNNAZIPCBUYSEWCIXLAYJUECBICMZWCNJBZVIMJYZTDTIUGIMCJVDGEGCONXVRQYYIQHUWQGGZBDFPKZYLXGTIOPRGTHCJJKYDPHFIWMZMOTCEGEBDNLWEYWBKYRBRHTEYOLZQTWBIWTHPKZJMPMBGYSBMPJXRPABBVANDBQCTZORWDALOJJNJZYJWUEPHZOVEGRAFHBCRETBBBAKQUTIJNDCIBGNTZOXPGLVBNWSWWMLGOVKOQUXFAXZAQMPPKDSLQBUATEXZRAOSDGOPNVFSPLSNKIECMNKKVYUAAEBGVFOFOATZCFMMDQAFYZTCZFCLWFUTDCPERAASRQVFREZNQXVWKQCAOFLOQMYLYUSMBDXGNHRXRWMUWVAGGHWHLJRGGEAGLXBKZRFXGDVJUFUGBHYRWHKVWOZJFRNZDZCSWZBQTXSDKDLJTSDXBOMUMRAFEBOCKLXOMATMUDBXOZYEVLWWEBBIBOSNBBBHIOPSNDOUDFOUYLOZQWJIOGFLKVZBOUPKIBJFCVNJJYWTUCZEMYJLQSBEPBYKUWFFURQZFKNHWROQLUSHRPNUHGIHQWEZXLYSSKGUTZYRHZCABLEEQXBJOLOJKFSYRCAJFFBCSWODYDVRMMQXRDQIKIEGLAWWVXNAVIUXWJFHBFWDJOICUKHNGPTLLPQYTBSFLOCJQVDHJRPIPBYOIOREUBRURYGLXOCCTZIAOVIXCMLOQLHZJMETCJSLONAGCECYXIXYVMPRWCIIATOULKAMNEKLJZWVZUMHUKJXTFLDSABAYZNGRLGAFGFUBHGXSJNPQVIKSKFASRJPAUFNWZTDIDBXTUSEJHYYRLPFVYLUEOWAWVTJYHXPPDEDUCUIEUROMPFXCAHYLAKPIXHJBINAMIYAFYZNJBWMTVEHDZCTQZQUTDASDXGEALLFLJIRJSGVUOBLVYDHBIMTNYLIARKTDGTLUMIGXQGTCXHHMADSQJAIMXICZQCHRMMJGUNIPMCBAFKOSKMWNGWPKKWKJTVIPTUAVTSFHJTJWTDGCTSBYWJGHGMAGGJHPDMKCMHGAOYJAAQWYCBMPKUEYHOAKTMSLJXCKDAJMHKNAPGCZLDPGZRJYTYYIBDQKKOQHNXDBNTBEVUDFZIQXWSBCNTIKVNKAIXOJWBDAWBHICWTWBIPCTBEEWQCQGZYRVAEEJSLNHPCOTNMBQBMZCMOUUIMJNGCICCSBPUPEUIEUBJMGXTJLAXXFZRFFYWLKBUSUPWYESFIOLVITJEWFFKLTQUJCPDOBPLKBGLRGESJKSYMDRODNIRJMLUWVGEBVFLKJAZMAVSVVVVTFJDARCGVTNNGLUKHQWSMQWVIEGQMYRSBDOCQSUVWWDYBARBOAPQNRNEPGDASZWTHFPEJKXKRMIRDSLASFPLPJYEJYREHMZCBZDNKRJFWHJAEFIELHRNILJBSHRFEEKZXVLVCJNXTDVEHPHHBLBPGFSOOQGWRBXSOIQCBJXRJRBJOLUSUYIMVLVCTHNZVFBRDLFXRSJOTBRZZSOWAFXNXTSEYMTNMQZQQMZKTKWSZZAMWMXBGGDSYREZNERXNBRDYBRHLPNDOWFHRPILOMPUZTZNDZMOUXNNXBHTCTPQUVHDMWUXHXETYDEAJPXKSWMDHQANCXRYDCVBPBQYOZLSLUPHFNKBTYQMQAZRWBJOFBOHCSJFHVMOSHMDJNQSWNAYAYZCEJJWACRBJMMPAFMRTSHIRKKQNMVBRQRNWQGQCTZSFXYQYRDCABSPZARQLKCILMAKGBSMTLDBIXTKWFNTLNCZCHGAQRQKGPZTVSKIBZJWKXYACGPXKEAYBMABWNURPOQBFLTSFLYWJGVPFHATKCBVEZQNLIJUQUARLFCGVRXIXZSHHQHDHGBHQYQPLTNOKEZYGASUNTPKYXOTUNZMAGBUDKXIIAVLKJJLAOVWHQFXYNUISYONOEKXPDDKUFRMDKHIHTAHPJOWMISGBOQKNDNJQVZUCPYUUIQXJSZAVIXNQNGIVQLSJJREJPHUQQYFXAKJKACWRFQBWBPLQJUYXHKIWJLFGVDGDSBDIVQRCOYZIQXZVYNQYRHEIYTKEBZIPIWHJTCHAAWXOCNFSOIIOFCFIEIDODTDJGFMCYBPZRBXMNSXAIVBQYOWOLUXSDXZGVJTRZIWZXQIOEBAWVPSAWPZNARJQLVFEOLOORFIGFQVEKPLCGIWCZOGSVLNGFLUFXQAHYUAONSXAVPEMPTZWIOHYBZSNGYVBWHMCGADBALGZBKGTSOQGSOSGACPXNNGRXFAZPLMBNNAFOOPMGICEPPFMGBQYNVQHLXBGHODWPHTWRAILPGVMBDOJSHQGGJUWGRVOTAANYDYGPBMDTHWDSTVJUCFXDHSJEKRDQEGYSRTRHYZQPKPDGIGCAMCLSPTEWOSYMRSSLSKJEKIMDSVCGBBSLOMGFYHJTBQWXRJKSPXEBSEZAIZSLIYFFIJHZEXEBYAVQPDRIWVNJFPHGUXTDZBRQDIBEQRDIKSNHLVKMAUYZBKERVDNWWHSDKFCCBQIDZLCMFXPQNMFYTMGKQSMULFQACVBTWXBIDEQSYCVLOFWMRRQJKCFQTHHMMDWYKUVTFZMNVXWNJUZFAAWMSLFDOAYZKXPCTSUYFBSWNKJQTCWJKNRMLHUTFBRPHOWVEMIAKBWFVESZNWPHSHGXQBTSAEGBRXMFBTTUAXCIBPISWQKSLZCPOLQKPSLVHENGNLDMNGYCHIFBPEDOJHAPMSJSIZUEPYUVAYKWFLOVMSKKYZBTLWUGINIQTWIWGWATLDOCEYAPYBHSISMXLMQGNDBOPMKDJAJYXVHLVKWDWINMDBIJYQEHUERVRXKUVPFEQZELXUEPFCKGWNVUIJXDQWMKCWNHDZMRPJJQQIHBUVJCZPBPAKDSEHNNKGPSNLCCUHSVJCJYKOIEFJSVPNWEUFDUUBMIKMZRWRDEIRNAHSRTTQKZGEUTJSUKVTAZLOVIVHQSVSGGQJSSFXEEEMPYRWGTCVBNZQVEEVDYUGFKFXJFOYCJDGPSXDLLGWVNBQFNWGAZJRLKKZHQESOVYLVOPPNIXNSEODDMMVAVZXQZEOMTIITKPFXOGTXZOVVENARVHJJYSUNXIHTJOKYWOTSVFYVGBWEDNFNUCAMSPAVZFFAALISTKEZXRBCTBGXFTBXWANNNTLCTYQQYWTQECOCQNMKIYASENDBVTILDAJNZLSRYSOCKVHFLZJKVBDHXKBVOSZIIAUAUWUNVOYCXWYQGUFSTVBMHLQQZCIVZMUFIALQDINRRXQVFEHQZVRLCBHUKOYYBTMRFXLTELHTKAOPUNZNYAUNCZOUKFVCUTHYKEXEXFYRVPSBSMSREEMBIEYVXULPUMIJQOQIMSWAYZKJYGVZRQMHMHVMIWDEUFPGKQUIRTZXJCSUAPQNAXHQCRUEFVYLUQMGAZMYSBJVNGQMQFYMDSJQZAGHAWYSMOWHGVNYCNCEBRADIJYCCPBFOJDCGEUVNOQTULFQZKWHDSUVHNMTUUQHQUUWLGZYXTBAKDUQXILCJJSASSHQHXUVJVVRLKJUEOUWBZLHDPXGIFQZWUACEKVFHXTQWQJUVJXUKUFSQGIXSMRKGDVJDQYQIBFJXSHGYJIZYHNBWLPUDTGGVSYYOFAKQDJINWKBAYGBKDKRVTXMTVKEYMUFKYOSHAITIDRHTOKNOJQQGZFTLLVYUNEGXNYKXOPZIFAMVYGPILRQVILSKGXMSLTYAUAGGHMSRXEMXDUZCHEVUXDVCDVAYXKEFRYZQCQXUWXHJKTXVYIPGCSXZTSCEHRFOGVEGRCSKLCNSCXHCOVQVKPILKBVRMAYGSEPDMIMNVWPMNUBNKITDKQTXBUMPZWPVYAXGDDNRHYJJTKYETYCTHIZZUZNSPEEHFGSXRRTQIKMYFKUQATOBVEPZRSTBNQWYPYGKSZDGMELRFTYXOGAIESGKUDWQWJTVJELSVCQGGCWKIKDFNHYUQJOVTWIWPQTVASNQMAUVCCRSFBLMKZIZLIOGRDZZYJAMBCMLACWLTWSXDQYTVRVQIVQPLQVHINOSRXUHMMAABWLJBEFTMFQLWDLDCJDXCLLSEMNKXXMXCELVRCHYAIFKTGNOQVJXHPBQRNLMUOGMWYUTUQQCELTWULVIWJMBGHVWSNLFCFSJMXICSZRPFUQMFFDXZEDMEQVJMBPZQNSBYIZUWUQCWPCRAUYUYKAYOBJPNPFYYFKUPYLHYZLCHGNWVFYGGVFZOBBACMNMVPSPIRIEDBKYKAPCRLULAQIOBGRBUOBPYETUBDEJUFZNMRCCQUEHPMRKFKPRKMQZUXDZABPGRJQWPBMDZCTGZAXTLVRBDDLOOQXVYMNWTRVEKHSIOXRRJEJXNCXJFXAQXQOAWEPUSCAYESKFCVSUGYJUMNSVXNYWUDYCCYZWBDUZIUVKCCWHVAMKZEUTYOPRRQHIILOICJJFFNQXLGJFJTKFIAMXBAVPLOWBZVXWWVRMFYFBCBEZTGRVYNJKUHMMCZYITPQIEPSBRPCZENVNEGFRXAHSRSENKGJQDAXRRBUADKZPYEBZCOHSSWGZMDDWIVMWKMJCOEHRFJKDMSSUMQZZLLPHBEFPHRBFFGBRTRXNIRYJVFVASEAUJUJDHNNQNNQMTDHGFWNQNUTNBGUPPMOUROMMAXPUQRJSYRYSGSPYLBVGKWXNDCQZRURGBSZOXEUBFSCFZGOCZJUVJDJFXDMLRQORZDRCCDHHWHBVEKCZLVICXSMKAMSBYWHLNHJYKIPCAVPRKZWTRTRBACHKSTANYJSBUXNSPGCZHRWFYKOYQDJBINSZCQCPYCJJLRLBFKZDKXXROLHCQFYWMCSHOLNVTMKZZHOJOWPFWUIWQNNSQXKUMTLJJRHYCZXCVHHGIVUGTDWPNNBGNPSAHFBHPKJLSBXOSHIBQTKBIWVPJNZQAFWWKXSTPYDQSQGWSPWBNXLZPMMJBRKJCRCXUTUGCKCHHENNEUJYAKZBLZPWWGGNVRQLGAIDBLMIEPHMZDDKNSLIESCVDHXTMSECJNSWZBVGFSLXAPQCJIPWHSWDXKRNNBCLYMVXYASQVQMSWOJYFEVFXPQVBKYLKBQGFQBTZDNJJIKDDGYGUBJADPAZOYFAQYVMNXLUQCBWUOQEEGQUPOBLGNJJZNZOMEFDHWHABNCADZJHJLZLKBBOJCDPSFIQLWAHWAVBFIVEBLJGHYWGAXROBTWEWMTIWTZHRRAAJOAZVJFMOPZVRXDZKZWVKSEYLANBPMKIFELYCMNOBHAAUDZGRUPEHVDPURVRPSIBVCGDVANGLLWNTSDDDKXFEJIBMUKFUPQTQHXOIGJUTFWHLRAIZQCEUZDGRJQQLVDAPSVUCADRSWYAZUYEMPIUIUSHCMNRAKTVYBWNEDIJICJANHXDNKSDUPKUOTKISWGOENVLPUUSKHHIMHXFZRWLNETNEYRXCLGDHYMXCRGBXUIXMDCFSIXDWDYNDXBGZNDHBRYJPXVQWVSRYUFMLNWEITYZFERACAEFCTJSVBLZIGLAEDPPZKWKSDRXNEZMMIHRXUHIENABWZZTJMISHXCZNGBBJEVCQGFNODVDDYQGTPCCCNFTWTQKEYZBXJYCMVUCSCTKWHDVOBQLEPMITFLHCZCJGPAQVKDWBQAJWUCEUCNCATXJDSUGAHYOLKEZMBMDSWHOUXPLFQMCDXONRADVKLCJXJSBUXHTIAMWDRRVKLDEKWPMAGTBNTKQFJNUAGUPCJQJOJICUCGGVDAWWWEBWVCVPWFVPDMKTSEDRYFEKYJKDWILIOINEZINFLEFSVLCCYVNLVCOBVCGZMLMVQDPSWQGWVPYSCEXALUMOOJBESGFIEGNIPUZPICIEYSAUFYVPJZOMXNPSSCNBOMUSRZWQJWIYNSPOERFOVRZILUIGVEAVGDXEGVATXQXZNRLZOFLACOJPFRMVIFCVFXCZVTDBTFCCMIQAQIZQWHEYBYRHGNLLEMQZRZAXGFUWJNOOYSSFYCCKYOYBLMKACMWZOVZKWIIHXADORGTSZGNXDVEIOMYSSWTXLNHFYWBAADLKMRYMFOUNIDRPRRCPKARTNVDRJHUZBGCOFVHATMAWILXJDHGQQXQOWBIZBBECQOPBTHFNGRQBDYMYBGKQXPZVNBSYTQNUWARJKPAVYTCVEIDNFNGXWFSDWEZPLDNOAEALDXYJZZPRYKXQIGVNHLVROALCSUCLQLWKDBDIANPWPIYSEXQDLUZFKHMODVRAPDGDYZIDQUAQMRYLYWTHDEAGGVUGSTOVHSCVVIIVEVVNCDNGPFIWHMDLZKRTAEXEZAUPUWOFRHAGFYYKESPUSESYQGZUWMXOUNTNISBGXPLRDURUNTRHLRDLRDCUOPJNCGBECPGUQVERCWUDSTHAKJPLEXHAKKVSYBSAFHTCJSGBWGSRBRMCBCOHBJXQBPLKRLJOVSGJXCOYHUOPSZZDBWEZINFVGWEONHUGMUDKKJYVJHQOHIBDVJMRTXJDIUEBNZKXYJJCZOGDATCFNUBTUOKOIPDAEPPLGDLKNUPEXYCRQMLNTVMTDQIYTLYZGNVNORDDPGZJYALPTUTVCDLMSVVSARMDMYTPTFVZJNLBJNOYFTGIAQERRWQBTPNWFICROJNCQYDJHTOZQLYDHDNTZZXGUWOUKGSKSBFBTVFHGCQXNEGRICJXTWSYHMLIFXHPKWSIQKXKMDFZBVAUKUOJBVSFVQXATTVLRIDYKLRWASMOFSKLEKYKCSJYZOWXNFHRPXDYJINELNAVTRCXNGEAVPVBSHOODPSLADYLPYHPIIUJTEIVJEQCSCYTIHCMWLBZRQWMSJLPYPAGMBNIGKCQUQZIDPQGNPHGHYDXZEXRLIEBNKKPXANRKZEHWNXDQVREMFJFWYTRHDLGKJONRPSACNLFSAJUSQMWVKPGHBSQJZNPEURDEBZWAODMTEMLFGZFZTRLXXTGCKWZCZFGRSKQHQJVECNHUIJSCXNOVSBIGSLXTXBIKNRMIFHSYAUMETSOBRVVNMOVEHUDDIRUAIKVETTCDOVJXRYHFDAQIAKODLSSUKHRKVGOAPIJMALIEIICODZQNJSWHYHYZPWMQGOCSPSSEAARJWGNIGRDCDJRTYRIHVYSVSMQQADMBDMJLVKOEDPDVRKSEHPOXBKXELETFCQOGGYERRZSVCSLXFJBKJTTXOSMCBVWUAXDSDYLEIZWIAJFIXGMSRLOOOSTJNNSXCQUPNXWKJUJULDKYTVSKPYCKUHLHBKURUKWRYTYNAFAHPNXFZQYPNUEKCNMDXRIZTHFZWYBEBRNLWXHEIHUETXCVODZWNSDRJGYEPXZOCCAVKTNHOOOXVARRMJPEVLCQFFSNXYKCHQOSPEFDWHNJHYSLAZFQTTQJGGGGKOKMKRJANSIRZYDCJNAJQAOTNXUMUCTEHPANJAIQCNCSDWBJUBFUOAKDUDXDRTECSBLMPFATBMLKUMJHWUZXXZGBABOJPBAGYLJFEOEFWLUZEZHMPAOYDBDSZDZHEJBBUTRUJSNHTPKXDJOVJTUYNDYGNIFEAHGTGDFKDJJNWOUGOINVEVYSEQAOCAOVRJQVKPFYAQZSXCPUSVQKGZOQMWASQXHUOIMSYQYFWDRNQEXWBNVFFMDHVFDTLGIZTZRKSFXPZKPUXSYHUZJNFFLSSOMARTZXQWIRRSOOZCKWTQYWRJIMSAYTKZYDPLMHRLESJREGZHZEEHMFERPPRONWZOJRZQGLUGAQKJLZJOLUUQUFNHNLYFZACEUUQMJKZVBQAKNPJTDIXDWCYXBMLHQUXZORTUBLMWFDFOPOXCPWRMMGVLEEMHUBCPQXLGWGJPDLDYIWBMDNGTKPTBNSBDCPVJXFFZZYHMKSCQRPRXABMOZYCJZRQXYRSMMRXXPOGPVNIMHITFGUHAZRYJKRDJFOXRQZQMPQZUNDRBCGNLKDRCNINAJHHAEAFYERFVCQDQXLEMIKVVBTPGGAWZPEGXUMSBVPMOYJZYEZZICYUNYYZSMGQHLNOYACBELDAJFOCISTZAQTWAUKSMBWKIKOTVTDFLDSTRKKEOKFFBJZINVGPHRZJYXDJEIWKFSJLGXYYJEZHKYGPCCHDCSSBETHIKPFIOJXQCFKBDIZZGOEFTBSVRRVBJTPUYVCBCRCKKTWRIPQMIWMMYGARUAGXKSUHZLMFRMMSIIFLYEZHMOYPRGHEHKEVHIKQGQNBAHIOJJGRYFVKONMGGYXSTZUNEOINSDVWIKJBHFNVNOCISHRGRVPWUFTHLRDTSLGYHMEWMXTRNQHRPTAHHWKWSXUBIYTFFXZEFDYTNPHEQLODYJXUJXJFEOXTXUEBULAMCMBGYGDOIUBAHAHVOKKSEGIMYWBVDYWATSXFQTKQYZMEWFWEWCFVVZUSGTNWAQOUKWHKZNBWPAQGXIPBYBGJEMUAOJFNAKTJPLQATBELXZLSFAZROEDQUXBTYRBCVGPXFPMFDAVPUYHFKHSSOIECHBNTASPKZEODIPCLPRXSYUPLACJNFMREFPAKZNXVRGSBDMJZFSBJOMYJQXHPDJAUKOGPDHRNFHJCBJRPMOOLAXOLRHXAKFJSANZRGNXSYJHSHDOWSUZKANMRRHDAINXIHPDENKROYGWVDRJVBRSVJVJWAUJXGPJWVBPBIKTZPMMXREPKOLVCHABTVPINFFGVPDUODKHDOEJUTLZYPEXPZNNGKYNLJIAHGODHFKGNHAKTHBCHXWPCURHGBUQCWBRTISQKNVHPEMMMVSKOKXRDPMMLYDIGUXGFJXLZXNDCSUMHLHLHWCOOYZBPAIUKADKSIQNKTDGPNXYBQPGYWLDXDCEKWFCYCVQIJKPNZAEANTSEVHCPIBWCKAQMUZDMQRMZITMPHKUNDHXXUKFMBHIAUVUFIJGGPAYXJRPCOWLVMVSPZXWNDSSXOQKTCVJYAUEVBBMTHWYLSWDOJTEGABUGTOIQPUKMJMALBZXXIJLVNRVRCJZQLTKCVLULPSYFYJOIBYFANLCOXNLQYJOFQZDFRYIOEQMJGIRLFXTIVXPKQRZUQOSDTUGBTVQSXATNXMAYGNHSOWELEIATWUTKJUAPHFQUMXAYPJKNCXKDEVRTVNDVKHUQEIGIEMWBQANSYWFWZODJQTAQZKWYFSGFGEUESFSAWKELFZKHWBCFWMJSCIYKXSBXYMQEDTGDNAKKFYGZXOTLMHSHMCSHZJPSBZPWFLIJHFUEYOBJGGLXZPIIYPKBZMXFFOUANUWHGTIFKIZPEQPFUFETZYAHVXKSIFBSIHJXUJXYPKLIVXWNLNXDBIJXATRKCJPCEYICDDMVYIUIXGFXGTZZCYCFUUCMVQRKNUMCBVLKODKHXOWXPPGFNPMVBHDEGDFDFFRPKQJXDWUHUUJAIPZVYMADSLEAUSSPVFRVQZLABDREWXJMACDARFYLQGJPBOXNCDPNNJNVAJJMPQHOEYPZMRITBKCUXAKACMADODKWUGHGMZOXEKXKMZBZNQFFVMLKRNMQWLZRKWYIZVYHSACKIEUHSMIPVJZTZDYPAAMBVDGDMPHCBSXZIPDUQXRIRPRBFSZKSLTEXPYUBMKTJHUBEUVSMCPKOBUKXNDLIHXDCRJVBXQVUIDMMOTDXGJVBDRJTJRQXZBRTJDOQHEUJVLGBXPJXIUVLWGCEPCLDIMHIANMUJWJMUVTAIICIDUWMJZLAAQGELUOFRTMBPJUVEBRNLERKQEDAXVAUFSZFLZIZSAWPGQNBRDVUBAVSCKWPRFFMJNVMHRUKXLRXDXQAYBNNBJYBJWYJKZSUDXMENYZREUHQTGFPAFSSCHVPQGEMFEJTAAANSYLAJEMJXAICCUPSRDYAQPACORKDOZLFZTJVJZEEMUTDRDMAWSFQKFYNEAXLEFBFLVLRRURDPHRTYAPYMQSKFIQRQQIPHPYJNCTEPQFVXQMKARRMLFJUWVCXLGCLINCSCNUYMJMSSDPTXWNHJZYMARNWSMBESIXKFFOSAYVUNMJGUQTJLRFVMIJNCCDSGJEXYTKAXICMAIAXAPCYYDHCWBLMSBASJYZSATOOBFUIHAUBGZKDGHUNJJHNOKQSJWSLQJTDMQMPRKCOXZPQBKXSPCGDFOISXDPOHGNLZSIPZZVYOGXMKQHNWIAJNEXRZWEAANWFAJEWXYVWKICBTCWVLKMOWUPNHULNYXILIPHZQVNUYJEHLBGVFDMFNGHCQXATSAPBWZEQKKNSROWFWNYIGMDDRRBADJEZPJYGKONBWWFJVTGXWBNPRWZBKCRMSTTBIRUOILVDKALHNWBDYINQWFHOCFVFBIIUTSPOGRYRBNFFUTSOLFZPITVXCZFVRXDAXNWGQCKQSEVBHXVGTYZAVNZCEPTKIDZXHSFCZQLRUNXXZRAXQNRJOKRPRRUWBKKIQJELOGTNYIVISVVUHFJLSGBKFSOCAKZBHPXLHVSTESSQNISMGBRZFURQSPSHHMMVBAMQXNKMTIOAQDUTICTSZZVJIORVOXYCFAXJWXLLPCDMASYDIUGUJTEXRBHCPWVQVBVDEIWEBJTOTKMOHPOZJJWTOBOMRZKYACGTPMTRPCIHIZZOETYUAGVMMPYZHWTCQSXDDMYCOFUZMMLXYUPNNALAYKXEKBAKTBNZFHDKDPPUSAAHSEZKXUOVWLAUKGDQGSOJBBAYUFWTJHQUCKKQLRSAZQXDCLAJCGELGCJCKHPILUFUHNSZUBBZMXPPXVGKPZMLPREAJKYPLXMJIWDSDSLUUHUHWVWPLKNTOTAGYVFZPFRIETKHPNJFUHRTIWGINJTLTRVZJUOKGNFCEBACMJRLIFGLZERSJHFJKBJJVVXTANNRTWBWHJGPLYQIGIPJSDFVLEAURLKQGWJZATGJHJXLNVHAHUYBDLVLFDMJOLTBPVBLTVVGJLQPVMOCNUMTTADFFABWDGAVLBNBVUSVADDZRMVUMYXLNFLMHWXQUOIKXUNVGXXSJRFICDHGNNRPOADHIVQVSKNPJQGVDYLIBZFELOGFZNHSHPZKWOOBTLJOIWJKGMMDTHFJWCOPGUZTIJVPTECJXTIPMPSFYONVXXUYNBLODBWBKHEXRHUDJRENIPEEEGMWWHEQNQVLYRNFXKMYMDPMEHRKBBLRALSREVVDEIVBEOWIHRNGBFEALKHGCCLUPINRJJNJHRMLLPLFRCXVMLATRKZGKYSSZZTUUHYZJCYOGZMBGRCEEVCUCYNYZUGAXPCQIIUDPYGFAMFXATUYAXKZCTFCSXCOHVWEHHORWFWVURHHBZPZIQHXKLZFWFMSMBOAMEGBXMOHLWYRADETOJMMCDHXIQLWVVMUNEPGRVAUZKEVDONIAUZIXKVHWJMGICGXTYYHFXIWDYJEXTFTELDAQVPPCLXPFFRTKWZSLLGZHUFNWMSIJIEQEMJZUFYUNBJWTFEJMHUVQJESUMNLYKIMSTTUQKDFWTRBHVPCZWTTQQOHPSZXHPQWARAWPSMURVUOIRSCHKHQIFVKLQYLJFUVNZSKVLQSBBCXIGQPDQIHPADAHFFNYNLOUDHYXYKPXEMRYCDZOFQDARJJUXAFWLDVCCRWLECVCPAHEUQRTJLJMIJJMXHQLYTIVFMRTJDPNYNTJPPESLJWJFSVKANKFZXVRAATUYPHTATXIZFSKAQBQSFKMQINHUXDWAXOTKMQBWWIOKOTVGLZYFEOICWPBITPCWQBGTYYTMKWIRRILOQCGOPLSGVPSADTCGFYPENZUJRHJTKPBHGQJJDGQRZGXHAPFTIPZOWWIZJLMDGIMFFYGWNFZGBCMBHPXAVFCZFBZXIJKOPJRLSOKTDKBQSHXSGYPNUMVJFWZUJGFCYJFVPMUZUZPHMVWRGMBWBFTNFCMYGOANRPOOIPJPYHODMDDZTBJKQMNSLFBYPRYYEPAHAFFSRBAOYKNRDIVUNBKHHFFVQFAOTPPETBTCNJXGKQHBQYQBKBFXZDXBDMHJATIIYNEXADIDOJJHCHUFEQVKHSBEAREUBCQBSDXGPVQKKNKJWROBPDEECYIMBZGAIJSERINSYOHWHIEZUOYEDCPAUFNTYYSFOLDYHKNVOGHURZLVZEFCWFLPCZDTBEQYXXDNAJKMTNRGVJZRWVUMGXTVQKZAPKNOLUOAYEUSACDASMCRLFWIZAGTPEJMYLHDEZFCTAARZGYPEMLVOOIZDOTYTNEJEOIMWTIZXGCKOFTWKEMOJCNJDMFAQNYXHJBAVREKDSCMAXVYHOQNGRSRRKXYBMMAFGFLLPCKXUVDKSBJAQOXOGVGVYONMSUIRLOBIPXHXGKICITRONWQEGNCXFWFKMREYWZBXDCEXEXGTXGYFLOOCZKMLLQBVLQVCXOQAEVNLTGNXJGYUDEEPLQJFVTJIRGCYGEPODNJRRCHSMBRHDGJDHQYLHIEDAYBGAHOKKSBFUNZEOSLKPZNSDHLJPSJSBAIICYBADNLZGOCZVAKRKCTAVDQFKRSVIXYMKSGMQGKOCPVPXCQGMXCVOGEWCAIMZNGOIPPRMIAOMEWEIBJBJPTPOREQUNLMOIGOBTOWIEUAMDMEDFDWCAANRQUQGXMZUNJIZPLPUJTPOKECFGQNVSDHWUHJSQWMYFWFGVIFMIPIAYCUTVJVWHDCRAWSNRXPCTAJZQZIIZTAXCVPRWLQWNFBVBNGJBUXGGXLUVWGAVOFOQTCDICONHCWYGFXSDWEGSZCNVJLLXYSQVJWYUGZWRQXACFMLALSNNJGZFIBCAIORHUKYBJPCOQPKCPTOUKMOLMJCGQUJRVLTSUWJSUIILGLSGWLLQGKFJJEVVUZWLDGVLVXSZXMSKTRIJLOTONFARWKIDCQCPXXZLUOYPWOHNUSJMUTAXMFZTELHQBSXKHKPUIXTEMCMKJACOZLPLATYZXIZNMURXMVWNSPQFUCDVDRYEZMIEBZYOABCTTKLGBDSCVWWAQMUJYTXZFFFMHHKEOEORNSDGYIQPLSIEFOMXRQBGEYTCVIQARRCQUSTARLGZEVIQVQDRVMMCIWQEEBCIWKNNXCGBPAEELMPCDQFMKFKAXVAGSKDPRXSZTXXQQQTGPLFLAUBOFMUGDIOZCEVABXEKOHUOYRNBXDOHIIUDDHQHDIHVVBOITYCNFFNULBWGLNZDKHNVAXMGDGDLSQRATNBKTBIOCXBPFTQRDLQGNNWUZFOYRRYJAPMQCQBXUWUBDVLICZJXVPHOHDYQENOMJGIPAYTBDYPMNNLBXGCAOXUNMFFPEVPFKUPGERNNDOZLFVKFCIBCPBUIMHOMCVVDKBVQIOVZQKBPMXABGNJGEPIVFIEDXYFXIDODKJZCXKNHVFQHUSFMJWXFBGRPDIPSMBVEOLMZGWNQLQUQIXKSKOOXTSPFJEDBMAXHDPKEFAMASMLUJBNUKLEYIXPJEKYFTEKNFJRQDYGCHVTKCSEQTRUHPBZPWTEBGWEKXISBPUHEAFAEPLLVVUIFCLZRTUPMIAJVUVLTHOTFPMZZHEMOFWCBPBUVUIWAZOIHJBFZRDXJSACARXYBGNXKHMSKUAMKEALQWTWLMLZTQHGPNYUFKBLFBOZEWEVSSDOBPFAPYNNEXVPZOKKUGSQYFIAEQJTYNLYOBQUDLQKZFVXQAJCCBVJWMPUUARURYPUQDCQOTOPBTTLLOEDPRWEKPPLKUEMCPBGDGJQOBXCSEVPYXUVNDZKVIUZLGJXDHOYQYDDIKSDZSLTWRDKTQMDSOHUWKFJPTEQUAULYGUBLSJRAJNEHSPLGUOORIZOMBTMYJUWBNJYBHNCPDKSKVENEMEAAACQPFLCPZVNOZSASBVDMAKTXATLKVXJCMONWIOSQEVQGXFMHRMGOXBFSUVOJMSXDJBKSWJGWDFWSBQSNLCZYWNWZEIMWXBEMGSIMNAQHVFXLDNQNSWNEARIQXRHGYGNYINFFTEKMTCBOUWZAHYKFYFMNDURMGBHNCPDHUWKFJPUARURYPXYBGNXKHLQUQIXKSQHUSFMJWXGDGDLSQRAATYZXIZNMURKTRIJLOTONFOGEWCAIMZNGOIRLOBIPXHXGKICIPAUFNTYYSFOLDYHFSKAQBQSFKMQINHUXCCRWLECVCPAHEUQRTJLJKBJJVVXTANNRTWBWHJGPLYQQSEVBHXVGTYZAVNZCEPTKIDZXHWFHOCFVFBIIUTSPOGRYRBNFFUTQJTDMQMPRKCOXZPQBKXSPCGDFOIPRFFMJNVMHRUKXLRXDXQAYBNNBJYLGBXPJXIUVLWGCEPCLDIMHIANMUJWOQHEUJVLGBXPJXIUVLWGCEPCLDIMHIASZKSLTEXPYUBMKTJHUBEUVSMCPKOBUKXNDLIHXDFSZKSLTEXPYUBMKTJHUBEUVSMCPKOBUKXNDLIHXDCAYPJKNCXKDEVRTVNDVKHUQEIGIEMWBQANSYWFWZODIJLVNRVRCJZQLTKCVLULPSYFYJOIBYFANLCOXNLQYJOHBNTASPKZEODIPCLPRXSYUPLACJNFMREFPAKZNXVRGSBDMSDVWIKJBHFNVNOCISHRGRVPWUFTHLRDTSLGYHMEWMXTRNQHRNSDVWIKJBHFNVNOCISHRGRVPWUFTHLRDTSLGYHMEWMXTRNQHRNVGPHRZJYXDJEIWKFSJLGXYYJEZHKYGPCCHDCSSBETHIKPFIOPQXLGWGJPDLDYIWBMDNGTKPTBNSBDCPVJXFFZZYHMKSCQRPRXABMMPFATBMLKUMJHWUZXXZGBABOJPBAGYLJFEOEFWLUZEZHMPAOYDBDSJWGNIGRDCDJRTYRIHVYSVSMQQADMBDMJLVKOEDPDVRKSEHPOXBKXEIYTLYZGNVNORDDPGZJYALPTUTVCDLMSVVSARMDMYTPTFVZJNLBJNOYFTCJSGBWGSRBRMCBCOHBJXQBPLKRLJOVSGJXCOYHUOPSZZDBWEZINFVGWNUWARJKPAVYTCVEIDNFNGXWFSDWEZPLDNOAEALDXYJZZPRYKXQIGVNHLGRQBDYMYBGKQXPZVNBSYTQNUWARJKPAVYTCVEIDNFNGXWFSDWEZPLDNOAERXNEZMMIHRXUHIENABWZZTJMISHXCZNGBBJEVCQGFNODVDDYQGTPCCCNFTDRXNEZMMIHRXUHIENABWZZTJMISHXCZNGBBJEVCQGFNODVDDYQGTPCCCNFTUKFUPQTQHXOIGJUTFWHLRAIZQCEUZDGRJQQLVDAPSVUCADRSWYAZUYEMPIUIIWJMBGHVWSNLFCFSJMXICSZRPFUQMFFDXZEDMEQVJMBPZQNSBYIZUWUQCWPCRAUYVIWJMBGHVWSNLFCFSJMXICSZRPFUQMFFDXZEDMEQVJMBPZQNSBYIZUWUQCWPCRAURCHYAIFKTGNOQVJXHPBQRNLMUOGMWYUTUQQCELTWULVIWJMBGHVWSNLFCFSJMXICSZRPFUQMFFBWLPUDTGGVSYYOFAKQDJINWKBAYGBKDKRVTXMTVKEYMUFKYOSHAITIDRHTOKNOJQQGZFTLLVYUNPHOWVEMIAKBWFVESZNWPHSHGXQBTSAEGBRXMFBTTUAXCIBPISWQKSLZCPOLQKPSLVHENGNLDMNGYZKXPCTSUYFBSWNKJQTCWJKNRMLHUTFBRPHOWVEMIAKBWFVESZNWPHSHGXQBTSAEGBRXMFBTTUAXCIBPSNGYVBWHMCGADBALGZBKGTSOQGSOSGACPXNNGRXFAZPLMBNNAFOOPMGICEPPFMGBQYNVQHLXBGHODWPHTWAWXOCNFSOIIOFCFIEIDODTDJGFMCYBPZRBXMNSXAIVBQYOWOLUXSDXZGVJTRZIWZXQIOEBAWVPSAWPZNARJQLQYQPLTNOKEZYGASUNTPKYXOTUNZMAGBUDKXIIAVLKJJLAOVWHQFXYNUISYONOEKXPDDKUFRMDKHIHTAHPJOWMIHQYQPLTNOKEZYGASUNTPKYXOTUNZMAGBUDKXIIAVLKJJLAOVWHQFXYNUISYONOEKXPDDKUFRMDKHIHTAHPJOWMIBHQYQPLTNOKEZYGASUNTPKYXOTUNZMAGBUDKXIIAVLKJJLAOVWHQFXYNUISYONOEKXPDDKUFRMDKHIHTAHPJOWMISGBHQYQPLTNOKEZYGASUNTPKYXOTUNZMAGBUDKXIIAVLKJJLAOVWHQFXYNUISYONOEKXPDDKUFRMDKHIHTAHPJOWMISHGBHQYQPLTNOKEZYGASUNTPKYXOTUNZMAGBUDKXIIAVLKJJLAOVWHQFXYNUISYONOEKXPDDKUFRMDKHIHTAHPJOWMISGDHGBHQYQPLTNOKEZYGASUNTPKYXOTUNZMAGBUDKXIIAVLKJJLAOVWHQFXYNUISYONOEKXPDDKUFRMDKHIHTAHPJOWMISGBGVPFHATKCBVEZQNLIJUQUARLFCGVRXIXZSHHQHDHGBHQYQPLTNOKEZYGASUNTPKYXOTUNZMAGBUDKXIIAVLKJJLAOVWHQFXBFLTSFLYWJGVPFHATKCBVEZQNLIJUQUARLFCGVRXIXZSHHQHDHGBHQYQPLTNOKEZYGASUNTPKYXOTUNZMAGBUDKXIIAVLKJJLAVTNNGLUKHQWSMQWVIEGQMYRSBDOCQSUVWWDYBARBOAPQNRNEPGDASZWTHFPEJKXKRMIRDSLASFPLPJYEJYREHMZCBZDNKRJFWHJAEFAXXFZRFFYWLKBUSUPWYESFIOLVITJEWFFKLTQUJCPDOBPLKBGLRGESJKSYMDRODNIRJMLUWVGEBVFLKJAZMAVSVVVVTFJDARCGVTNNGUBJMGXTJLAXXFZRFFYWLKBUSUPWYESFIOLVITJEWFFKLTQUJCPDOBPLKBGLRGESJKSYMDRODNIRJMLUWVGEBVFLKJAZMAVSVVVVTFJDARCGVNPQVIKSKFASRJPAUFNWZTDIDBXTUSEJHYYRLPFVYLUEOWAWVTJYHXPPDEDUCUIEUROMPFXCAHYLAKPIXHJBINAMIYAFYZNJBWMTVEHDZCTQZBHGXSJNPQVIKSKFASRJPAUFNWZTDIDBXTUSEJHYYRLPFVYLUEOWAWVTJYHXPPDEDUCUIEUROMPFXCAHYLAKPIXHJBINAMIYAFYZNJBWMTVEHDZCUBHGXSJNPQVIKSKFASRJPAUFNWZTDIDBXTUSEJHYYRLPFVYLUEOWAWVTJYHXPPDEDUCUIEUROMPFXCAHYLAKPIXHJBINAMIYAFYZNJBWMTVEHDZCTMHUKJXTFLDSABAYZNGRLGAFGFUBHGXSJNPQVIKSKFASRJPAUFNWZTDIDBXTUSEJHYYRLPFVYLUEOWAWVTJYHXPPDEDUCUIEUROMPFXCAHYLAKPIXHJBICTZORWDALOJJNJZYJWUEPHZOVEGRAFHBCRETBBBAKQUTIJNDCIBGNTZOXPGLVBNWSWWMLGOVKOQUXFAXZAQMPPKDSLQBUATEXZRAOSDGOPNVFSPLSNKIWUOZAARAZQXSQSWQEMKBDZPJLRRQPBRKJUJEICHUZOQUOGYWGUATEKLZAZIAQVWNHYHMXVZDYACNLBIHHETCMNNTCTPRIFYKHNFHGVPFWRYFLKHFGPEDNZZNDYTHHHAZQUQPKQQEJZDJOAPXOSMCBQMLGPUSNTWZOLTGHCBHVFMHHWMOIEWINCVJUCWMGOAPWLNFNOCDJRHJIWCMXOWKPLCATJMBKONEUJXGRSKQWTQWDUMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLITMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLIMNVUIYDHRTMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLIMNVUIYDHIRTMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLIMNVUIYDHHQIRTMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLIMNVUIYDHHEYQIRTMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLIMNVUIYDHHEFYQIRTMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLIMNVUIYDHHERFYQIRTMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLIMNVUIYDHHECPGKZPRFYQIRTMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLIMNVUIYDHHECPGKZFPRFYQIRTMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLIMNVUIYDHHECPGKVFPRFYQIRTMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLIMNVUIYDHHECPGKVODWEVFPRFYQIRTMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLIMNVUIYDHHEQVODWEVFPRFYQIRTMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLIMNVUIYDHHECPGQVODWEVFPRFYQIRTMOYRDCMLVOGPGMYJERFQBGYNZTLAYSFNQSOQKSDHDUAYBIOGVLRNCYUFQOBUXGIZNKJQSMTUHMUOCOOASMHJXDSCYCBXUZGRTPKJJCSCCKEYKDOYORJMDOSNWTJVWUJKSYBQWLIMNVUIYDHHECPGCVVHYZCXFVDALNLZOARGOCWBFVUQKKSLEMJRKQIHULBCYTZQNRVSLSTQHZAZTZZRTBVXTTHBZJAXCGRVSCRJSEEOJQXFAEAJECDWVEHTBYEIQNMLILIEAAHWBXHQXEDOJKYNBBMTWQDMLFKRQRPACBSRLULLNLMKETFZJEBWTXZDHVDXJMMNIYAQYXEPJVDKPKQBSMWLATYCUWYSYOJZHUDSXTCSHTRACDQOQSNCYLMXJBYBBWKSNHYAYVRLCWFGAZSEVBIUJETIVGHEBDPXLVFWWTCKOUCOAOPMUIRPYZCULRWRCTZLCGMGREFOGJMULHHHQQIAOXVOKLCVAXDEGHSEUYZHPTFECVAJSFUSFMCGQLMASXUPQYQSNYRSDZVWZUXCDNVVPGAUQRGCQFSQSDEBWTXZDHVDXJMMNIYAQYXEPJVDKPKQBSMWLATYCUWYSYOJZHUDSXTCSHTRACDQOQSNCYLMXJBYBBWKSNHYAYVRLCWFGCQJCQLPHFANJTGZXOJRGGMYHXKQVCLBAAKUPWGUWGXEAHQBGJRKABJEUQUKOUABOVZDUKHRRXSBCRCHDFDUXCRZCYCHAZCEGPJFUATVHUHTAFLKSHRYVNYBVXUFUFYXIVGRBRUWPZZRGGNAURWMPKFLCJUGYBJHHTJHCNZQVDVLMJCQJCQLPHFANJTGZXOJRGGMYHXKQVCLBAAKUPWGUWGXEAHQBGJRKABJEUQUKOUABOVZDUKHRRXSBCRCHDFDUXCRZCYCHAZCEGPJFUATVHUHTAFLKSHRYVNYBVXUFUFYXIVGRBRUWPZZRGGNAURWMPKFLCJUGYBJHHTJHCNZQVDVLMENSPFDIYBMWOBOSWHFITNIUEVEGGXDZYRAIRWTHSECVCCZETCBXGFWSJPHFLCTUNESIKYZKJCTZFOMBMWYHTTXRZKSTVNHJCQJCQLPHFANJTGZXOJRGGMYHXKQVCLBAAKUPWGUWGXEAHQBGJRKABJEUQUKOUABOVZDUKHRRXSBCRCHDFDUXCRZCLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBRCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCBMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCJFGBMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCJUGBMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCJFCQTTHUGBMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCJFCQTXHUGBMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCJFCQTAXHUGBMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCJFCQTAAXHUGBMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCJFCQZAAXHUGBMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCJFCQTTTZAAXHUGBMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCJFCQTUTZAAXHUGBMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCJFCQTOUTZAAXHUGBMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCJFCQTTKOUTZAAXHUGBMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCJFCQTTKLHVKOUTZAAXHUGBMWURCDKHFEEBLRVDUFOARAOFKXFESYNYRKSMLBUQYTCJSLHIHGMPTXAPLTINHRQXRLOSXQDEFLZEVHHSAGQBRNBPJEQVCKVOTUBGGOIRCWEEYQGCIPXJDFRZUPUTVXGMPSCOVBPUFYVPTEYXTRUHXARDSYTZTGDIHALCQZAIWRPDAYGNZDKMTIFEJHQTEMIYVARZJRWUDDXKMGUUQBWHZNWCJFCQTTKLHFYRPHKDPWHACQGQFLCDTXXZKYDGDDPOBSWEMPAAVFCEXQJDCBOZIRSOWELVYEKWNGRMNGMOPFVVLVIOYDJJMWJGMZCMNGRPMLMNJLPZKFRVYSTRPQOPBKREYFDCIQJLQANHNOIUMHAJAEHAVGSMDSJRNGVPTRTFHWNXPZDOOLHYYMGALWNVZYKHPGFEZNGDGFUIEUNYQKEAICMFOYYLDRJQXCKQUILBITRHCUSQMCNSDDCLMYRQWFYRPHKDPWHACQGQFLCDTXXZKYDGDDPOBSWEMPAAVFCEXQJDCBOZIRSOWELVYEKWNGRMNGMOPFVVLVIOYDJJMWJGMZCMNGRPMLMNJLPZKFRVYSTRPQOPBKREYFDCIQJLQANHNOIUMHAJAEHAVGSMDSJRNGVPTRTFHWNXPZDOOLHYYMGALWNVZYKHPGFEZNGDGFUIEUNYQKEAICMFOYYLDRJQXCKQUILBITRHCUSQMCNSDDCLMYRQXWFYRPHKDPWHACQGQFLCDTXXZKYDGDDPOBSWEMPAAVFCEXQJDCBOZIRSOWELVYEKWNGRMNGMOPFVVLVIOYDJJMWJGMZCMNGRPMLMNJLPZKFRVYSTRPQOPBKREYFDCIQJLQANHNOIUMHAJAEHAVGSMDSJRNGVPTRTFHWNXPZDOOLHYYMGALWNVZYKHPGFEZNGDGFUIEUNYQKEAICMFOYYLDRJQXCKQUILBITRHCUSQMCNSDDCLMYRNXWFYRPHKDPWHACQGQFLCDTXXZKYDGDDPOBSWEMPAAVFCEXQJDCBOZIRSOWELVYEKWNGRMNGMOPFVVLVIOYDJJMWJGMZCMNGRPMLMNJLPZKFRVYSTRPQOPBKREYFDCIQJLQANHNOIUMHAJAEHAVGSMDSJRNGVPTRTFHWNXPZDOOLHYYMGALWNVZYKHPGFEZNGDGFUIEUNYQKEAICMFOYYLDRJQXCKQUILBITRHCUSQMCNSDDCLMYRKNXWFYRPHKDPWHACQGQFLCDTXXZKYDGDDPOBSWEMPAAVFCEXQJDCBOZIRSOWELVYEKWNGRMNGMOPFVVLVIOYDJJMWJGMZCMNGRPMLMNJLPZKFRVYSTRPQOPBKREYFDCIQJLQANHNOIUMHAJAEHAVGSMDSJRNGVPTRTFHWNXPZDOOLHYYMGALWNVZYKHPGFEZNGDGFUIEUNYQKEAICMFOYYLDRJQXCKQUILBITRHCUSQMCNSDDCLMYRQUKNXWFYRPHKDPWHACQGQFLCDTXXZKYDGDDPOBSWEMPAAVFCEXQJDCBOZIRSOWELVYEKWNGRMNGMOPFVVLVIOYDJJMWJGMZCMNGRPMLMNJLPZKFRVYSTRPQOPBKREYFDCIQJLQANHNOIUMHAJAEHAVGSMDSJRNGVPTRTFHWNXPZDOOLHYYMGALWNVZYKHPGFEZNGDGFUIEUNYQKEAICMFOYYLDRJQXCKQUILBITRHCUSQMCNSDDCLMYRQIAUKNXWFYRPHKDPWHACQGQFLCDTXXZKYDGDDPOBSWEMPAAVFCEXQJDCBOZIRSOWELVYEKWNGRMNGMOPFVVLVIOYDJJMWJGMZCMNGRPMLMNJLPZKFRVYSTRPQOPBKREYFDCIQJLQANHNOIUMHAJAEHAVGSMDSJRNGVPTRTFHWNXPZDOOLHYYMGALWNVZYKHPGFEZNGDGFUIEUNYQKEAICMFOYYLDRJQXCKQUILBITRHCUSQMCNSDDCLMYRQIADAUKNXWFYRPHKDPWHACQGQFLCDTXXZKYDGDDPOBSWEMPAAVFCEXQJDCBOZIRSOWELVYEKWNGRMNGMOPFVVLVIOYDJJMWJGMZCMNGRPMLMNJLPZKFRVYSTRPQOPBKREYFDCIQJLQANHNOIUMHAJAEHAVGSMDSJRNGVPTRTFHWNXPZDOOLHYYMGALWNVZYKHPGFEZNGDGFUIEUNYQKEAICMFOYYLDRJQXCKQUILBITRHCUSQMCNSDDCLMYRQIIDAUKNXWFYRPHKDPWHACQGQFLCDTXXZKYDGDDPOBSWEMPAAVFCEXQJDCBOZIRSOWELVYEKWNGRMNGMOPFVVLVIOYDJJMWJGMZCMNGRPMLMNJLPZKFRVYSTRPQOPBKREYFDCIQJLQANHNOIUMHAJAEHAVGSMDSJRNGVPTRTFHWNXPZDOOLHYYMGALWNVZYKHPGFEZNGDGFUIEUNYQKEAICMFOYYLDRJQXCKQUILBITRHCUSQMCNSDDCLMYRQIAOM
diff --git a/src/zlib-ng/test/CVE-2018-25032/fixed.txt b/src/zlib-ng/test/CVE-2018-25032/fixed.txt
new file mode 100644
index 0000000..5ccca24
--- /dev/null
+++ b/src/zlib-ng/test/CVE-2018-25032/fixed.txt
@@ -0,0 +1 @@
+AAABAACAADAAEAAFAAGAAHAAIAAJAAKAALAAMAANAAOAAPAAQAARAASAATAAUAAVAAWAAXAAYAAZABBABCABDABEABFABGABHABIABJABKABLABMABNABOABPABQABRABSABTABUABVABWABXABYABZACBACCACDACEACFACGACHACIACJACKACLACMACNACOACPACQACRACSACTACUACVACWACXACYACZADBADCADDADEADFADGADHADIADJADKADLADMADNADOADPADQADRADSADTADUADVADWADXADYADZAEBAECAEDAEEAEFAEGAEHAEIAEJAEKAELAEMAENAEOAEPAEQAERAESAETAEUAEVAEWAEXAEYAEZAFBAFCAFDAFEAFFAFGAFHAFIAFJAFKAFLAFMAFNAFOAFPAFQAFRAFSAFTAFUAFVAFWAFXAFYAFZAGBAGCAGDAGEAGFAGGAGHAGIAGJAGKAGLAGMAGNAGOAGPAGQAGRAGSAGTAGUAGVAGWAGXAGYAGZAHBAHCAHDAHEAHFAHGAHHAHIAHJAHKAHLAHMAHNAHOAHPAHQAHRAHSAHTAHUAHVAHWAHXAHYAHZAIBAICAIDAIEAIFAIGAIHAIIAIJAIKAILAIMAINAIOAIPAIQAIRAISAITAIUAIVAIWAIXAIYAIZAJBAJCAJDAJEAJFAJGAJHAJIAJJAJKAJLAJMAJNAJOAJPAJQAJRAJSAJTAJUAJVAJWAJXAJYAJZAKBAKCAKDAKEAKFAKGAKHAKIAKJAKKAKLAKMAKNAKOAKPAKQAKRAKSAKTAKUAKVAKWAKXAKYAKZALBALCALDALEALFALGALHALIALJALKALLALMALNALOALPALQALRALSALTALUALVALWALXALYALZAMBAMCAMDAMEAMFAMGAMHAMIAMJAMKAMLAMMAMNAMOAMPAMQAMRAMSAMTAMUAMVAMWAMXAMYAMZANBANCANDANEANFANGANHANIANJANKANLANMANNANOANPANQANRANSANTANUANVANWANXANYANZAOBAOCAODAOEAOFAOGAOHAOIAOJAOKAOLAOMAONAOOAOPAOQAORAOSAOTAOUAOVAOWAOXAOYAOZAPBAPCAPDAPEAPFAPGAPHAPIAPJAPKAPLAPMAPNAPOAPPAPQAPRAPSAPTAPUAPVAPWAPXAPYAPZAQBAQCAQDAQEAQFAQGAQHAQIAQJAQKAQLAQMAQNAQOAQPAQQAQRAQSAQTAQUAQVAQWAQXAQYAQZARBARCARDAREARFARGARHARIARJARKARLARMARNAROARPARQARRARSARTARUARVARWARXARYARZASBASCASDASEASFASGASHASIASJASKASLASMASNASOASPASQASRASSASTASUASVASWASXASYASZATBATCATDATEATFATGATHATIATJATKATLATMATNATOATPATQATRATSATTATUATVATWATXATYATZAUBAUCAUDAUEAUFAUGAUHAUIAUJAUKAULAUMAUNAUOAUPAUQAURAUSAUTAUUAUVAUWAUXAUYAUZAVBAVCAVDAVEAVFAVGAVHAVIAVJAVKAVLAVMAVNAVOAVPAVQAVRAVSAVTAVUAVVAVWAVXAVYAVZAWBAWCAWDAWEAWFAWGAWHAWIAWJAWKAWLAWMAWNAWOAWPAWQAWRAWSAWTAWUAWVAWWAWXAWYAWZAXBAXCAXDAXEAXFAXGAXHAXIAXJAXKAXLAXMAXNAXOAXPAXQAXRAXSAXTAXUAXVAXWAXXAXYAXZAYBAYCAYDAYEAYFAYGAYHAYIAYJAYKAYLAYMAYNAYOAYPAYQAYRAYSAYTAYUAYVAYWAYXAYYAYZAZBAZCAZDAZEAZFAZGAZHAZIAZJAZKAZLAZMAZNAZOAZPAZQAZRAZSAZTAZUAZVAZWAZXAZYAZZBBBCBBDBBEBBFBBGBBHBBIBBJBBKBBLBBMBBNBBOBBPBBQBBRBBSBBTBBUBBVBBWBBXBBYBBZBCCBCDBCEBCFBCGBCHBCIBCJBCKBCLBCMBCNBCOBCPBCQBCRBCSBCTBCUBCVBCWBCXBCYBCZBDCBDDBDEBDFBDGBDHBDIBDJBDKBDLBDMBDNBDOBDPBDQBDRBDSBDTBDUBDVBDWBDXBDYBDZBECBEDBEEBEFBEGBEHBEIBEJBEKBELBEMBENBEOBEPBEQBERBESBETBEUBEVBEWBEXBEYBEZBFCBFDBFEBFFBFGBFHBFIBFJBFKBFLBFMBFNBFOBFPBFQBFRBFSBFTBFUBFVBFWBFXBFYBFZBGCBGDBGEBGFBGGBGHBGIBGJBGKBGLBGMBGNBGOBGPBGQBGRBGSBGTBGUBGVBGWBGXBGYBGZBHCBHDBHEBHFBHGBHHBHIBHJBHKBHLBHMBHNBHOBHPBHQBHRBHSBHTBHUBHVBHWBHXBHYBHZBICBIDBIEBIFBIGBIHBIIBIJBIKBILBIMBINBIOBIPBIQBIRBISBITBIUBIVBIWBIXBIYBIZBJCBJDBJEBJFBJGBJHBJIBJJBJKBJLBJMBJNBJOBJPBJQBJRBJSBJTBJUBJVBJWBJXBJYBJZBKCBKDBKEBKFBKGBKHBKIBKJBKKBKLBKMBKNBKOBKPBKQBKRBKSBKTBKUBKVBKWBKXBKYBKZBLCBLDBLEBLFBLGBLHBLIBLJBLKBLLBLMBLNBLOBLPBLQBLRBLSBLTBLUBLVBLWBLXBLYBLZBMCBMDBMEBMFBMGBMHBMIBMJBMKBMLBMMBMNBMOBMPBMQBMRBMSBMTBMUBMVBMWBMXBMYBMZBNCBNDBNEBNFBNGBNHBNIBNJBNKBNLBNMBNNBNOBNPBNQBNRBNSBNTBNUBNVBNWBNXBNYBNZBOCBODBOEBOFBOGBOHBOIBOJBOKBOLBOMBONBOOBOPBOQBORBOSBOTBOUBOVBOWBOXBOYBOZBPCBPDBPEBPFBPGBPHBPIBPJBPKBPLBPMBPNBPOBPPBPQBPRBPSBPTBPUBPVBPWBPXBPYBPZBQCBQDBQEBQFBQGBQHBQIBQJBQKBQLBQMBQNBQOBQPBQQBQRBQSBQTBQUBQVBQWBQXBQYBQZBRCBRDBREBRFBRGBRHBRIBRJBRKBRLBRMBRNBROBRPBRQBRRBRSBRTBRUBRVBRWBRXBRYBRZBSCBSDBSEBSFBSGBSHBSIBSJBSKBSLBSMBSNBSOBSPBSQBSRBSSBSTBSUBSVBSWBSXBSYBSZBTCBTDBTEBTFBTGBTHBTIBTJBTKBTLBTMBTNBTOBTPBTQBTRBTSBTTBTUBTVBTWBTXBTYBTZBUCBUDBUEBUFBUGBUHBUIBUJBUKBULBUMBUNBUOBUPBUQBURBUSBUTBUUBUVBUWBUXBUYBUZBVCBVDBVEBVFBVGBVHBVIBVJBVKBVLBVMBVNBVOBVPBVQBVRBVSBVTBVUBVVBVWBVXBVYBVZBWCBWDBWEBWFBWGBWHBWIBWJBWKBWLBWMBWNBWOBWPBWQBWRBWSBWTBWUBWVBWWBWXBWYBWZBXCBXDBXEBXFBXGBXHBXIBXJBXKBXLBXMBXNBXOBXPBXQBXRBXSBXTBXUBXVBXWBXXBXYBXZBYCBYDBYEBYFBYGBYHBYIBYJBYKBYLBYMBYNBYOBYPBYQBYRBYSBYTBYUBYVBYWBYXBYYBYZBZCBZDBZEBZFBZGBZHBZIBZJBZKBZLBZMBZNBZOBZPBZQBZRBZSBZTBZUBZVBZWBZXBZYBZZCCCDCCECCFCCGCCHCCICCJCCKCCLCCMCCNCCOCCPCCQCCRCCSCCTCCUCCVCCWCCXCCYCCZCDDCDECDFCDGCDHCDICDJCDKCDLCDMCDNCDOCDPCDQCDRCDSCDTCDUCDVCDWCDXCDYCDZCEDCEECEFCEGCEHCEICEJCEKCELCEMCENCEOCEPCEQCERCESCETCEUCEVCEWCEXCEYCEZCFDCFECFFCFGCFHCFICFJCFKCFLCFMCFNCFOCFPCFQCFRCFSCFTCFUCFVCFWCFXCFYCFZCGDCGECGFCGGCGHCGICGJCGKCGLCGMCGNCGOCGPCGQCGRCGSCGTCGUCGVCGWCGXCGYCGZCHDCHECHFCHGCHHCHICHJCHKCHLCHMCHNCHOCHPCHQCHRCHSCHTCHUCHVCHWCHXCHYCHZCIDCIECIFCIGCIHCIICIJCIKCILCIMCINCIOCIPCIQCIRCISCITCIUCIVCIWCIXCIYCIZCJDCJECJFCJGCJHCJICJJCJKCJLCJMCJNCJOCJPCJQCJRCJSCJTCJUCJVCJWCJXCJYCJZCKDCKECKFCKGCKHCKICKJCKKCKLCKMCKNCKOCKPCKQCKRCKSCKTCKUCKVCKWCKXCKYCKZCLDCLECLFCLGCLHCLICLJCLKCLLCLMCLNCLOCLPCLQCLRCLSCLTCLUCLVCLWCLXCLYCLZCMDCMECMFCMGCMHCMICMJCMKCMLCMMCMNCMOCMPCMQCMRCMSCMTCMUCMVCMWCMXCMYCMZCNDCNECNFCNGCNHCNICNJCNKCNLCNMCNNCNOCNPCNQCNRCNSCNTCNUCNVCNWCNXCNYCNZCODCOECOFCOGCOHCOICOJCOKCOLCOMCONCOOCOPCOQCORCOSCOTCOUCOVCOWCOXCOYCOZCPDCPECPFCPGCPHCPICPJCPKCPLCPMCPNCPOCPPCPQCPRCPSCPTCPUCPVCPWCPXCPYCPZCQDCQECQFCQGCQHCQICQJCQKCQLCQMCQNCQOCQPCQQCQRCQSCQTCQUCQVCQWCQXCQYCQZCRDCRECRFCRGCRHCRICRJCRKCRLCRMCRNCROCRPCRQCRRCRSCRTCRUCRVCRWCRXCRYCRZCSDCSECSFCSGCSHCSICSJCSKCSLCSMCSNCSOCSPCSQCSRCSSCSTCSUCSVCSWCSXCSYCSZCTDCTECTFCTGCTHCTICTJCTKCTLCTMCTNCTOCTPCTQCTRCTSCTTCTUCTVCTWCTXCTYCTZCUDCUECUFCUGCUHCUICUJCUKCULCUMCUNCUOCUPCUQCURCUSCUTCUUCUVCUWCUXCUYCUZCVDCVECVFCVGCVHCVICVJCVKCVLCVMCVNCVOCVPCVQCVRCVSCVTCVUCVVCVWCVXCVYCVZCWDCWECWFCWGCWHCWICWJCWKCWLCWMCWNCWOCWPCWQCWRCWSCWTCWUCWVCWWCWXCWYCWZCXDCXECXFCXGCXHCXICXJCXKCXLCXMCXNCXOCXPCXQCXRCXSCXTCXUCXVCXWCXXCXYCXZCYDCYECYFCYGCYHCYICYJCYKCYLCYMCYNCYOCYPCYQCYRCYSCYTCYUCYVCYWCYXCYYCYZCZDCZECZFCZGCZHCZICZJCZKCZLCZMCZNCZOCZPCZQCZRCZSCZTCZUCZVCZWCZXCZYCZZDDDEDDFDDGDDHDDIDDJDDKDDLDDMDDNDDODDPDDQDDRDDSDDTDDUDDVDDWDDXDDYDDZDEEDEFDEGDEHDEIDEJDEKDELDEMDENDEODEPDEQDERDESDETDEUDEVDEWDEXDEYDEZDFEDFFDFGDFHDFIDFJDFKDFLDFMDFNDFODFPDFQDFRDFSDFTDFUDFVDFWDFXDFYDFZDGEDGFDGGDGHDGIDGJDGKDGLDGMDGNDGODGPDGQDGRDGSDGTDGUDGVDGWDGXDGYDGZDHEDHFDHGDHHDHIDHJDHKDHLDHMDHNDHODHPDHQDHRDHSDHTDHUDHVDHWDHXDHYDHZDIEDIFDIGDIHDIIDIJDIKDILDIMDINDIODIPDIQDIRDISDITDIUDIVDIWDIXDIYDIZDJEDJFDJGDJHDJIDJJDJKDJLDJMDJNDJODJPDJQDJRDJSDJTDJUDJVDJWDJXDJYDJZDKEDKFDKGDKHDKIDKJDKKDKLDKMDKNDKODKPDKQDKRDKSDKTDKUDKVDKWDKXDKYDKZDLEDLFDLGDLHDLIDLJDLKDLLDLMDLNDLODLPDLQDLRDLSDLTDLUDLVDLWDLXDLYDLZDMEDMFDMGDMHDMIDMJDMKDMLDMMDMNDMODMPDMQDMRDMSDMTDMUDMVDMWDMXDMYDMZDNEDNFDNGDNHDNIDNJDNKDNLDNMDNNDNODNPDNQDNRDNSDNTDNUDNVDNWDNXDNYDNZDOEDOFDOGDOHDOIDOJDOKDOLDOMDONDOODOPDOQDORDOSDOTDOUDOVDOWDOXDOYDOZDPEDPFDPGDPHDPIDPJDPKDPLDPMDPNDPODPPDPQDPRDPSDPTDPUDPVDPWDPXDPYDPZDQEDQFDQGDQHDQIDQJDQKDQLDQMDQNDQODQPDQQDQRDQSDQTDQUDQVDQWDQXDQYDQZDREDRFDRGDRHDRIDRJDRKDRLDRMDRNDRODRPDRQDRRDRSDRTDRUDRVDRWDRXDRYDRZDSEDSFDSGDSHDSIDSJDSKDSLDSMDSNDSODSPDSQDSRDSSDSTDSUDSVDSWDSXDSYDSZDTEDTFDTGDTHDTIDTJDTKDTLDTMDTNDTODTPDTQDTRDTSDTTDTUDTVDTWDTXDTYDTZDUEDUFDUGDUHDUIDUJDUKDULDUMDUNDUODUPDUQDURDUSDUTDUUDUVDUWDUXDUYDUZDVEDVFDVGDVHDVIDVJDVKDVLDVMDVNDVODVPDVQDVRDVSDVTDVUDVVDVWDVXDVYDVZDWEDWFDWGDWHDWIDWJDWKDWLDWMDWNDWODWPDWQDWRDWSDWTDWUDWVDWWDWXDWYDWZDXEDXFDXGDXHDXIDXJDXKDXLDXMDXNDXODXPDXQDXRDXSDXTDXUDXVDXWDXXDXYDXZDYEDYFDYGDYHDYIDYJDYKDYLDYMDYNDYODYPDYQDYRDYSDYTDYUDYVDYWDYXDYYDYZDZEDZFDZGDZHDZIDZJDZKDZLDZMDZNDZODZPDZQDZRDZSDZTDZUDZVDZWDZXDZYDZZEEEFEEGEEHEEIEEJEEKEELEEMEENEEOEEPEEQEEREESEETEEUEEVEEWEEXEEYEEZEFFEFGEFHEFIEFJEFKEFLEFMEFNEFOEFPEFQEFREFSEFTEFUEFVEFWEFXEFYEFZEGFEGGEGHEGIEGJEGKEGLEGMEGNEGOEGPEGQEGREGSEGTEGUEGVEGWEGXEGYEGZEHFEHGEHHEHIEHJEHKEHLEHMEHNEHOEHPEHQEHREHSEHTEHUEHVEHWEHXEHYEHZEIFEIGEIHEIIEIJEIKEILEIMEINEIOEIPEIQEIREISEITEIUEIVEIWEIXEIYEIZEJFEJGEJHEJIEJJEJKEJLEJMEJNEJOEJPEJQEJREJSEJTEJUEJVEJWEJXEJYEJZEKFEKGEKHEKIEKJEKKEKLEKMEKNEKOEKPEKQEKREKSEKTEKUEKVEKWEKXEKYEKZELFELGELHELIELJELKELLELMELNELOELPELQELRELSELTELUELVELWELXELYELZEMFEMGEMHEMIEMJEMKEMLEMMEMNEMOEMPEMQEMREMSEMTEMUEMVEMWEMXEMYEMZENFENGENHENIENJENKENLENMENNENOENPENQENRENSENTENUENVENWENXENYENZEOFEOGEOHEOIEOJEOKEOLEOMEONEOOEOPEOQEOREOSEOTEOUEOVEOWEOXEOYEOZEPFEPGEPHEPIEPJEPKEPLEPMEPNEPOEPPEPQEPREPSEPTEPUEPVEPWEPXEPYEPZEQFEQGEQHEQIEQJEQKEQLEQMEQNEQOEQPEQQEQREQSEQTEQUEQVEQWEQXEQYEQZERFERGERHERIERJERKERLERMERNEROERPERQERRERSERTERUERVERWERXERYERZESFESGESHESIESJESKESLESMESNESOESPESQESRESSESTESUESVESWESXESYESZETFETGETHETIETJETKETLETMETNETOETPETQETRETSETTETUETVETWETXETYETZEUFEUGEUHEUIEUJEUKEULEUMEUNEUOEUPEUQEUREUSEUTEUUEUVEUWEUXEUYEUZEVFEVGEVHEVIEVJEVKEVLEVMEVNEVOEVPEVQEVREVSEVTEVUEVVEVWEVXEVYEVZEWFEWGEWHEWIEWJEWKEWLEWMEWNEWOEWPEWQEWREWSEWTEWUEWVEWWEWXEWYEWZEXFEXGEXHEXIEXJEXKEXLEXMEXNEXOEXPEXQEXREXSEXTEXUEXVEXWEXXEXYEXZEYFEYGEYHEYIEYJEYKEYLEYMEYNEYOEYPEYQEYREYSEYTEYUEYVEYWEYXEYYEYZEZFEZGEZHEZIEZJEZKEZLEZMEZNEZOEZPEZQEZREZSEZTEZUEZVEZWEZXEZYEZZFFFGFFHFFIFFJFFKFFLFFMFFNFFOFFPFFQFFRFFSFFTFFUFFVFFWFFXFFYFFZFGGFGHFGIFGJFGKFGLFGMFGNFGOFGPFGQFGRFGSFGTFGUFGVFGWFGXFGYFGZFHGFHHFHIFHJFHKFHLFHMFHNFHOFHPFHQFHRFHSFHTFHUFHVFHWFHXFHYFHZFIGFIHFIIFIJFIKFILFIMFINFIOFIPFIQFIRFISFITFIUFIVFIWFIXFIYFIZFJGFJHFJIFJJFJKFJLFJMFJNFJOFJPFJQFJRFJSFJTFJUFJVFJWFJXFJYFJZFKGFKHFKIFKJFKKFKLFKMFKNFKOFKPFKQFKRFKSFKTFKUFKVFKWFKXFKYFKZFLGFLHFLIFLJFLKFLLFLMFLNFLOFLPFLQFLRFLSFLTFLUFLVFLWFLXFLYFLZFMGFMHFMIFMJFMKFMLFMMFMNFMOFMPFMQFMRFMSFMTFMUFMVFMWFMXFMYFMZFNGFNHFNIFNJFNKFNLFNMFNNFNOFNPFNQFNRFNSFNTFNUFNVFNWFNXFNYFNZFOGFOHFOIFOJFOKFOLFOMFONFOOFOPFOQFORFOSFOTFOUFOVFOWFOXFOYFOZFPGFPHFPIFPJFPKFPLFPMFPNFPOFPPFPQFPRFPSFPTFPUFPVFPWFPXFPYFPZFQGFQHFQIFQJFQKFQLFQMFQNFQOFQPFQQFQRFQSFQTFQUFQVFQWFQXFQYFQZFRGFRHFRIFRJFRKFRLFRMFRNFROFRPFRQFRRFRSFRTFRUFRVFRWFRXFRYFRZFSGFSHFSIFSJFSKFSLFSMFSNFSOFSPFSQFSRFSSFSTFSUFSVFSWFSXFSYFSZFTGFTHFTIFTJFTKFTLFTMFTNFTOFTPFTQFTRFTSFTTFTUFTVFTWFTXFTYFTZFUGFUHFUIFUJFUKFULFUMFUNFUOFUPFUQFURFUSFUTFUUFUVFUWFUXFUYFUZFVGFVHFVIFVJFVKFVLFVMFVNFVOFVPFVQFVRFVSFVTFVUFVVFVWFVXFVYFVZFWGFWHFWIFWJFWKFWLFWMFWNFWOFWPFWQFWRFWSFWTFWUFWVFWWFWXFWYFWZFXGFXHFXIFXJFXKFXLFXMFXNFXOFXPFXQFXRFXSFXTFXUFXVFXWFXXFXYFXZFYGFYHFYIFYJFYKFYLFYMFYNFYOFYPFYQFYRFYSFYTFYUFYVFYWFYXFYYFYZFZGFZHFZIFZJFZKFZLFZMFZNFZOFZPFZQFZRFZSFZTFZUFZVFZWFZXFZYFZZGGGHGGIGGJGGKGGLGGMGGNGGOGGPGGQGGRGGSGGTGGUGGVGGWGGXGGYGGZGHHGHIGHJGHKGHLGHMGHNGHOGHPGHQGHRGHSGHTGHUGHVGHWGHXGHYGHZGIHGIIGIJGIKGILGIMGINGIOGIPGIQGIRGISGITGIUGIVGIWGIXGIYGIZGJHGJIGJJGJKGJLGJMGJNGJOGJPGJQGJRGJSGJTGJUGJVGJWGJXGJYGJZGKHGKIGKJGKKGKLGKMGKNGKOGKPGKQGKRGKSGKTGKUGKVGKWGKXGKYGKZGLHGLIGLJGLKGLLGLMGLNGLOGLPGLQGLRGLSGLTGLUGLVGLWGLXGLYGLZGMHGMIGMJGMKGMLGMMGMNGMOGMPGMQGMRGMSGMTGMUGMVGMWGMXGMYGMZGNHGNIGNJGNKGNLGNMGNNGNOGNPGNQGNRGNSGNTGNUGNVGNWGNXGNYGNZGOHGOIGOJGOKGOLGOMGONGOOGOPGOQGORGOSGOTGOUGOVGOWGOXGOYGOZGPHGPIGPJGPKGPLGPMGPNGPOGPPGPQGPRGPSGPTGPUGPVGPWGPXGPYGPZGQHGQIGQJGQKGQLGQMGQNGQOGQPGQQGQRGQSGQTGQUGQVGQWGQXGQYGQZGRHGRIGRJGRKGRLGRMGRNGROGRPGRQGRRGRSGRTGRUGRVGRWGRXGRYGRZGSHGSIGSJGSKGSLGSMGSNGSOGSPGSQGSRGSSGSTGSUGSVGSWGSXGSYGSZGTHGTIGTJGTKGTLGTMGTNGTOGTPGTQGTRGTSGTTGTUGTVGTWGTXGTYGTZGUHGUIGUJGUKGULGUMGUNGUOGUPGUQGURGUSGUTGUUGUVGUWGUXGUYGUZGVHGVIGVJGVKGVLGVMGVNGVOGVPGVQGVRGVSGVTGVUGVVGVWGVXGVYGVZGWHGWIGWJGWKGWLGWMGWNGWOGWPGWQGWRGWSGWTGWUGWVGWWGWXGWYGWZGXHGXIGXJGXKGXLGXMGXNGXOGXPGXQGXRGXSGXTGXUGXVGXWGXXGXYGXZGYHGYIGYJGYKGYLGYMGYNGYOGYPGYQGYRGYSGYTGYUGYVGYWGYXGYYGYZGZHGZIGZJGZKGZLGZMGZNGZOGZPGZQGZRGZSGZTGZUGZVGZWGZXGZYGZZHHHIHHJHHKHHLHHMHHNHHOHHPHHQHHRHHSHHTHHUHHVHHWHHXHHYHHZHIIHIJHIKHILHIMHINHIOHIPHIQHIRHISHITHIUHIVHIWHIXHIYHIZHJIHJJHJKHJLHJMHJNHJOHJPHJQHJRHJSHJTHJUHJVHJWHJXHJYHJZHKIHKJHKKHKLHKMHKNHKOHKPHKQHKRHKSHKTHKUHKVHKWHKXHKYHKZHLIHLJHLKHLLHLMHLNHLOHLPHLQHLRHLSHLTHLUHLVHLWHLXHLYHLZHMIHMJHMKHMLHMMHMNHMOHMPHMQHMRHMSHMTHMUHMVHMWHMXHMYHMZHNIHNJHNKHNLHNMHNNHNOHNPHNQHNRHNSHNTHNUHNVHNWHNXHNYHNZHOIHOJHOKHOLHOMHONHOOHOPHOQHORHOSHOTHOUHOVHOWHOXHOYHOZHPIHPJHPKHPLHPMHPNHPOHPPHPQHPRHPSHPTHPUHPVHPWHPXHPYHPZHQIHQJHQKHQLHQMHQNHQOHQPHQQHQRHQSHQTHQUHQVHQWHQXHQYHQZHRIHRJHRKHRLHRMHRNHROHRPHRQHRRHRSHRTHRUHRVHRWHRXHRYHRZHSIHSJHSKHSLHSMHSNHSOHSPHSQHSRHSSHSTHSUHSVHSWHSXHSYHSZHTIHTJHTKHTLHTMHTNHTOHTPHTQHTRHTSHTTHTUHTVHTWHTXHTYHTZHUIHUJHUKHULHUMHUNHUOHUPHUQHURHUSHUTHUUHUVHUWHUXHUYHUZHVIHVJHVKHVLHVMHVNHVOHVPHVQHVRHVSHVTHVUHVVHVWHVXHVYHVZHWIHWJHWKHWLHWMHWNHWOHWPHWQHWRHWSHWTHWUHWVHWWHWXHWYHWZHXIHXJHXKHXLHXMHXNHXOHXPHXQHXRHXSHXTHXUHXVHXWHXXHXYHXZHYIHYJHYKHYLHYMHYNHYOHYPHYQHYRHYSHYTHYUHYVHYWHYXHYYHYZHZIHZJHZKHZLHZMHZNHZOHZPHZQHZRHZSHZTHZUHZVHZWHZXHZYHZZIIIJIIKIILIIMIINIIOIIPIIQIIRIISIITIIUIIVIIWIIXIIYIIZIJJIJKIJLIJMIJNIJOIJPIJQIJRIJSIJTIJUIJVIJWIJXIJYIJZIKJIKKIKLIKMIKNIKOIKPIKQIKRIKSIKTIKUIKVIKWIKXIKYIKZILJILKILLILMILNILOILPILQILRILSILTILUILVILWILXILYILZIMJIMKIMLIMMIMNIMOIMPIMQIMRIMSIMTIMUIMVIMWIMXIMYIMZINJINKINLINMINNINOINPINQINRINSINTINUINVINWINXINYINZIOJIOKIOLIOMIONIOOIOPIOQIORIOSIOTIOUIOVIOWIOXIOYIOZIPJIPKIPLIPMIPNIPOIPPIPQIPRIPSIPTIPUIPVIPWIPXIPYIPZIQJIQKIQLIQMIQNIQOIQPIQQIQRIQSIQTIQUIQVIQWIQXIQYIQZIRJIRKIRLIRMIRNIROIRPIRQIRRIRSIRTIRUIRVIRWIRXIRYIRZISJISKISLISMISNISOISPISQISRISSISTISUISVISWISXISYISZITJITKITLITMITNITOITPITQITRITSITTITUITVITWITXITYITZIUJIUKIULIUMIUNIUOIUPIUQIURIUSIUTIUUIUVIUWIUXIUYIUZIVJIVKIVLIVMIVNIVOIVPIVQIVRIVSIVTIVUIVVIVWIVXIVYIVZIWJIWKIWLIWMIWNIWOIWPIWQIWRIWSIWTIWUIWVIWWIWXIWYIWZIXJIXKIXLIXMIXNIXOIXPIXQIXRIXSIXTIXUIXVIXWIXXIXYIXZIYJIYKIYLIYMIYNIYOIYPIYQIYRIYSIYTIYUIYVIYWIYXIYYIYZIZJIZKIZLIZMIZNIZOIZPIZQIZRIZSIZTIZUIZVIZWIZXIZYIZZJJJKJJLJJMJJNJJOJJPJJQJJRJJSJJTJJUJJVJJWJJXJJYJJZJKKJKLJKMJKNJKOJKPJKQJKRJKSJKTJKUJKVJKWJKXJKYJKZJLKJLLJLMJLNJLOJLPJLQJLRJLSJLTJLUJLVJLWJLXJLYJLZJMKJMLJMMJMNJMOJMPJMQJMRJMSJMTJMUJMVJMWJMXJMYJMZJNKJNLJNMJNNJNOJNPJNQJNRJNSJNTJNUJNVJNWJNXJNYJNZJOKJOLJOMJONJOOJOPJOQJORJOSJOTJOUJOVJOWJOXJOYJOZJPKJPLJPMJPNJPOJPPJPQJPRJPSJPTJPUJPVJPWJPXJPYJPZJQKJQLJQMJQNJQOJQPJQQJQRJQSJQTJQUJQVJQWJQXJQYJQZJRKJRLJRMJRNJROJRPJRQJRRJRSJRTJRUJRVJRWJRXJRYJRZJSKJSLJSMJSNJSOJSPJSQJSRJSSJSTJSUJSVJSWJSXJSYJSZJTKJTLJTMJTNJTOJTPJTQJTRJTSJTTJTUJTVJTWJTXJTYJTZJUKJULJUMJUNJUOJUPJUQJURJUSJUTJUUJUVJUWJUXJUYJUZJVKJVLJVMJVNJVOJVPJVQJVRJVSJVTJVUJVVJVWJVXJVYJVZJWKJWLJWMJWNJWOJWPJWQJWRJWSJWTJWUJWVJWWJWXJWYJWZJXKJXLJXMJXNJXOJXPJXQJXRJXSJXTJXUJXVJXWJXXJXYJXZJYKJYLJYMJYNJYOJYPJYQJYRJYSJYTJYUJYVJYWJYXJYYJYZJZKJZLJZMJZNJZOJZPJZQJZRJZSJZTJZUJZVJZWJZXJZYJZZKKKLKKMKKNKKOKKPKKQKKRKKSKKTKKUKKVKKWKKXKKYKKZKLLKLMKLNKLOKLPKLQKLRKLSKLTKLUKLVKLWKLXKLYKLZKMLKMMKMNKMOKMPKMQKMRKMSKMTKMUKMVKMWKMXKMYKMZKNLKNMKNNKNOKNPKNQKNRKNSKNTKNUKNVKNWKNXKNYKNZKOLKOMKONKOOKOPKOQKORKOSKOTKOUKOVKOWKOXKOYKOZKPLKPMKPNKPOKPPKPQKPRKPSKPTKPUKPVKPWKPXKPYKPZKQLKQMKQNKQOKQPKQQKQRKQSKQTKQUKQVKQWKQXKQYKQZKRLKRMKRNKROKRPKRQKRRKRSKRTKRUKRVKRWKRXKRYKRZKSLKSMKSNKSOKSPKSQKSRKSSKSTKSUKSVKSWKSXKSYKSZKTLKTMKTNKTOKTPKTQKTRKTSKTTKTUKTVKTWKTXKTYKTZKULKUMKUNKUOKUPKUQKURKUSKUTKUUKUVKUWKUXKUYKUZKVLKVMKVNKVOKVPKVQKVRKVSKVTKVUKVVKVWKVXKVYKVZKWLKWMKWNKWOKWPKWQKWRKWSKWTKWUKWVKWWKWXKWYKWZKXLKXMKXNKXOKXPKXQKXRKXSKXTKXUKXVKXWKXXKXYKXZKYLKYMKYNKYOKYPKYQKYRKYSKYTKYUKYVKYWKYXKYYKYZKZLKZMKZNKZOKZPKZQKZRKZSKZTKZUKZVKZWKZXKZYKZZLLLMLLNLLOLLPLLQLLRLLSLLTLLULLVLLWLLXLLYLLZLMMLMNLMOLMPLMQLMRLMSLMTLMULMVLMWLMXLMYLMZLNMLNNLNOLNPLNQLNRLNSLNTLNULNVLNWLNXLNYLNZLOMLONLOOLOPLOQLORLOSLOTLOULOVLOWLOXLOYLOZLPMLPNLPOLPPLPQLPRLPSLPTLPULPVLPWLPXLPYLPZLQMLQNLQOLQPLQQLQRLQSLQTLQULQVLQWLQXLQYLQZLRMLRNLROLRPLRQLRRLRSLRTLRULRVLRWLRXLRYLRZLSMLSNLSOLSPLSQLSRLSSLSTLSULSVLSWLSXLSYLSZLTMLTNLTOLTPLTQLTRLTSLTTLTULTVLTWLTXLTYLTZLUMLUNLUOLUPLUQLURLUSLUTLUULUVLUWLUXLUYLUZLVMLVNLVOLVPLVQLVRLVSLVTLVULVVLVWLVXLVYLVZLWMLWNLWOLWPLWQLWRLWSLWTLWULWVLWWLWXLWYLWZLXMLXNLXOLXPLXQLXRLXSLXTLXULXVLXWLXXLXYLXZLYMLYNLYOLYPLYQLYRLYSLYTLYULYVLYWLYXLYYLYZLZMLZNLZOLZPLZQLZRLZSLZTLZULZVLZWLZXLZYLZZMMMNMMOMMPMMQMMRMMSMMTMMUMMVMMWMMXMMYMMZMNNMNOMNPMNQMNRMNSMNTMNUMNVMNWMNXMNYMNZMONMOOMOPMOQMORMOSMOTMOUMOVMOWMOXMOYMOZMPNMPOMPPMPQMPRMPSMPTMPUMPVMPWMPXMPYMPZMQNMQOMQPMQQMQRMQSMQTMQUMQVMQWMQXMQYMQZMRNMROMRPMRQMRRMRSMRTMRUMRVMRWMRXMRYMRZMSNMSOMSPMSQMSRMSSMSTMSUMSVMSWMSXMSYMSZMTNMTOMTPMTQMTRMTSMTTMTUMTVMTWMTXMTYMTZMUNMUOMUPMUQMURMUSMUTMUUMUVMUWMUXMUYMUZMVNMVOMVPMVQMVRMVSMVTMVUMVVMVWMVXMVYMVZMWNMWOMWPMWQMWRMWSMWTMWUMWVMWWMWXMWYMWZMXNMXOMXPMXQMXRMXSMXTMXUMXVMXWMXXMXYMXZMYNMYOMYPMYQMYRMYSMYTMYUMYVMYWMYXMYYMYZMZNMZOMZPMZQMZRMZSMZTMZUMZVMZWMZXMZYMZZNNNONNPNNQNNRNNSNNTNNUNNVNNWNNXNNYNNZNOONOPNOQNORNOSNOTNOUNOVNOWNOXNOYNOZNPONPPNPQNPRNPSNPTNPUNPVNPWNPXNPYNPZNQONQPNQQNQRNQSNQTNQUNQVNQWNQXNQYNQZNRONRPNRQNRRNRSNRTNRUNRVNRWNRXNRYNRZNSONSPNSQNSRNSSNSTNSUNSVNSWNSXNSYNSZNTONTPNTQNTRNTSNTTNTUNTVNTWNTXNTYNTZNUONUPNUQNURNUSNUTNUUNUVNUWNUXNUYNUZNVONVPNVQNVRNVSNVTNVUNVVNVWNVXNVYNVZNWONWPNWQNWRNWSNWTNWUNWVNWWNWXNWYNWZNXONXPNXQNXRNXSNXTNXUNXVNXWNXXNXYNXZNYONYPNYQNYRNYSNYTNYUNYVNYWNYXNYYNYZNZONZPNZQNZRNZSNZTNZUNZVNZWNZXNZYNZZOOOPOOQOOROOSOOTOOUOOVOOWOOXOOYOOZOPPOPQOPROPSOPTOPUOPVOPWOPXOPYOPZOQPOQQOQROQSOQTOQUOQVOQWOQXOQYOQZORPORQORRORSORTORUORVORWORXORYORZOSPOSQOSROSSOSTOSUOSVOSWOSXOSYOSZOTPOTQOTROTSOTTOTUOTVOTWOTXOTYOTZOUPOUQOUROUSOUTOUUOUVOUWOUXOUYOUZOVPOVQOVROVSOVTOVUOVVOVWOVXOVYOVZOWPOWQOWROWSOWTOWUOWVOWWOWXOWYOWZOXPOXQOXROXSOXTOXUOXVOXWOXXOXYOXZOYPOYQOYROYSOYTOYUOYVOYWOYXOYYOYZOZPOZQOZROZSOZTOZUOZVOZWOZXOZYOZZPPPQPPRPPSPPTPPUPPVPPWPPXPPYPPZPQQPQRPQSPQTPQUPQVPQWPQXPQYPQZPRQPRRPRSPRTPRUPRVPRWPRXPRYPRZPSQPSRPSSPSTPSUPSVPSWPSXPSYPSZPTQPTRPTSPTTPTUPTVTABUABVABWABXABYABZACBACCACDACEACFACGACHACIACJACKACLACMACNACOACPACQACRACSACTACUACVACWACXACYACZADBADCADDADEADFADGADHADIADJADKADLADMADAAABAACAADAAEAAFAAGAAHAAIAAJAAKAALAAMAANAAOAAPAAQAARAASAATAAUAAVAAWAAXAAYAAZABBABCABDABEABFABGABHABIABJABKABLABMABNABOABPABQABRABSABHAFIAFJAFKAFLAFMAFNAFOAFPAFQAFRAFSAFTAFUAFVAFWAFXAFYAFZAGBAGCAGDAGEAGFAGGAGHAGIAGJAGKAGLAGMAGNAGOAGPAGQAGRAGSAGTAGUAGVAGWAGXAGYAGZAHNADOADPADQADRADSADTADUADVADWADXADYADZAEBAECAEDAEEAEFAEGAEHAEIAEJAEKAELAEMAENAEOAEPAEQAERAESAETAEUAEVAEWAEXAEYAEZAFBAFCAFDAFEAFFAFGAFUAIVAIWAIXAIYAIZAJBAJCAJDAJEAJFAJGAJHAJIAJJAJKAJLAJMAJNAJOAJPAJQAJRAJSAJTAJUAJVAJWAJXAJYAJZAKBAKCAKDAKEAKFAKGAKHAKIAKJAKKAKLAKMAKNAKBAHCAHDAHEAHFAHGAHHAHIAHJAHKAHLAHMAHNAHOAHPAHQAHRAHSAHTAHUAHVAHWAHXAHYAHZAIBAICAIDAIEAIFAIGAIHAIIAIJAIKAILAIMAINAIOAIPAIQAIRAISAITAIIAMJAMKAMLAMMAMNAMOAMPAMQAMRAMSAMTAMUAMVAMWAMXAMYAMZANBANCANDANEANFANGANHANIANJANKANLANMANNANOANPANQANRANSANTANUANVANWANXANYANZAOBAOOAKPAKQAKRAKSAKTAKUAKVAKWAKXAKYAKZALBALCALDALEALFALGALHALIALJALKALLALMALNALOALPALQALRALSALTALUALVALWALXALYALZAMBAMCAMDAMEAMFAMGAMHAMVAPWAPXAPYAPZAQBAQCAQDAQEAQFAQGAQHAQIAQJAQKAQLAQMAQNAQOAQPAQQAQRAQSAQTAQUAQVAQWAQXAQYAQZARBARCARDAREARFARGARHARIARJARKARLARMARNAROARCAODAOEAOFAOGAOHAOIAOJAOKAOLAOMAONAOOAOPAOQAORAOSAOTAOUAOVAOWAOXAOYAOZAPBAPCAPDAPEAPFAPGAPHAPIAPJAPKAPLAPMAPNAPOAPPAPQAPRAPSAPTAPUAPJATKATLATMATNATOATPATQATRATSATTATUATVATWATXATYATZAUBAUCAUDAUEAUFAUGAUHAUIAUJAUKAULAUMAUNAUOAUPAUQAURAUSAUTAUUAUVAUWAUXAUYAUZAVBAVCAVPARQARRARSARTARUARVARWARXARYARZASBASCASDASEASFASGASHASIASJASKASLASMASNASOASPASQASRASSASTASUASVASWASXASYASZATBATCATDATEATFATGATHATIATWAWXAWYAWZAXBAXCAXDAXEAXFAXGAXHAXIAXJAXKAXLAXMAXNAXOAXPAXQAXRAXSAXTAXUAXVAXWAXXAXYAXZAYBAYCAYDAYEAYFAYGAYHAYIAYJAYKAYLAYMAYNAYOAYPAYDAVEAVFAVGAVHAVIAVJAVKAVLAVMAVNAVOAVPAVQAVRAVSAVTAVUAVVAVWAVXAVYAVZAWBAWCAWDAWEAWFAWGAWHAWIAWJAWKAWLAWMAWNAWOAWPAWQAWRAWSAWTAWUAWVAWBLBBMBBNBBOBBPBBQBBRBBSBBTBBUBBVBBWBBXBBYBBZBCCBCDBCEBCFBCGBCHBCIBCJBCKBCLBCMBCNBCOBCPBCQBCRBCSBCTBCUBCVBCWBCXBCYBCZBDCBDDBDEBDFBDGBQAYRAYSAYTAYUAYVAYWAYXAYYAYZAZBAZCAZDAZEAZFAZGAZHAZIAZJAZKAZLAZMAZNAZOAZPAZQAZRAZSAZTAZUAZVAZWAZXAZYAZZBBBCBBDBBEBBFBBGBBHBBIBBJBBKBFDBFEBFFBFGBFHBFIBFJBFKBFLBFMBFNBFOBFPBFQBFRBFSBFTBFUBFVBFWBFXBFYBFZBGCBGDBGEBGFBGGBGHBGIBGJBGKBGLBGMBGNBGOBGPBGQBGRBGSBGTBGUBGVBGWBDHBDIBDJBDKBDLBDMBDNBDOBDPBDQBDRBDSBDTBDUBDVBDWBDXBDYBDZBECBEDBEEBEFBEGBEHBEIBEJBEKBELBEMBENBEOBEPBEQBERBESBETBEUBEVBEWBEXBEYBEZBFCBITBIUBIVBIWBIXBIYBIZBJCBJDBJEBJFBJGBJHBJIBJJBJKBJLBJMBJNBJOBJPBJQBJRBJSBJTBJUBJVBJWBJXBJYBJZBKCBKDBKEBKFBKGBKHBKIBKJBKKBKLBKMBKNBKOBGXBGYBGZBHCBHDBHEBHFBHGBHHBHIBHJBHKBHLBHMBHNBHOBHPBHQBHRBHSBHTBHUBHVBHWBHXBHYBHZBICBIDBIEBIFBIGBIHBIIBIJBIKBILBIMBINBIOBIPBIQBIRBISBMLBMMBMNBMOBMPBMQBMRBMSBMTBMUBMVBMWBMXBMYBMZBNCBNDBNEBNFBNGBNHBNIBNJBNKBNLBNMBNNBNOBNPBNQBNRBNSBNTBNUBNVBNWBNXBNYBNZBOCBODBOEBOFBOGBKPBKQBKRBKSBKTBKUBKVBKWBKXBKYBKZBLCBLDBLEBLFBLGBLHBLIBLJBLKBLLBLMBLNBLOBLPBLQBLRBLSBLTBLUBLVBLWBLXBLYBLZBMCBMDBMEBMFBMGBMHBMIBMJBMKBQDBQEBQFBQGBQHBQIBQJBQKBQLBQMBQNBQOBQPBQQBQRBQSBQTBQUBQVBQWBQXBQYBQZBRCBRDBREBRFBRGBRHBRIBRJBRKBRLBRMBRNBROBRPBRQBRRBRSBRTBRUBRVBRWBOHBOIBOJBOKBOLBOMBONBOOBOPBOQBORBOSBOTBOUBOVBOWBOXBOYBOZBPCBPDBPEBPFBPGBPHBPIBPJBPKBPLBPMBPNBPOBPPBPQBPRBPSBPTBPUBPVBPWBPXBPYBPZBQCBTTBTUBTVBTWBTXBTYBTZBUCBUDBUEBUFBUGBUHBUIBUJBUKBULBUMBUNBUOBUPBUQBURBUSBUTBUUBUVBUWBUXBUYBUZBVCBVDBVEBVFBVGBVHBVIBVJBVKBVLBVMBVNBVOBRXBRYBRZBSCBSDBSEBSFBSGBSHBSIBSJBSKBSLBSMBSNBSOBSPBSQBSRBSSBSTBSUBSVBSWBSXBSYBSZBTCBTDBTEBTFBTGBTHBTIBTJBTKBTLBTMBTNBTOBTPBTQBTRBTSBXLBXMBXNBXOBXPBXQBXRBXSBXTBXUBXVBXWBXXBXYBXZBYCBYDBYEBYFBYGBYHBYIBYJBYKBYLBYMBYNBYOBYPBYQBYRBYSBYTBYUBYVBYWBYXBYYBYZBZCBZDBZEBZFBZGBVPBVQBVRBVSBVTBVUBVVBVWBVXBVYBVZBWCBWDBWEBWFBWGBWHBWIBWJBWKBWLBWMBWNBWOBWPBWQBWRBWSBWTBWUBWVBWWBWXBWYBWZBXCBXDBXEBXFBXGBXHBXIBXJBXKBCDFCDGCDHCDICDJCDKCDLCDMCDNCDOCDPCDQCDRCDSCDTCDUCDVCDWCDXCDYCDZCEDCEECEFCEGCEHCEICEJCEKCELCEMCENCEOCEPCEQCERCESCETCEUCEVCEWCEXCEYCEZZHBZIBZJBZKBZLBZMBZNBZOBZPBZQBZRBZSBZTBZUBZVBZWBZXBZYBZZCCCDCCECCFCCGCCHCCICCJCCKCCLCCMCCNCCOCCPCCQCCRCCSCCTCCUCCVCCWCCXCCYCCZCDDCDECGYCGZCHDCHECHFCHGCHHCHICHJCHKCHLCHMCHNCHOCHPCHQCHRCHSCHTCHUCHVCHWCHXCHYCHZCIDCIECIFCIGCIHCIICIJCIKCILCIMCINCIOCIPCIQCIRCISCITCIUCIVCFDCFECFFCFGCFHCFICFJCFKCFLCFMCFNCFOCFPCFQCFRCFSCFTCFUCFVCFWCFXCFYCFZCGDCGECGFCGGCGHCGICGJCGKCGLCGMCGNCGOCGPCGQCGRCGSCGTCGUCGVCGWCGXCKUCKVCKWCKXCKYCKZCLDCLECLFCLGCLHCLICLJCLKCLLCLMCLNCLOCLPCLQCLRCLSCLTCLUCLVCLWCLXCLYCLZCMDCMECMFCMGCMHCMICMJCMKCMLCMMCMNCMOCMPCMQCMRCIWCIXCIYCIZCJDCJECJFCJGCJHCJICJJCJKCJLCJMCJNCJOCJPCJQCJRCJSCJTCJUCJVCJWCJXCJYCJZCKDCKECKFCKGCKHCKICKJCKKCKLCKMCKNCKOCKPCKQCKRCKSCKTCOQCORCOSCOTCOUCOVCOWCOXCOYCOZCPDCPECPFCPGCPHCPICPJCPKCPLCPMCPNCPOCPPCPQCPRCPSCPTCPUCPVCPWCPXCPYCPZCQDCQECQFCQGCQHCQICQJCQKCQLCQMCQNCMSCMTCMUCMVCMWCMXCMYCMZCNDCNECNFCNGCNHCNICNJCNKCNLCNMCNNCNOCNPCNQCNRCNSCNTCNUCNVCNWCNXCNYCNZCODCOECOFCOGCOHCOICOJCOKCOLCOMCONCOOCOPCSMCSNCSOCSPCSQCSRCSSCSTCSUCSVCSWCSXCSYCSZCTDCTECTFCTGCTHCTICTJCTKCTLCTMCTNCTOCTPCTQCTRCTSCTTCTUCTVCTWCTXCTYCTZCUDCUECUFCUGCUHCUICUJCQOCQPCQQCQRCQSCQTCQUCQVCQWCQXCQYCQZCRDCRECRFCRGCRHCRICRJCRKCRLCRMCRNCROCRPCRQCRRCRSCRTCRUCRVCRWCRXCRYCRZCSDCSECSFCSGCSHCSICSJCSKCSLCWICWJCWKCWLCWMCWNCWOCWPCWQCWRCWSCWTCWUCWVCWWCWXCWYCWZCXDCXECXFCXGCXHCXICXJCXKCXLCXMCXNCXOCXPCXQCXRCXSCXTCXUCXVCXWCXXCXYCXZCYDCYECYFCUKCULCUMCUNCUOCUPCUQCURCUSCUTCUUCUVCUWCUXCUYCUZCVDCVECVFCVGCVHCVICVJCVKCVLCVMCVNCVOCVPCVQCVRCVSCVTCVUCVVCVWCVXCVYCVZCWDCWECWFCWGCWHEDDFDDGDDHDDIDDJDDKDDLDDMDDNDDODDPDDQDDRDDSDDTDDUDDVDDWDDXDDYDDZDEEDEFDEGDEHDEIDEJDEKDELDEMDENDEODEPDEQDERDESDETDEUDEVDEWDEXDEYDEZDFCYGCYHCYICYJCYKCYLCYMCYNCYOCYPCYQCYRCYSCYTCYUCYVCYWCYXCYYCYZCZDCZECZFCZGCZHCZICZJCZKCZLCZMCZNCZOCZPCZQCZRCZSCZTCZUCZVCZWCZXCZYCZZDDDEDHFDHGDHHDHIDHJDHKDHLDHMDHNDHODHPDHQDHRDHSDHTDHUDHVDHWDHXDHYDHZDIEDIFDIGDIHDIIDIJDIKDILDIMDINDIODIPDIQDIRDISDITDIUDIVDIWDIXDIYDIZDJEDFFDFGDFHDFIDFJDFKDFLDFMDFNDFODFPDFQDFRDFSDFTDFUDFVDFWDFXDFYDFZDGEDGFDGGDGHDGIDGJDGKDGLDGMDGNDGODGPDGQDGRDGSDGTDGUDGVDGWDGXDGYDGZDHEDLFDLGDLHDLIDLJDLKDLLDLMDLNDLODLPDLQDLRDLSDLTDLUDLVDLWDLXDLYDLZDMEDMFDMGDMHDMIDMJDMKDMLDMMDMNDMODMPDMQDMRDMSDMTDMUDMVDMWDMXDMYDMZDNEDJFDJGDJHDJIDJJDJKDJLDJMDJNDJODJPDJQDJRDJSDJTDJUDJVDJWDJXDJYDJZDKEDKFDKGDKHDKIDKJDKKDKLDKMDKNDKODKPDKQDKRDKSDKTDKUDKVDKWDKXDKYDKZDLEDPFDPGDPHDPIDPJDPKDPLDPMDPNDPODPPDPQDPRDPSDPTDPUDPVDPWDPXDPYDPZDQEDQFDQGDQHDQIDQJDQKDQLDQMDQNDQODQPDQQDQRDQSDQTDQUDQVDQWDQXDQYDQZDREDNFDNGDNHDNIDNJDNKDNLDNMDNNDNODNPDNQDNRDNSDNTDNUDNVDNWDNXDNYDNZDOEDOFDOGDOHDOIDOJDOKDOLDOMDONDOODOPDOQDORDOSDOTDOUDOVDOWDOXDOYDOZDPEDTFDTGDTHDTIDTJDTKDTLDTMDTNDTODTPDTQDTRDTSDTTDTUDTVDTWDTXDTYDTZDUEDUFDUGDUHDUIDUJDUKDULDUMDUNDUODUPDUQDURDUSDUTDUUDUVDUWDUXDUYDUZDVEDRFDRGDRHDRIDRJDRKDRLDRMDRNDRODRPDRQDRRDRSDRTDRUDRVDRWDRXDRYDRZDSEDSFDSGDSHDSIDSJDSKDSLDSMDSNDSODSPDSQDSRDSSDSTDSUDSVDSWDSXDSYDSZDTEDXFDXGDXHDXIDXJDXKDXLDXMDXNDXODXPDXQDXRDXSDXTDXUDXVDXWDXXDXYDXZDYEDYFDYGDYHDYIDYJDYKDYLDYMDYNDYODYPDYQDYRDYSDYTDYUDYVDYWDYXDYYDYZDZEDVFDVGDVHDVIDVJDVKDVLDVMDVNDVODVPDVQDVRDVSDVTDVUDVVDVWDVXDVYDVZDWEDWFDWGDWHDWIDWJDWKDWLDWMDWNDWODWPDWQDWRDWSDWTDWUDWVDWWDWXDWYDWZDXFGEFHEFIEFJEFKEFLEFMEFNEFOEFPEFQEFREFSEFTEFUEFVEFWEFXEFYEFZEGFEGGEGHEGIEGJEGKEGLEGMEGNEGOEGPEGQEGREGSEGTEGUEGVEGWEGXEGYEGZEHFEHGEHHEEDZFDZGDZHDZIDZJDZKDZLDZMDZNDZODZPDZQDZRDZSDZTDZUDZVDZWDZXDZYDZZEEEFEEGEEHEEIEEJEEKEELEEMEENEEOEEPEEQEEREESEETEEUEEVEEWEEXEEYEEZEFFEJKEJLEJMEJNEJOEJPEJQEJREJSEJTEJUEJVEJWEJXEJYEJZEKFEKGEKHEKIEKJEKKEKLEKMEKNEKOEKPEKQEKREKSEKTEKUEKVEKWEKXEKYEKZELFELGELHELIELJELKELLEHIEHJEHKEHLEHMEHNEHOEHPEHQEHREHSEHTEHUEHVEHWEHXEHYEHZEIFEIGEIHEIIEIJEIKEILEIMEINEIOEIPEIQEIREISEITEIUEIVEIWEIXEIYEIZEJFEJGEJHEJIEJJENOENPENQENRENSENTENUENVENWENXENYENZEOFEOGEOHEOIEOJEOKEOLEOMEONEOOEOPEOQEOREOSEOTEOUEOVEOWEOXEOYEOZEPFEPGEPHEPIEPJEPKEPLEPMEPNEPOEPPELMELNELOELPELQELRELSELTELUELVELWELXELYELZEMFEMGEMHEMIEMJEMKEMLEMMEMNEMOEMPEMQEMREMSEMTEMUEMVEMWEMXEMYEMZENFENGENHENIENJENKENLENMENNERSERTERUERVERWERXERYERZESFESGESHESIESJESKESLESMESNESOESPESQESRESSESTESUESVESWESXESYESZETFETGETHETIETJETKETLETMETNETOETPETQETRETSETTEPQEPREPSEPTEPUEPVEPWEPXEPYEPZEQFEQGEQHEQIEQJEQKEQLEQMEQNEQOEQPEQQEQREQSEQTEQUEQVEQWEQXEQYEQZERFERGERHERIERJERKERLERMERNEROERPERQERREVWEVXEVYEVZEWFEWGEWHEWIEWJEWKEWLEWMEWNEWOEWPEWQEWREWSEWTEWUEWVEWWEWXEWYEWZEXFEXGEXHEXIEXJEXKEXLEXMEXNEXOEXPEXQEXREXSEXTEXUEXVEXWEXXETUETVETWETXETYETZEUFEUGEUHEUIEUJEUKEULEUMEUNEUOEUPEUQEUREUSEUTEUUEUVEUWEUXEUYEUZEVFEVGEVHEVIEVJEVKEVLEVMEVNEVOEVPEVQEVREVSEVTEVUEVVEFFGFFHFFIFFJFFKFFLFFMFFNFFOFFPFFQFFRFFSFFTFFUFFVFFWFFXFFYFFZFGGFGHFGIFGJFGKFGLFGMFGNFGOFGPFGQFGRFGSFGTFGUFGVFGWFGXFGYFGZFHGFHHFHIFHJXYEXZEYFEYGEYHEYIEYJEYKEYLEYMEYNEYOEYPEYQEYREYSEYTEYUEYVEYWEYXEYYEYZEZFEZGEZHEZIEZJEZKEZLEZMEZNEZOEZPEZQEZREZSEZTEZUEZVEZWEZXEZYEZZFFJOFJPFJQFJRFJSFJTFJUFJVFJWFJXFJYFJZFKGFKHFKIFKJFKKFKLFKMFKNFKOFKPFKQFKRFKSFKTFKUFKVFKWFKXFKYFKZFLGFLHFLIFLJFLKFLLFLMFLNFLOFLPFLQFLRFHKFHLFHMFHNFHOFHPFHQFHRFHSFHTFHUFHVFHWFHXFHYFHZFIGFIHFIIFIJFIKFILFIMFINFIOFIPFIQFIRFISFITFIUFIVFIWFIXFIYFIZFJGFJHFJIFJJFJKFJLFJMFJNFNWFNXFNYFNZFOGFOHFOIFOJFOKFOLFOMFONFOOFOPFOQFORFOSFOTFOUFOVFOWFOXFOYFOZFPGFPHFPIFPJFPKFPLFPMFPNFPOFPPFPQFPRFPSFPTFPUFPVFPWFPXFPYFPZFLSFLTFLUFLVFLWFLXFLYFLZFMGFMHFMIFMJFMKFMLFMMFMNFMOFMPFMQFMRFMSFMTFMUFMVFMWFMXFMYFMZFNGFNHFNIFNJFNKFNLFNMFNNFNOFNPFNQFNRFNSFNTFNUFNVFSKFSLFSMFSNFSOFSPFSQFSRFSSFSTFSUFSVFSWFSXFSYFSZFTGFTHFTIFTJFTKFTLFTMFTNFTOFTPFTQFTRFTSFTTFTUFTVFTWFTXFTYFTZFUGFUHFUIFUJFUKFULFUMFUNFQGFQHFQIFQJFQKFQLFQMFQNFQOFQPFQQFQRFQSFQTFQUFQVFQWFQXFQYFQZFRGFRHFRIFRJFRKFRLFRMFRNFROFRPFRQFRRFRSFRTFRUFRVFRWFRXFRYFRZFSGFSHFSIFSJFWSFWTFWUFWVFWWFWXFWYFWZFXGFXHFXIFXJFXKFXLFXMFXNFXOFXPFXQFXRFXSFXTFXUFXVFXWFXXFXYFXZFYGFYHFYIFYJFYKFYLFYMFYNFYOFYPFYQFYRFYSFYTFYUFYVFUOFUPFUQFURFUSFUTFUUFUVFUWFUXFUYFUZFVGFVHFVIFVJFVKFVLFVMFVNFVOFVPFVQFVRFVSFVTFVUFVVFVWFVXFVYFVZFWGFWHFWIFWJFWKFWLFWMFWNFWOFWPFWQFWRHGHIGHJGHKGHLGHMGHNGHOGHPGHQGHRGHSGHTGHUGHVGHWGHXGHYGHZGIHGIIGIJGIKGILGIMGINGIOGIPGIQGIRGISGITGIUGIVGIWGIXGIYGIZGJHGJIGJJGJKGJLGJMGJFYWFYXFYYFYZFZGFZHFZIFZJFZKFZLFZMFZNFZOFZPFZQFZRFZSFZTFZUFZVFZWFZXFZYFZZGGGHGGIGGJGGKGGLGGMGGNGGOGGPGGQGGRGGSGGTGGUGGVGGWGGXGGYGGZGHTGLUGLVGLWGLXGLYGLZGMHGMIGMJGMKGMLGMMGMNGMOGMPGMQGMRGMSGMTGMUGMVGMWGMXGMYGMZGNHGNIGNJGNKGNLGNMGNNGNOGNPGNQGNRGNSGNTGNUGNVGNWGNXGNYGNNGJOGJPGJQGJRGJSGJTGJUGJVGJWGJXGJYGJZGKHGKIGKJGKKGKLGKMGKNGKOGKPGKQGKRGKSGKTGKUGKVGKWGKXGKYGKZGLHGLIGLJGLKGLLGLMGLNGLOGLPGLQGLRGLSGLMGQNGQOGQPGQQGQRGQSGQTGQUGQVGQWGQXGQYGQZGRHGRIGRJGRKGRLGRMGRNGROGRPGRQGRRGRSGRTGRUGRVGRWGRXGRYGRZGSHGSIGSJGSKGSLGSMGSNGSOGSPGSQGSRGSZGOHGOIGOJGOKGOLGOMGONGOOGOPGOQGORGOSGOTGOUGOVGOWGOXGOYGOZGPHGPIGPJGPKGPLGPMGPNGPOGPPGPQGPRGPSGPTGPUGPVGPWGPXGPYGPZGQHGQIGQJGQKGQLGQYGUZGVHGVIGVJGVKGVLGVMGVNGVOGVPGVQGVRGVSGVTGVUGVVGVWGVXGVYGVZGWHGWIGWJGWKGWLGWMGWNGWOGWPGWQGWRGWSGWTGWUGWVGWWGWXGWYGWZGXHGXIGXJGXKGXSGSTGSUGSVGSWGSXGSYGSZGTHGTIGTJGTKGTLGTMGTNGTOGTPGTQGTRGTSGTTGTUGTVGTWGTXGTYGTZGUHGUIGUJGUKGULGUMGUNGUOGUPGUQGURGUSGUTGUUGUVGUWGUXGURGZSGZTGZUGZVGZWGZXGZYGZZHHHIHHJHHKHHLHHMHHNHHOHHPHHQHHRHHSHHTHHUHHVHHWHHXHHYHHZHIIHIJHIKHILHIMHINHIOHIPHIQHIRHISHITHIUHIVHIWHIXHIYHLGXMGXNGXOGXPGXQGXRGXSGXTGXUGXVGXWGXXGXYGXZGYHGYIGYJGYKGYLGYMGYNGYOGYPGYQGYRGYSGYTGYUGYVGYWGYXGYYGYZGZHGZIGZJGZKGZLGZMGZNGZOGZPGZQGZLPHLQHLRHLSHLTHLUHLVHLWHLXHLYHLZHMIHMJHMKHMLHMMHMNHMOHMPHMQHMRHMSHMTHMUHMVHMWHMXHMYHMZHNIHNJHNKHNLHNMHNNHNOHNPHNQHNRHNSHNTHNUHNVHNWHIZHJIHJJHJKHJLHJMHJNHJOHJPHJQHJRHJSHJTHJUHJVHJWHJXHJYHJZHKIHKJHKKHKLHKMHKNHKOHKPHKQHKRHKSHKTHKUHKVHKWHKXHKYHKZHLIHLJHLKHLLHLMHLNHLOHQNHQOHQPHQQHQRHQSHQTHQUHQVHQWHQXHQYHQZHRIHRJHRKHRLHRMHRNHROHRPHRQHRRHRSHRTHRUHRVHRWHRXHRYHRZHSIHSJHSKHSLHSMHSNHSOHSPHSQHSRHSSHSTHSUHNXHNYHNZHOIHOJHOKHOLHOMHONHOOHOPHOQHORHOSHOTHOUHOVHOWHOXHOYHOZHPIHPJHPKHPLHPMHPNHPOHPPHPQHPRHPSHPTHPUHPVHPWHPXHPYHPZHQIHQJHQKHQLHQMHVLHVMHVNHVOHVPHVQHVRHVSHVTHVUHVVHVWHVXHVYHVZHWIHWJHWKHWLHWMHWNHWOHWPHWQHWRHWSHWTHWUHWVHWWHWXHWYHWZHXIHXJHXKHXLHXMHXNHXOHXPHXQHXRHXSHSVHSWHSXHSYHSZHTIHTJHTKHTLHTMHTNHTOHTPHTQHTRHTSHTTHTUHTVHTWHTXHTYHTZHUIHUJHUKHULHUMHUNHUOHUPHUQHURHUSHUTHUUHUVHUWHUXHUYHUZHVIHVJHVKHIIKIILIIMIINIIOIIPIIQIIRIISIITIIUIIVIIWIIXIIYIIZIJJIJKIJLIJMIJNIJOIJPIJQIJRIJSIJTIJUIJVIJWIJXIJYIJZIKJIKKIKLIKMIKNIKOIKPIKQIKRIKSIKTXTHXUHXVHXWHXXHXYHXZHYIHYJHYKHYLHYMHYNHYOHYPHYQHYRHYSHYTHYUHYVHYWHYXHYYHYZHZIHZJHZKHZLHZMHZNHZOHZPHZQHZRHZSHZTHZUHZVHZWHZXHZYHZZIIIJINNINOINPINQINRINSINTINUINVINWINXINYINZIOJIOKIOLIOMIONIOOIOPIOQIORIOSIOTIOUIOVIOWIOXIOYIOZIPJIPKIPLIPMIPNIPOIPPIPQIPRIPSIPTIPUIPVIPWIKUIKVIKWIKXIKYIKZILJILKILLILMILNILOILPILQILRILSILTILUILVILWILXILYILZIMJIMKIMLIMMIMNIMOIMPIMQIMRIMSIMTIMUIMVIMWIMXIMYIMZINJINKINLINMISQISRISSISTISUISVISWISXISYISZITJITKITLITMITNITOITPITQITRITSITTITUITVITWITXITYITZIUJIUKIULIUMIUNIUOIUPIUQIURIUSIUTIUUIUVIUWIUXIUYIUZIPXIPYIPZIQJIQKIQLIQMIQNIQOIQPIQQIQRIQSIQTIQUIQVIQWIQXIQYIQZIRJIRKIRLIRMIRNIROIRPIRQIRRIRSIRTIRUIRVIRWIRXIRYIRZISJISKISLISMISNISOISPIXTIXUIXVIXWIXXIXYIXZIYJIYKIYLIYMIYNIYOIYPIYQIYRIYSIYTIYUIYVIYWIYXIYYIYZIZJIZKIZLIZMIZNIZOIZPIZQIZRIZSIZTIZUIZVIZWIZXIZYIZZJJJKJJLJJIVJIVKIVLIVMIVNIVOIVPIVQIVRIVSIVTIVUIVVIVWIVXIVYIVZIWJIWKIWLIWMIWNIWOIWPIWQIWRIWSIWTIWUIWVIWWIWXIWYIWZIXJIXKIXLIXMIXNIXOIXPIXQIXRIXSYJLZJMKJMLJMMJMNJMOJMPJMQJMRJMSJMTJMUJMVJMWJMXJMYJMZJNKJNLJNMJNNJNOJNPJNQJNRJNSJNTJNUJNVJNWJNXJNYJNZJOKJOLJOMJONJOOJOPJOQJORJOSJOTJOMJJNJJOJJPJJQJJRJJSJJTJJUJJVJJWJJXJJYJJZJKKJKLJKMJKNJKOJKPJKQJKRJKSJKTJKUJKVJKWJKXJKYJKZJLKJLLJLMJLNJLOJLPJLQJLRJLSJLTJLUJLVJLWJLXJLQJRRJRSJRTJRUJRVJRWJRXJRYJRZJSKJSLJSMJSNJSOJSPJSQJSRJSSJSTJSUJSVJSWJSXJSYJSZJTKJTLJTMJTNJTOJTPJTQJTRJTSJTTJTUJTVJTWJTXJTYJTZJUKJULJUUJOVJOWJOXJOYJOZJPKJPLJPMJPNJPOJPPJPQJPRJPSJPTJPUJPVJPWJPXJPYJPZJQKJQLJQMJQNJQOJQPJQQJQRJQSJQTJQUJQVJQWJQXJQYJQZJRKJRLJRMJRNJROJRPJRYJWZJXKJXLJXMJXNJXOJXPJXQJXRJXSJXTJXUJXVJXWJXXJXYJXZJYKJYLJYMJYNJYOJYPJYQJYRJYSJYTJYUJYVJYWJYXJYYJYZJZKJZLJZMJZNJZOJZPJZQJZRJZSJZTJZMJUNJUOJUPJUQJURJUSJUTJUUJUVJUWJUXJUYJUZJVKJVLJVMJVNJVOJVPJVQJVRJVSJVTJVUJVVJVWJVXJVYJVZJWKJWLJWMJWNJWOJWPJWQJWRJWSJWTJWUJWVJWWJWXJWMTKMUKMVKMWKMXKMYKMZKNLKNMKNNKNOKNPKNQKNRKNSKNTKNUKNVKNWKNXKNYKNZKOLKOMKONKOOKOPKOQKORKOSKOTKOUKOVKOWKOXKOYKOZKPLKPMKPNKPOKPPKPQKPRKUJZVJZWJZXJZYJZZKKKLKKMKKNKKOKKPKKQKKRKKSKKTKKUKKVKKWKKXKKYKKZKLLKLMKLNKLOKLPKLQKLRKLSKLTKLUKLVKLWKLXKLYKLZKMLKMMKMNKMOKMPKMQKMRKMSKSRKSSKSTKSUKSVKSWKSXKSYKSZKTLKTMKTNKTOKTPKTQKTRKTSKTTKTUKTVKTWKTXKTYKTZKULKUMKUNKUOKUPKUQKURKUSKUTKUUKUVKUWKUXKUYKUZKVLKVMKVNKVOKVPKPSKPTKPUKPVKPWKPXKPYKPZKQLKQMKQNKQOKQPKQQKQRKQSKQTKQUKQVKQWKQXKQYKQZKRLKRMKRNKROKRPKRQKRRKRSKRTKRUKRVKRWKRXKRYKRZKSLKSMKSNKSOKSPKSQKYPKYQKYRKYSKYTKYUKYVKYWKYXKYYKYZKZLKZMKZNKZOKZPKZQKZRKZSKZTKZUKZVKZWKZXKZYKZZLLLMLLNLLOLLPLLQLLRLLSLLTLLULLVLLWLLXLLYLLZLMMLMNLMOLMPVQKVRKVSKVTKVUKVVKVWKVXKVYKVZKWLKWMKWNKWOKWPKWQKWRKWSKWTKWUKWVKWWKWXKWYKWZKXLKXMKXNKXOKXPKXQKXRKXSKXTKXUKXVKXWKXXKXYKXZKYLKYMKYNKYOKLPSLPTLPULPVLPWLPXLPYLPZLQMLQNLQOLQPLQQLQRLQSLQTLQULQVLQWLQXLQYLQZLRMLRNLROLRPLRQLRRLRSLRTLRULRVLRWLRXLRYLRZLSMLSNLSOLSPLSQLSRLSSLSTLMQLMRLMSLMTLMULMVLMWLMXLMYLMZLNMLNNLNOLNPLNQLNRLNSLNTLNULNVLNWLNXLNYLNZLOMLONLOOLOPLOQLORLOSLOTLOULOVLOWLOXLOYLOZLPMLPNLPOLPPLPQLPRLVWLVXLVYLVZLWMLWNLWOLWPLWQLWRLWSLWTLWULWVLWWLWXLWYLWZLXMLXNLXOLXPLXQLXRLXSLXTLXULXVLXWLXXLXYLXZLYMLYNLYOLYPLYQLYRLYSLYTLYULYVLYWLYXLSULSVLSWLSXLSYLSZLTMLTNLTOLTPLTQLTRLTSLTTLTULTVLTWLTXLTYLTZLUMLUNLUOLUPLUQLURLUSLUTLUULUVLUWLUXLUYLUZLVMLVNLVOLVPLVQLVRLVSLVTLVULVVOMOPMOQMORMOSMOTMOUMOVMOWMOXMOYMOZMPNMPOMPPMPQMPRMPSMPTMPUMPVMPWMPXMPYMPZMQNMQOMQPMQQMQRMQSMQTMQUMQVMQWMQXMQYMQZMRNMROMRPMRQMRRMRSMRLYYLYZLZMLZNLZOLZPLZQLZRLZSLZTLZULZVLZWLZXLZYLZZMMMNMMOMMPMMQMMRMMSMMTMMUMMVMMWMMXMMYMMZMNNMNOMNPMNQMNRMNSMNTMNUMNVMNWMNXMNYMNZMONMOYMUZMVNMVOMVPMVQMVRMVSMVTMVUMVVMVWMVXMVYMVZMWNMWOMWPMWQMWRMWSMWTMWUMWVMWWMWXMWYMWZMXNMXOMXPMXQMXRMXSMXTMXUMXVMXWMXXMXYMXZMYNMYOMYPMYTMRUMRVMRWMRXMRYMRZMSNMSOMSPMSQMSRMSSMSTMSUMSVMSWMSXMSYMSZMTNMTOMTPMTQMTRMTSMTTMTUMTVMTWMTXMTYMTZMUNMUOMUPMUQMURMUSMUTMUUMUVMUWMUXMUOXNOYNOZNPONPPNPQNPRNPSNPTNPUNPVNPWNPXNPYNPZNQONQPNQQNQRNQSNQTNQUNQVNQWNQXNQYNQZNRONRPNRQNRRNRSNRTNRUNRVNRWNRXNRYNRZNSONSPNSQNSRNSSNQMYRMYSMYTMYUMYVMYWMYXMYYMYZMZNMZOMZPMZQMZRMZSMZTMZUMZVMZWMZXMZYMZZNNNONNPNNQNNRNNSNNTNNUNNVNNWNNXNNYNNZNOONOPNOQNORNOSNOTNOUNOVNOWNWPNWQNWRNWSNWTNWUNWVNWWNWXNWYNWZNXONXPNXQNXRNXSNXTNXUNXVNXWNXXNXYNXZNYONYPNYQNYRNYSNYTNYUNYVNYWNYXNYYNYZNZONZPNZQNZRNZSNZTNZUNZVNZWNSTNSUNSVNSWNSXNSYNSZNTONTPNTQNTRNTSNTTNTUNTVNTWNTXNTYNTZNUONUPNUQNURNUSNUTNUUNUVNUWNUXNUYNUZNVONVPNVQNVRNVSNVTNVUNVVNVWNVXNVYNVZNWONORXORYORZOSPOSQOSROSSOSTOSUOSVOSWOSXOSYOSZOTPOTQOTROTSOTTOTUOTVOTWOTXOTYOTZOUPOUQOUROUSOUTOUUOUVOUWOUXOUYOUZOVPOVQOVROVSOVTOVUOVVOVWZXNZYNZZOOOPOOQOOROOSOOTOOUOOVOOWOOXOOYOOZOPPOPQOPROPSOPTOPUOPVOPWOPXOPYOPZOQPOQQOQROQSOQTOQUOQVOQWOQXOQYOQZORPORQORRORSORTORUORVORWOZXOZYOZZPPPQPPRPPSPPTPPUPPVPPWPPXPPYPPZPQQPQRPQSPQTPQUPQVPQWPQXPQYPQZPRQPRRPRSPRTPRUPRVPRWPRXPRYPRZPSQPSRPSSPSTPSUPSVPSWPSXPSYPSZPTOVXOVYOVZOWPOWQOWROWSOWTOWUOWVOWWOWXOWYOWZOXPOXQOXROXSOXTOXUOXVOXWOXXOXYOXZOYPOYQOYROYSOYTOYUOYVOYWOYXOYYOYZOZPOZQOZROZSOZTOZUOZVOZWQPTRPTSPTTPTUPTV \ No newline at end of file
diff --git a/src/zlib-ng/test/GH-979/pigz-2.6.tar.gz b/src/zlib-ng/test/GH-979/pigz-2.6.tar.gz
new file mode 100644
index 0000000..0d76ef8
--- /dev/null
+++ b/src/zlib-ng/test/GH-979/pigz-2.6.tar.gz
Binary files differ
diff --git a/src/zlib-ng/test/Makefile.in b/src/zlib-ng/test/Makefile.in
index 97b8be7..4cd1399 100644
--- a/src/zlib-ng/test/Makefile.in
+++ b/src/zlib-ng/test/Makefile.in
@@ -9,13 +9,11 @@ SRCDIR=
SRCTOP=
LIBNAME=
TEST_LDFLAGS=-L.. ../$(LIBNAME).a
-WITH_FUZZERS=
-COMPATTESTS =
QEMU_RUN=
QEMU_VER:=$(shell command -v $(QEMU_RUN) --version 2> /dev/null)
-all: oldtests cvetests $(COMPATTESTS) fuzzer ghtests
+all: oldtests ghtests
oldtests: #set by ../configure
check_cross_dep:
@@ -27,28 +25,10 @@ endif
ALL_SRC_FILES := $(wildcard ../*)
-# Only check the fuzzer when it is a stand-alone executable.
-ifneq (,$(LIB_FUZZING_ENGINE))
-fuzzer:
-else
- ifeq (0,$(WITH_FUZZERS))
-fuzzer:
- else
-fuzzer:
- @${QEMU_RUN} ../checksum_fuzzer$(EXE) $(ALL_SRC_FILES) && \
- ${QEMU_RUN} ../compress_fuzzer$(EXE) $(ALL_SRC_FILES) && \
- ${QEMU_RUN} ../example_small_fuzzer$(EXE) $(ALL_SRC_FILES) && \
- ${QEMU_RUN} ../example_large_fuzzer$(EXE) $(ALL_SRC_FILES) && \
- ${QEMU_RUN} ../example_flush_fuzzer$(EXE) $(ALL_SRC_FILES) && \
- ${QEMU_RUN} ../example_dict_fuzzer$(EXE) $(ALL_SRC_FILES) && \
- ${QEMU_RUN} ../minigzip_fuzzer$(EXE) $(ALL_SRC_FILES)
- endif
-endif
-
teststatic: check_cross_dep
@TMPST=tmpst_$$$$; \
HELLOST=tmphellost_$$$$; \
- if echo hello world | ${QEMU_RUN} ../minigzip$(EXE) > $$HELLOST && ${QEMU_RUN} ../minigzip$(EXE) -d < $$HELLOST && ${QEMU_RUN} ../example$(EXE) $$TMPST && ${QEMU_RUN} ../adler32_test$(EXE); then \
+ if echo hello world | ${QEMU_RUN} ../minigzip$(EXE) > $$HELLOST && ${QEMU_RUN} ../minigzip$(EXE) -d < $$HELLOST && ${QEMU_RUN} ../example$(EXE) $$TMPST; then \
echo ' *** zlib test OK ***'; \
else \
echo ' *** zlib test FAILED ***'; exit 1; \
@@ -62,36 +42,15 @@ testshared: check_cross_dep
SHLIB_PATH=`pwd`/..:$(SHLIB_PATH) ; export SHLIB_PATH; \
TMPSH=tmpsh_$$$$; \
HELLOSH=tmphellosh_$$$$; \
- if echo hello world | ${QEMU_RUN} ../minigzipsh$(EXE) > $$HELLOSH && ${QEMU_RUN} ../minigzipsh$(EXE) -d < $$HELLOSH && ${QEMU_RUN} ../examplesh$(EXE) $$TMPSH && ${QEMU_RUN} ../adler32_testsh$(EXE); then \
+ if echo hello world | ${QEMU_RUN} ../minigzipsh$(EXE) > $$HELLOSH && ${QEMU_RUN} ../minigzipsh$(EXE) -d < $$HELLOSH && ${QEMU_RUN} ../examplesh$(EXE) $$TMPSH; then \
echo ' *** zlib shared test OK ***'; \
else \
echo ' *** zlib shared test FAILED ***'; exit 1; \
fi; \
rm -f $$TMPSH $$HELLOSH
-cvetests: testCVEinputs
-
-# Tests requiring zlib-ng to be built with --zlib-compat
-compattests: testCVE-2003-0107
-
-testCVEinputs: check_cross_dep
- @EXE=$(EXE) QEMU_RUN="${QEMU_RUN}" $(SRCDIR)/testCVEinputs.sh
-
-testCVE-2003-0107: CVE-2003-0107$(EXE) check_cross_dep
- @if ${QEMU_RUN} ./CVE-2003-0107$(EXE); then \
- echo ' *** zlib not vulnerable to CVE-2003-0107 ***'; \
- else \
- echo ' *** zlib VULNERABLE to CVE-2003-0107 ***'; exit 1; \
- fi
-
-CVE-2003-0107.o: $(SRCDIR)/CVE-2003-0107.c
- $(CC) $(CFLAGS) -I.. -I$(SRCTOP) -c -o $@ $(SRCDIR)/CVE-2003-0107.c
-
-CVE-2003-0107$(EXE): CVE-2003-0107.o
- $(CC) $(CFLAGS) -o $@ CVE-2003-0107.o $(TEST_LDFLAGS)
-
.PHONY: ghtests
-ghtests: testGH-361 testGH-364 testGH-751
+ghtests: testGH-361 testGH-364 testGH-751 testGH-1235
.PHONY: testGH-361
testGH-361:
@@ -108,9 +67,16 @@ testGH-364: switchlevels$(EXE)
testGH-751:
$(QEMU_RUN) ../minigzip$(EXE) <$(SRCDIR)/GH-751/test.txt | $(QEMU_RUN) ../minigzip$(EXE) -d >/dev/null
+gh1235$(EXE): $(SRCDIR)/gh1235.c
+ $(CC) $(CFLAGS) -I.. -I$(SRCTOP) -o $@ $< $(TEST_LDFLAGS)
+
+.PHONY: testGH-1235
+testGH-1235: gh1235$(EXE)
+ $(QEMU_RUN) ./gh1235$(EXE)
+
clean:
rm -f *.o *.gcda *.gcno *.gcov
- rm -f CVE-2003-0107$(EXE) switchlevels$(EXE)
+ rm -f switchlevels$(EXE) gh1235$(EXE)
distclean:
rm -f Makefile
diff --git a/src/zlib-ng/test/README.md b/src/zlib-ng/test/README.md
index 247d5ba..d844ba5 100644
--- a/src/zlib-ng/test/README.md
+++ b/src/zlib-ng/test/README.md
@@ -3,11 +3,12 @@ Contents
|Name|Description|
|-|-|
-|[CVE-2003-0107.c](https://nvd.nist.gov/vuln/detail/CVE-2003-0107)|Buffer overflow in the gzprintf function, requires ZLIB_COMPAT|
+|[CVE-2003-0107](https://nvd.nist.gov/vuln/detail/CVE-2003-0107)|Buffer overflow in the gzprintf function, requires ZLIB_COMPAT|
|[CVE-2002-0059](https://nvd.nist.gov/vuln/detail/CVE-2002-0059)|inflateEnd to release memory more than once|
|[CVE-2004-0797](https://nvd.nist.gov/vuln/detail/CVE-2004-0797)|Error handling in inflate and inflateBack causes crash|
|[CVE-2005-1849](https://nvd.nist.gov/vuln/detail/CVE-2005-1849)|inftrees.h bug causes crash|
-|[CVE-2005-2096](https://nvd.nist.gov/vuln/detail/CVE-2005-2096)|Buffer overflow when incomplete code description
+|[CVE-2005-2096](https://nvd.nist.gov/vuln/detail/CVE-2005-2096)|Buffer overflow when incomplete code description|
+|[CVE-2018-25032](https://nvd.nist.gov/vuln/detail/CVE-2018-25032)|Memory corruption when compressing if the input has many distant matches.|
|[GH-361](https://github.com/zlib-ng/zlib-ng/issues/361)|Test case for overlapping matches|
|[GH-364](https://github.com/zlib-ng/zlib-ng/issues/364)|Test case for switching compression levels|
|[GH-382](https://github.com/zlib-ng/zlib-ng/issues/382)|Test case for deflateEnd returning -3 in deflate quick|
@@ -26,11 +27,11 @@ Some of the files in _test_ are licensed differently:
“Combinatorial Modeling of Chromatin Features Quantitatively Predicts DNA
Replication Timing in _Drosophila_” by Federico Comoglio and Renato Paro,
which is licensed under the CC-BY license. See
- http://www.ploscompbiol.org/static/license for more information.
+ https://www.ploscompbiol.org/static/license for more information.
- - test/data/lcet10.txt is from Project Gutenberg. It does not have expired
+ - test/data/lcet10.txt is from Project Gutenberg. It does not have expired
copyright, but is still in the public domain according to the license information.
- (http://www.gutenberg.org/ebooks/53).
+ (https://www.gutenberg.org/ebooks/53).
- test/GH-382/defneg3.dat was the smallest file generated by Nathan Moinvaziri
that reproduced GH-382. It is licensed under the terms of the zlib license.
diff --git a/src/zlib-ng/test/abicheck.md b/src/zlib-ng/test/abicheck.md
index 6e9e58a..57337f5 100644
--- a/src/zlib-ng/test/abicheck.md
+++ b/src/zlib-ng/test/abicheck.md
@@ -29,7 +29,7 @@ means someone has to check out and build
the previous source tree and extract its .abi
using abidw. This can be slow.
-If you don't mind the slowness, run abicheck.sh --refresh_if,
+If you don't mind the slowness, run abicheck.sh --refresh-if,
and it will download and build the reference version
and extract the .abi on the spot if needed.
(FIXME: should this be the default?)
@@ -46,7 +46,7 @@ constantly downloading and building the old
version, you can check the .abi file into git.
To make this easier, a helper script could be written to automatically build
-all the configurations tested by .github/worflows/abicheck.yml
+all the configurations tested by .github/workflows/abicheck.yml
Then they could be checked into git en masse by a maintainer
when a new platform is added or a new major version (which
intentionally breaks backwards compatibility) is being prepared.
diff --git a/src/zlib-ng/test/abicheck.sh b/src/zlib-ng/test/abicheck.sh
index 89199a5..4267aff 100755
--- a/src/zlib-ng/test/abicheck.sh
+++ b/src/zlib-ng/test/abicheck.sh
@@ -49,7 +49,7 @@ do
--refresh)
refresh=true
;;
- --refresh_if)
+ --refresh-if)
refresh_if=true
;;
--help)
@@ -94,7 +94,11 @@ then
fi
# Canonicalize CHOST to work around bug in original zlib's configure
-export CHOST=$(sh $TESTDIR/../tools/config.sub $CHOST)
+# (Don't export it if it wasn't already exported, else may cause
+# default compiler detection failure and shared library link error
+# when building both zlib and zlib-ng.
+# See https://github.com/zlib-ng/zlib-ng/issues/1219)
+CHOST=$(sh $TESTDIR/../tools/config.sub $CHOST)
if test "$CHOST" = ""
then
@@ -121,7 +125,7 @@ then
git reset --hard FETCH_HEAD
cd ..
# Build unstripped, uninstalled, very debug shared library
- CFLAGS="$CFLAGS -ggdb" sh src.d/configure $CONFIGURE_ARGS
+ CFLAGS="$CFLAGS -ggdb" src.d/configure $CONFIGURE_ARGS
make -j2
cd ..
# Find shared library, extract its abi
@@ -134,12 +138,10 @@ then
# caching abi files in git (but that would slow builds down).
fi
-if test -f "$ABIFILE"
+if ! test -f "$ABIFILE"
then
- ABIFILE="$ABIFILE"
-else
- echo "abicheck: SKIP: $ABIFILE not found; rerun with --refresh or --refresh_if"
- exit 0
+ echo "abicheck: SKIP: $ABIFILE not found; rerun with --refresh or --refresh-if"
+ exit 1
fi
# Build unstripped, uninstalled, very debug shared library
diff --git a/src/zlib-ng/test/benchmarks/CMakeLists.txt b/src/zlib-ng/test/benchmarks/CMakeLists.txt
new file mode 100644
index 0000000..19762fc
--- /dev/null
+++ b/src/zlib-ng/test/benchmarks/CMakeLists.txt
@@ -0,0 +1,96 @@
+cmake_minimum_required(VERSION 3.12)
+
+include(FetchContent)
+
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS ON)
+enable_language(CXX)
+
+# Search for Google benchmark package
+find_package(benchmark QUIET)
+if(NOT benchmark_FOUND)
+ # Fetch google benchmark source code from official repository
+ set(BENCHMARK_ENABLE_TESTING OFF)
+ FetchContent_Declare(benchmark
+ GIT_REPOSITORY https://github.com/google/benchmark.git)
+ FetchContent_MakeAvailable(benchmark)
+ FetchContent_GetProperties(benchmark)
+
+ if(NOT benchmark_POPULATED)
+ FetchContent_Populate(benchmark)
+ endif()
+endif()
+
+add_executable(benchmark_zlib
+ benchmark_adler32.cc
+ benchmark_adler32_copy.cc
+ benchmark_compare256.cc
+ benchmark_crc32.cc
+ benchmark_main.cc
+ benchmark_slidehash.cc
+ )
+
+target_include_directories(benchmark_zlib PRIVATE
+ ${CMAKE_SOURCE_DIR}
+ ${CMAKE_BINARY_DIR}
+ ${benchmark_SOURCE_DIR}/benchmark/include)
+
+target_link_libraries(benchmark_zlib zlibstatic benchmark::benchmark)
+if(WIN32)
+ target_link_libraries(benchmark_zlib shlwapi)
+endif()
+
+if(ZLIB_ENABLE_TESTS)
+ add_test(NAME benchmark_zlib
+ COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:benchmark_zlib>)
+endif()
+
+if(WITH_BENCHMARK_APPS)
+ option(BUILD_ALT_BENCH "Link against alternative zlib implementation" OFF)
+
+ # Search for libpng package
+ find_package(PNG QUIET)
+
+ if(NOT PNG_FOUND)
+ FetchContent_Declare(PNG
+ GIT_REPOSITORY https://github.com/glennrp/libpng.git)
+ FetchContent_MakeAvailable(PNG)
+ FetchContent_GetProperties(PNG)
+
+ if(NOT PNG_POPULATED)
+ FetchContent_Populate(PNG)
+ endif()
+ endif()
+
+ set(BENCH_APP_SRCS
+ benchmark_png_encode.cc
+ benchmark_png_decode.cc
+ benchmark_main.cc
+ )
+
+ add_executable(benchmark_zlib_apps ${BENCH_APP_SRCS})
+
+ if(DEFINED BUILD_ALT_BENCH)
+ set(ZLIB_ALT_LIB "libz.a" CACHE FILEPATH "Optional alternative zlib implementation (defaults to stock zlib)")
+ add_executable(benchmark_zlib_apps_alt ${BENCH_APP_SRCS})
+ target_link_libraries(benchmark_zlib_apps_alt libpng.a ${ZLIB_ALT_LIB} benchmark::benchmark)
+ target_compile_definitions(benchmark_zlib_apps_alt PRIVATE BUILD_ALT=1)
+ target_include_directories(benchmark_zlib_apps_alt PRIVATE
+ ${CMAKE_SOURCE_DIR}
+ ${CMAKE_BINARY_DIR}
+ ${PNG_INCLUDE_DIR}
+ ${benchmark_SOURCE_DIR}/benchmark/include)
+ endif()
+
+ target_include_directories(benchmark_zlib_apps PRIVATE
+ ${CMAKE_SOURCE_DIR}
+ ${CMAKE_BINARY_DIR}
+ ${PNG_INCLUDE_DIR}
+ ${benchmark_SOURCE_DIR}/benchmark/include)
+
+ # We need the static png library if we're statically linking to zlib,
+ # otherwise it will resolve these things in the system provided dynamic
+ # libraries (likely linked to stock zlib)
+ target_link_libraries(benchmark_zlib_apps libpng.a zlibstatic benchmark::benchmark)
+endif()
diff --git a/src/zlib-ng/test/benchmarks/README.md b/src/zlib-ng/test/benchmarks/README.md
new file mode 100644
index 0000000..5dce7f5
--- /dev/null
+++ b/src/zlib-ng/test/benchmarks/README.md
@@ -0,0 +1,47 @@
+## Benchmarks
+These benchmarks are written using [Google Benchmark](https://github.com/google/benchmark).
+
+*Repetitions*
+
+To increase the number of times each benchmark iteration is run use:
+
+```
+--benchmark_repetitions=20
+```
+
+*Filters*
+
+To filter out which benchmarks are performed use:
+
+```
+--benchmark_filter="adler32*"
+```
+
+There are two different benchmarks, micro and macro.
+
+### Benchmark benchmark_zlib
+These are microbenchmarks intended to test lower level subfunctions of the library.
+
+Benchmarks include impelementations of:
+ - Adler32
+ - CRC
+ - 256 byte comparisons
+ - SIMD accelerated "slide hash" routine
+
+By default these benchmarks report things on the nanosecond scale and are small enough
+to measure very minute diferences.
+
+### Benchmark benchmark_zlib_apps
+These benchmarks measure applications of zlib as a whole. Currently the only examples
+are PNG encoding and decoding. The PNG encode and decode tests leveraging procedurally
+generated and highly compressible image data.
+
+Additionally, a test called `png_decode_realistic` that will decode any RGB 8 BPP encoded
+set of PNGs in the working directory under a directory named "test_pngs" with files named
+{0..1}.png. If these images do not exist, they will error out and the benchmark will move
+on to the next set of benchmarks.
+
+*benchmark_zlib_apps_alt*
+
+The user can compile a comparison benchmark application linking to any zlib-compatible
+implementation of his or her choosing.
diff --git a/src/zlib-ng/test/benchmarks/benchmark_adler32.cc b/src/zlib-ng/test/benchmarks/benchmark_adler32.cc
new file mode 100644
index 0000000..b691c23
--- /dev/null
+++ b/src/zlib-ng/test/benchmarks/benchmark_adler32.cc
@@ -0,0 +1,89 @@
+/* benchmark_adler32.cc -- benchmark adler32 variants
+ * Copyright (C) 2022 Nathan Moinvaziri, Adam Stylinski
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include <benchmark/benchmark.h>
+
+extern "C" {
+# include "zbuild.h"
+# include "zutil_p.h"
+# include "cpu_features.h"
+}
+
+#define MAX_RANDOM_INTS (1024 * 1024)
+#define MAX_RANDOM_INTS_SIZE (MAX_RANDOM_INTS * sizeof(uint32_t))
+
+class adler32: public benchmark::Fixture {
+private:
+ uint32_t *random_ints;
+
+public:
+ void SetUp(const ::benchmark::State& state) {
+ /* Control the alignment so that we have the best case scenario for loads. With
+ * AVX512, unaligned loads can mean we're crossing a cacheline boundary at every load.
+ * And while this is a realistic scenario, it makes it difficult to compare benchmark
+ * to benchmark because one allocation could have been aligned perfectly for the loads
+ * while the subsequent one happened to not be. This is not to be advantageous to AVX512
+ * (indeed, all lesser SIMD implementations benefit from this aligned allocation), but to
+ * control the _consistency_ of the results */
+ random_ints = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE);
+ assert(random_ints != NULL);
+
+ for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) {
+ random_ints[i] = rand();
+ }
+ }
+
+ void Bench(benchmark::State& state, adler32_func adler32) {
+ uint32_t hash = 0;
+
+ for (auto _ : state) {
+ hash = adler32(hash, (const unsigned char *)random_ints, state.range(0));
+ }
+
+ benchmark::DoNotOptimize(hash);
+ }
+
+ void TearDown(const ::benchmark::State& state) {
+ zng_free(random_ints);
+ }
+};
+
+#define BENCHMARK_ADLER32(name, fptr, support_flag) \
+ BENCHMARK_DEFINE_F(adler32, name)(benchmark::State& state) { \
+ if (!support_flag) { \
+ state.SkipWithError("CPU does not support " #name); \
+ } \
+ Bench(state, fptr); \
+ } \
+ BENCHMARK_REGISTER_F(adler32, name)->Range(2048, MAX_RANDOM_INTS_SIZE);
+
+BENCHMARK_ADLER32(c, adler32_c, 1);
+
+#ifdef ARM_NEON_ADLER32
+BENCHMARK_ADLER32(neon, adler32_neon, arm_cpu_has_neon);
+#endif
+
+#ifdef PPC_VMX_ADLER32
+BENCHMARK_ADLER32(vmx, adler32_vmx, power_cpu_has_altivec);
+#endif
+#ifdef POWER8_VSX_ADLER32
+BENCHMARK_ADLER32(power8, adler32_power8, power_cpu_has_arch_2_07);
+#endif
+
+#ifdef X86_SSSE3_ADLER32
+BENCHMARK_ADLER32(ssse3, adler32_ssse3, x86_cpu_has_ssse3);
+#endif
+#ifdef X86_AVX2_ADLER32
+BENCHMARK_ADLER32(avx2, adler32_avx2, x86_cpu_has_avx2);
+#endif
+#ifdef X86_AVX512_ADLER32
+BENCHMARK_ADLER32(avx512, adler32_avx512, x86_cpu_has_avx512);
+#endif
+#ifdef X86_AVX512VNNI_ADLER32
+BENCHMARK_ADLER32(avx512_vnni, adler32_avx512_vnni, x86_cpu_has_avx512vnni);
+#endif
diff --git a/src/zlib-ng/test/benchmarks/benchmark_adler32_copy.cc b/src/zlib-ng/test/benchmarks/benchmark_adler32_copy.cc
new file mode 100644
index 0000000..fac4c7f
--- /dev/null
+++ b/src/zlib-ng/test/benchmarks/benchmark_adler32_copy.cc
@@ -0,0 +1,117 @@
+/* benchmark_adler32_copy.cc -- benchmark adler32 (elided copy) variants
+ * Copyright (C) 2022 Nathan Moinvaziri, Adam Stylinski
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+#include <benchmark/benchmark.h>
+
+extern "C" {
+# include "zbuild.h"
+# include "zutil_p.h"
+# include "cpu_features.h"
+}
+
+#define MAX_RANDOM_INTS (1024 * 1024)
+#define MAX_RANDOM_INTS_SIZE (MAX_RANDOM_INTS * sizeof(uint32_t))
+
+typedef uint32_t (*adler32_cpy_func)(uint32_t adler, unsigned char *dst, const unsigned char *buf, size_t len);
+
+class adler32_copy: public benchmark::Fixture {
+private:
+ uint32_t *random_ints_src;
+ uint32_t *random_ints_dst;
+
+public:
+ void SetUp(const ::benchmark::State& state) {
+ /* Control the alignment so that we have the best case scenario for loads. With
+ * AVX512, unaligned loads can mean we're crossing a cacheline boundary at every load.
+ * And while this is a realistic scenario, it makes it difficult to compare benchmark
+ * to benchmark because one allocation could have been aligned perfectly for the loads
+ * while the subsequent one happened to not be. This is not to be advantageous to AVX512
+ * (indeed, all lesser SIMD implementations benefit from this aligned allocation), but to
+ * control the _consistency_ of the results */
+ random_ints_src = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE);
+ random_ints_dst = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE);
+ assert(random_ints != NULL);
+
+ for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) {
+ random_ints_src[i] = rand();
+ }
+ }
+
+ void Bench(benchmark::State& state, adler32_cpy_func adler32_func) {
+ uint32_t hash = 0;
+
+ for (auto _ : state) {
+ hash = adler32_func(hash, (unsigned char *)random_ints_dst,
+ (const unsigned char*)random_ints_src, state.range(0));
+ }
+
+ benchmark::DoNotOptimize(hash);
+ }
+
+ void TearDown(const ::benchmark::State& state) {
+ zng_free(random_ints_src);
+ zng_free(random_ints_dst);
+ }
+};
+
+#define BENCHMARK_ADLER32_COPY(name, fptr, support_flag) \
+ BENCHMARK_DEFINE_F(adler32_copy, name)(benchmark::State& state) { \
+ if (!support_flag) { \
+ state.SkipWithError("CPU does not support " #name); \
+ } \
+ Bench(state, fptr); \
+ } \
+ BENCHMARK_REGISTER_F(adler32_copy, name)->Range(8192, MAX_RANDOM_INTS_SIZE);
+
+#define BENCHMARK_ADLER32_BASELINE_COPY(name, fptr, support_flag) \
+ BENCHMARK_DEFINE_F(adler32_copy, name)(benchmark::State& state) { \
+ if (!support_flag) { \
+ state.SkipWithError("CPU does not support " #name); \
+ } \
+ Bench(state, [](uint32_t init_sum, unsigned char *dst, \
+ const unsigned char *buf, size_t len) -> uint32_t { \
+ memcpy(dst, buf, len); \
+ return fptr(init_sum, buf, len); \
+ }); \
+ } \
+ BENCHMARK_REGISTER_F(adler32_copy, name)->Range(8192, MAX_RANDOM_INTS_SIZE);
+
+BENCHMARK_ADLER32_BASELINE_COPY(c, adler32_c, 1);
+
+#ifdef ARM_NEON_ADLER32
+/* If we inline this copy for neon, the function would go here */
+//BENCHMARK_ADLER32_COPY(neon, adler32_neon, arm_cpu_has_neon);
+BENCHMARK_ADLER32_BASELINE_COPY(neon_copy_baseline, adler32_neon, arm_cpu_has_neon);
+#endif
+
+#ifdef PPC_VMX_ADLER32
+//BENCHMARK_ADLER32_COPY(vmx_inline_copy, adler32_fold_copy_vmx, power_cpu_has_altivec);
+BENCHMARK_ADLER32_BASELINE_COPY(vmx_copy_baseline, adler32_vmx, power_cpu_has_altivec);
+#endif
+#ifdef POWER8_VSX_ADLER32
+//BENCHMARK_ADLER32_COPY(power8_inline_copy, adler32_fold_copy_power8, power_cpu_has_arch_2_07);
+BENCHMARK_ADLER32_BASELINE_COPY(power8, adler32_power8, power_cpu_has_arch_2_07);
+#endif
+
+#ifdef X86_SSE42_ADLER32
+BENCHMARK_ADLER32_BASELINE_COPY(sse42_baseline, adler32_ssse3, x86_cpu_has_ssse3);
+BENCHMARK_ADLER32_COPY(sse42, adler32_fold_copy_sse42, x86_cpu_has_sse42);
+#endif
+#ifdef X86_AVX2_ADLER32
+BENCHMARK_ADLER32_BASELINE_COPY(avx2_baseline, adler32_avx2, x86_cpu_has_avx2);
+BENCHMARK_ADLER32_COPY(avx2, adler32_fold_copy_avx2, x86_cpu_has_avx2);
+#endif
+#ifdef X86_AVX512_ADLER32
+BENCHMARK_ADLER32_BASELINE_COPY(avx512_baseline, adler32_avx512, x86_cpu_has_avx512);
+BENCHMARK_ADLER32_COPY(avx512, adler32_fold_copy_avx512, x86_cpu_has_avx512);
+#endif
+#ifdef X86_AVX512VNNI_ADLER32
+BENCHMARK_ADLER32_BASELINE_COPY(avx512_vnni_baseline, adler32_avx512_vnni, x86_cpu_has_avx512vnni);
+BENCHMARK_ADLER32_COPY(avx512_vnni, adler32_fold_copy_avx512_vnni, x86_cpu_has_avx512vnni);
+#endif
diff --git a/src/zlib-ng/test/benchmarks/benchmark_compare256.cc b/src/zlib-ng/test/benchmarks/benchmark_compare256.cc
new file mode 100644
index 0000000..54459da
--- /dev/null
+++ b/src/zlib-ng/test/benchmarks/benchmark_compare256.cc
@@ -0,0 +1,84 @@
+/* benchmark_compare256.cc -- benchmark compare256 variants
+ * Copyright (C) 2022 Nathan Moinvaziri
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <stdio.h>
+
+#include <benchmark/benchmark.h>
+
+extern "C" {
+# include "zbuild.h"
+# include "zutil_p.h"
+# include "cpu_features.h"
+}
+
+#define MAX_COMPARE_SIZE (256)
+
+class compare256: public benchmark::Fixture {
+private:
+ uint8_t *str1;
+ uint8_t *str2;
+
+public:
+ void SetUp(const ::benchmark::State& state) {
+ str1 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE);
+ assert(str1 != NULL);
+ memset(str1, 'a', MAX_COMPARE_SIZE);
+
+ str2 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE);
+ assert(str2 != NULL);
+ memset(str2, 'a', MAX_COMPARE_SIZE);
+ }
+
+ void Bench(benchmark::State& state, compare256_func compare256) {
+ int32_t match_len = (int32_t)state.range(0) - 1;
+ uint32_t len;
+
+ str2[match_len] = 0;
+ for (auto _ : state) {
+ len = compare256((const uint8_t *)str1, (const uint8_t *)str2);
+ }
+ str2[match_len] = 'a';
+
+ benchmark::DoNotOptimize(len);
+ }
+
+ void TearDown(const ::benchmark::State& state) {
+ zng_free(str1);
+ zng_free(str2);
+ }
+};
+
+#define BENCHMARK_COMPARE256(name, fptr, support_flag) \
+ BENCHMARK_DEFINE_F(compare256, name)(benchmark::State& state) { \
+ if (!support_flag) { \
+ state.SkipWithError("CPU does not support " #name); \
+ } \
+ Bench(state, fptr); \
+ } \
+ BENCHMARK_REGISTER_F(compare256, name)->Range(1, MAX_COMPARE_SIZE);
+
+BENCHMARK_COMPARE256(c, compare256_c, 1);
+
+#ifdef UNALIGNED_OK
+BENCHMARK_COMPARE256(unaligned_16, compare256_unaligned_16, 1);
+#ifdef HAVE_BUILTIN_CTZ
+BENCHMARK_COMPARE256(unaligned_32, compare256_unaligned_32, 1);
+#endif
+#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL)
+BENCHMARK_COMPARE256(unaligned_64, compare256_unaligned_64, 1);
+#endif
+#endif
+#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ)
+BENCHMARK_COMPARE256(sse2, compare256_sse2, x86_cpu_has_sse2);
+#endif
+#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ)
+BENCHMARK_COMPARE256(avx2, compare256_avx2, x86_cpu_has_avx2);
+#endif
+#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL)
+BENCHMARK_COMPARE256(neon, compare256_neon, arm_cpu_has_neon);
+#endif
+#ifdef POWER9
+BENCHMARK_COMPARE256(power9, compare256_power9, power_cpu_has_arch_3_00);
+#endif
diff --git a/src/zlib-ng/test/benchmarks/benchmark_crc32.cc b/src/zlib-ng/test/benchmarks/benchmark_crc32.cc
new file mode 100644
index 0000000..c781c62
--- /dev/null
+++ b/src/zlib-ng/test/benchmarks/benchmark_crc32.cc
@@ -0,0 +1,69 @@
+/* benchmark_crc32.cc -- benchmark crc32 variants
+ * Copyright (C) 2022 Nathan Moinvaziri
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include <benchmark/benchmark.h>
+
+extern "C" {
+# include "zbuild.h"
+# include "zutil_p.h"
+# include "cpu_features.h"
+}
+
+#define MAX_RANDOM_INTS (1024 * 1024)
+#define MAX_RANDOM_INTS_SIZE (MAX_RANDOM_INTS * sizeof(uint32_t))
+
+class crc32: public benchmark::Fixture {
+private:
+ uint32_t *random_ints;
+
+public:
+ void SetUp(const ::benchmark::State& state) {
+ random_ints = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE);
+ assert(random_ints != NULL);
+
+ for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) {
+ random_ints[i] = rand();
+ }
+ }
+
+ void Bench(benchmark::State& state, crc32_func crc32) {
+ uint32_t hash = 0;
+
+ for (auto _ : state) {
+ hash = crc32(hash, (const unsigned char *)random_ints, state.range(0));
+ }
+
+ benchmark::DoNotOptimize(hash);
+ }
+
+ void TearDown(const ::benchmark::State& state) {
+ zng_free(random_ints);
+ }
+};
+
+#define BENCHMARK_CRC32(name, fptr, support_flag) \
+ BENCHMARK_DEFINE_F(crc32, name)(benchmark::State& state) { \
+ if (!support_flag) { \
+ state.SkipWithError("CPU does not support " #name); \
+ } \
+ Bench(state, fptr); \
+ } \
+ BENCHMARK_REGISTER_F(crc32, name)->Range(1, MAX_RANDOM_INTS_SIZE);
+
+BENCHMARK_CRC32(braid, crc32_braid, 1);
+
+#ifdef ARM_ACLE_CRC_HASH
+BENCHMARK_CRC32(acle, crc32_acle, arm_cpu_has_crc32);
+#elif defined(POWER8_VSX_CRC32)
+BENCHMARK_CRC32(power8, crc32_power8, power_cpu_has_arch_2_07);
+#elif defined(S390_CRC32_VX)
+BENCHMARK_CRC32(vx, PREFIX(s390_crc32_vx), PREFIX(s390_cpu_has_vx));
+#elif defined(X86_PCLMULQDQ_CRC)
+/* CRC32 fold does a memory copy while hashing */
+BENCHMARK_CRC32(pclmulqdq, crc32_pclmulqdq, x86_cpu_has_pclmulqdq);
+#endif
diff --git a/src/zlib-ng/test/benchmarks/benchmark_main.cc b/src/zlib-ng/test/benchmarks/benchmark_main.cc
new file mode 100644
index 0000000..ee8b614
--- /dev/null
+++ b/src/zlib-ng/test/benchmarks/benchmark_main.cc
@@ -0,0 +1,26 @@
+/* benchmark_main.cc -- benchmark suite main entry point
+ * Copyright (C) 2022 Nathan Moinvaziri
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <stdio.h>
+
+#include <benchmark/benchmark.h>
+
+#ifndef BUILD_ALT
+extern "C" {
+# include "zbuild.h"
+# include "cpu_features.h"
+}
+#endif
+
+int main(int argc, char** argv) {
+#ifndef BUILD_ALT
+ cpu_check_features();
+#endif
+
+ ::benchmark::Initialize(&argc, argv);
+ ::benchmark::RunSpecifiedBenchmarks();
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/zlib-ng/test/benchmarks/benchmark_png_decode.cc b/src/zlib-ng/test/benchmarks/benchmark_png_decode.cc
new file mode 100644
index 0000000..c037976
--- /dev/null
+++ b/src/zlib-ng/test/benchmarks/benchmark_png_decode.cc
@@ -0,0 +1,126 @@
+#include <stdio.h>
+#include <benchmark/benchmark.h>
+#include "benchmark_png_shared.h"
+#include <assert.h>
+
+class png_decode: public benchmark::Fixture {
+protected:
+ png_dat inpng[10];
+
+ /* Backing this on the heap is a more realistic benchmark */
+ uint8_t *output_img_buf = NULL;
+
+public:
+ /* Let's make the vanilla version have something extremely compressible */
+ virtual void init_img(png_bytep img_bytes, size_t width, size_t height) {
+ init_compressible(img_bytes, width*height);
+ }
+
+ void SetUp(const ::benchmark::State& state) {
+ output_img_buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3);
+ assert(output_img_buf != NULL);
+ init_img(output_img_buf, IMWIDTH, IMHEIGHT);
+
+ /* First we need to author the png bytes to be decoded */
+ for (int i = 0; i < 10; ++i) {
+ inpng[i] = {NULL, 0, 0};
+ encode_png(output_img_buf, &inpng[i], i, IMWIDTH, IMHEIGHT);
+ }
+ }
+
+ /* State in this circumstance will convey the compression level */
+ void Bench(benchmark::State &state) {
+ for (auto _ : state) {
+ int compress_lvl = state.range(0);
+ png_parse_dat in = { inpng[compress_lvl].buf };
+ uint32_t width, height;
+ decode_png(&in, (png_bytepp)&output_img_buf, IMWIDTH * IMHEIGHT * 3, width, height);
+ }
+ }
+
+ void TearDown(const ::benchmark::State &state) {
+ free(output_img_buf);
+ for (int i = 0; i < 10; ++i) {
+ free(inpng[i].buf);
+ }
+ }
+};
+
+class png_decode_realistic: public png_decode {
+private:
+ bool test_files_found = false;
+
+public:
+ void SetUp(const ::benchmark::State &state) {
+ output_img_buf = NULL;
+ output_img_buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3);
+ /* Let's take all the images at different compression levels and jam their bytes into buffers */
+ char test_fname[25];
+ FILE *files[10];
+
+ /* Set all to NULL */
+ memset(files, 0, sizeof(FILE*));
+
+ for (size_t i = 0; i < 10; ++i) {
+ sprintf(test_fname, "test_pngs/%1lu.png", i);
+ FILE *in_img = fopen(test_fname, "r");
+ if (in_img == NULL) {
+ for (size_t j = 0; j < i; ++j) {
+ if (files[j])
+ fclose(files[j]);
+ }
+
+ /* For proper cleanup */
+ for (size_t j = i; j < 10; ++j) {
+ inpng[i] = { NULL, 0, 0 };
+ }
+
+ return;
+ }
+ files[i] = in_img;
+ }
+
+ test_files_found = true;
+ /* Now that we've established we have all the png files, let's read all of their bytes into buffers */
+ for (size_t i = 0; i < 10; ++i) {
+ FILE *in_file = files[i];
+ fseek(in_file, 0, SEEK_END);
+ size_t num_bytes = ftell(in_file);
+ rewind(in_file);
+
+ uint8_t *raw_file = (uint8_t*)malloc(num_bytes);
+ if (raw_file == NULL)
+ abort();
+
+ inpng[i].buf = raw_file;
+ inpng[i].len = num_bytes;
+ inpng[i].buf_rem = 0;
+
+ size_t bytes_read = fread(raw_file, 1, num_bytes, in_file);
+ if (bytes_read != num_bytes) {
+ fprintf(stderr, "couldn't read all of the bytes for file test_pngs/%lu.png", i);
+ abort();
+ }
+
+ fclose(in_file);
+ }
+ }
+
+ void Bench(benchmark::State &state) {
+ if (!test_files_found) {
+ state.SkipWithError("Test imagery in test_pngs not found");
+ }
+
+ png_decode::Bench(state);
+ }
+};
+
+BENCHMARK_DEFINE_F(png_decode, png_decode)(benchmark::State &state) {
+ Bench(state);
+}
+BENCHMARK_REGISTER_F(png_decode, png_decode)->DenseRange(0, 9, 1)->Unit(benchmark::kMicrosecond);
+
+BENCHMARK_DEFINE_F(png_decode_realistic, png_decode_realistic)(benchmark::State &state) {
+ Bench(state);
+}
+BENCHMARK_REGISTER_F(png_decode_realistic, png_decode_realistic)->DenseRange(0, 9, 1)->Unit(benchmark::kMicrosecond);
diff --git a/src/zlib-ng/test/benchmarks/benchmark_png_encode.cc b/src/zlib-ng/test/benchmarks/benchmark_png_encode.cc
new file mode 100644
index 0000000..f1c597d
--- /dev/null
+++ b/src/zlib-ng/test/benchmarks/benchmark_png_encode.cc
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <assert.h>
+#include <benchmark/benchmark.h>
+#include "benchmark_png_shared.h"
+
+#define IMWIDTH 1024
+#define IMHEIGHT 1024
+
+class png_encode: public benchmark::Fixture {
+private:
+ png_dat outpng;
+
+ /* Backing this on the heap is a more realistic benchmark */
+ uint8_t *input_img_buf = NULL;
+
+public:
+ /* Let's make the vanilla version have something extremely compressible */
+ virtual void init_img(png_bytep img_bytes, size_t width, size_t height) {
+ init_compressible(img_bytes, width * height);
+ }
+
+ void SetUp(const ::benchmark::State& state) {
+ input_img_buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3);
+ outpng.buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3);
+ /* Using malloc rather than zng_alloc so that we can call realloc.
+ * IMWIDTH * IMHEIGHT is likely to be more than enough bytes, though,
+ * given that a simple run length encoding already pretty much can
+ * reduce to this */
+ outpng.len = 0;
+ outpng.buf_rem = IMWIDTH * IMHEIGHT * 3;
+ assert(input_img_buf != NULL);
+ assert(outpng.buf != NULL);
+ init_img(input_img_buf, IMWIDTH, IMHEIGHT);
+ }
+
+ /* State in this circumstance will convey the compression level */
+ void Bench(benchmark::State &state) {
+ for (auto _ : state) {
+ encode_png((png_bytep)input_img_buf, &outpng, state.range(0), IMWIDTH, IMHEIGHT);
+ outpng.buf_rem = outpng.len;
+ outpng.len = 0;
+ }
+ }
+
+ void TearDown(const ::benchmark::State &state) {
+ free(input_img_buf);
+ free(outpng.buf);
+ }
+};
+
+BENCHMARK_DEFINE_F(png_encode, encode_compressible)(benchmark::State &state) {
+ Bench(state);
+}
+BENCHMARK_REGISTER_F(png_encode, encode_compressible)->DenseRange(0, 9, 1)->Unit(benchmark::kMicrosecond);
diff --git a/src/zlib-ng/test/benchmarks/benchmark_png_shared.h b/src/zlib-ng/test/benchmarks/benchmark_png_shared.h
new file mode 100644
index 0000000..926b4d9
--- /dev/null
+++ b/src/zlib-ng/test/benchmarks/benchmark_png_shared.h
@@ -0,0 +1,146 @@
+#pragma once
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#define IMWIDTH 1024
+#define IMHEIGHT 1024
+
+extern "C" {
+# include <png.h>
+}
+
+typedef struct _png_dat {
+ uint8_t *buf;
+ int64_t len;
+ size_t buf_rem;
+} png_dat;
+
+typedef struct _png_parse_dat {
+ uint8_t *cur_pos;
+} png_parse_dat;
+
+/* Write a customized write callback so that we write back to an in-memory buffer.
+ * This allows the testing to not involve disk IO */
+static void png_write_cb(png_structp pngp, png_bytep data, png_size_t len) {
+ png_dat *dat = (png_dat*)png_get_io_ptr(pngp);
+ size_t curSize = dat->len + len;
+
+ /* realloc double the requested buffer size to prevent excessive reallocs */
+ if (dat->buf_rem < len) {
+ dat->buf = (uint8_t*)realloc(dat->buf, dat->len + dat->buf_rem + 2 * len);
+
+ if (!dat->buf) {
+ /* Pretty unlikely but we'll put it here just in case */
+ fprintf(stderr, "realloc failed, exiting\n");
+ exit(1);
+ }
+
+ dat->buf_rem += 2 * len;
+ }
+
+ memcpy(dat->buf + dat->len, data, len);
+ dat->len = curSize;
+ dat->buf_rem -= len;
+}
+
+static void init_compressible(png_bytep buf, size_t num_pix) {
+ /* It doesn't actually matter what we make this, but for
+ * the sake of a reasonable test image, let's make this
+ * be a stripe of R, G, & B, with no alpha channel */
+ int32_t i = 0;
+ int32_t red_stop = num_pix / 3;
+ int32_t blue_stop = 2 * num_pix / 3;
+ int32_t green_stop = num_pix;
+
+ for (int32_t x = 0; i < red_stop; x += 3, ++i) {
+ buf[x] = 255;
+ buf[x + 1] = 0;
+ buf[x + 2] = 0;
+ }
+
+ for (int32_t x = 3 * i; i < blue_stop; x+= 3, ++i) {
+ buf[x] = 0;
+ buf[x + 1] = 255;
+ buf[x + 2] = 0;
+ }
+
+ for (int32_t x = 3 * i; i < green_stop; x += 3, ++i) {
+ buf[x] = 0;
+ buf[x + 1] = 0;
+ buf[x + 2] = 255;
+ }
+}
+
+static inline void encode_png(png_bytep buf, png_dat *outpng, int32_t comp_level, uint32_t width, uint32_t height) {
+ png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+
+ /* Most of this error handling is _likely_ not necessary. Likewise it's likely
+ * a lot of this stuff can be done in the setup function to avoid measuring this
+ * fixed setup time, but for now we'll do it here */
+ if (!png) abort();
+
+ png_infop info = png_create_info_struct(png);
+ if (!info) abort();
+
+ png_set_write_fn(png, outpng, png_write_cb, NULL);
+ png_bytep *png_row_ptrs = new png_bytep[height];
+ for (int i = 0; i < IMHEIGHT; ++i) {
+ png_row_ptrs[i] = (png_bytep)&buf[3*i*width];
+ }
+
+ png_set_IHDR(png, info, IMWIDTH, IMHEIGHT, 8, PNG_COLOR_TYPE_RGB,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
+ PNG_FILTER_TYPE_DEFAULT);
+
+ png_write_info(png, info);
+ png_set_compression_level(png, comp_level);
+ png_set_filter(png, 0, PNG_FILTER_NONE);
+ png_write_image(png, (png_bytepp)png_row_ptrs);
+ png_write_end(png, NULL);
+ png_destroy_write_struct(&png, &info);
+ delete[] png_row_ptrs;
+}
+
+static void read_from_pngdat(png_structp png, png_bytep out, png_size_t bytes_to_read) {
+ png_parse_dat *io = (png_parse_dat*)png_get_io_ptr(png);
+ memcpy(out, io->cur_pos, bytes_to_read);
+ io->cur_pos += bytes_to_read;
+}
+
+static inline int decode_png(png_parse_dat *dat, png_bytepp out_bytes, size_t in_size, uint32_t &width, uint32_t &height) {
+ png_structp png = NULL;
+ png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+
+ if (!png) abort();
+ png_infop info = NULL;
+ info = png_create_info_struct(png);
+ if (!info) abort();
+
+ png_set_read_fn(png, dat, read_from_pngdat);
+ png_read_info(png, info);
+
+ int bit_depth = 0, color_type = -1;
+ png_get_IHDR(png, info, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
+
+ size_t im_size = width * height * bit_depth/8 * 3;
+ if (color_type != PNG_COLOR_TYPE_RGB) {
+ fprintf(stderr, "expected an 8 bpp RGB image\n");
+ abort();
+ }
+
+ if (im_size > in_size) {
+ *out_bytes = (png_bytep)realloc(*out_bytes, im_size);
+ }
+
+ png_bytep *out_rows = new png_bytep[height];
+ for (size_t i = 0; i < height; ++i)
+ out_rows[i] = *out_bytes + (width*i*3);
+
+ png_read_rows(png, out_rows, NULL, height);
+ png_destroy_read_struct(&png, &info, NULL);
+ delete[] out_rows;
+
+ return im_size;
+}
diff --git a/src/zlib-ng/test/benchmarks/benchmark_slidehash.cc b/src/zlib-ng/test/benchmarks/benchmark_slidehash.cc
new file mode 100644
index 0000000..655820e
--- /dev/null
+++ b/src/zlib-ng/test/benchmarks/benchmark_slidehash.cc
@@ -0,0 +1,86 @@
+/* benchmark_slidehash.cc -- benchmark slide_hash variants
+ * Copyright (C) 2022 Adam Stylinski, Nathan Moinvaziri
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <limits.h>
+
+#include <benchmark/benchmark.h>
+
+extern "C" {
+# include "zbuild.h"
+# include "zutil_p.h"
+# include "deflate.h"
+# include "cpu_features.h"
+}
+
+#define MAX_RANDOM_INTS 32768
+
+class slide_hash: public benchmark::Fixture {
+private:
+ uint16_t *l0;
+ uint16_t *l1;
+ deflate_state *s_g;
+
+public:
+ void SetUp(const ::benchmark::State& state) {
+ l0 = (uint16_t *)zng_alloc(HASH_SIZE * sizeof(uint16_t));
+
+ for (int32_t i = 0; i < HASH_SIZE; i++) {
+ l0[i] = rand();
+ }
+
+ l1 = (uint16_t *)zng_alloc(MAX_RANDOM_INTS * sizeof(uint16_t));
+
+ for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) {
+ l1[i] = rand();
+ }
+
+ deflate_state *s = (deflate_state*)malloc(sizeof(deflate_state));
+ s->head = l0;
+ s->prev = l1;
+ s_g = s;
+ }
+
+ void Bench(benchmark::State& state, slide_hash_func slide_hash) {
+ s_g->w_size = (uint32_t)state.range(0);
+
+ for (auto _ : state) {
+ slide_hash(s_g);
+ benchmark::DoNotOptimize(s_g);
+ }
+ }
+
+ void TearDown(const ::benchmark::State& state) {
+ zng_free(l0);
+ zng_free(l1);
+ }
+};
+
+#define BENCHMARK_SLIDEHASH(name, fptr, support_flag) \
+ BENCHMARK_DEFINE_F(slide_hash, name)(benchmark::State& state) { \
+ if (!support_flag) { \
+ state.SkipWithError("CPU does not support " #name); \
+ } \
+ Bench(state, fptr); \
+ } \
+ BENCHMARK_REGISTER_F(slide_hash, name)->RangeMultiplier(2)->Range(1024, MAX_RANDOM_INTS);
+
+BENCHMARK_SLIDEHASH(c, slide_hash_c, 1);
+
+#ifdef ARM_NEON_SLIDEHASH
+BENCHMARK_SLIDEHASH(neon, slide_hash_neon, arm_cpu_has_neon);
+#endif
+#ifdef POWER8_VSX_SLIDEHASH
+BENCHMARK_SLIDEHASH(power8, slide_hash_power8, power_cpu_has_arch_2_07);
+#endif
+#ifdef PPC_VMX_SLIDEHASH
+BENCHMARK_SLIDEHASH(vmx, slide_hash_vmx, power_cpu_has_altivec);
+#endif
+
+#ifdef X86_SSE2
+BENCHMARK_SLIDEHASH(sse2, slide_hash_sse2, x86_cpu_has_sse2);
+#endif
+#ifdef X86_AVX2
+BENCHMARK_SLIDEHASH(avx2, slide_hash_avx2, x86_cpu_has_avx2);
+#endif
diff --git a/src/zlib-ng/test/data/lcet10.txt b/src/zlib-ng/test/data/lcet10.txt
index 26b187d..1dbdfc5 100644
--- a/src/zlib-ng/test/data/lcet10.txt
+++ b/src/zlib-ng/test/data/lcet10.txt
@@ -897,7 +897,7 @@ current difficulty in exchanging electronically computer-based
instructional software, which in turn makes it difficult for one scholar
to build upon the work of others, will be resolved before too long.
Stand-alone curricular applications that involve electronic text will be
-sharable through networks, reinforcing their significance as intellectual
+shareable through networks, reinforcing their significance as intellectual
products as well as instructional tools.
The second aspect of electronic learning involves the use of research and
@@ -1587,7 +1587,7 @@ Bowdoin.
CALALUCA * PLD's principal focus and contribution to scholarship *
Various questions preparatory to beginning the project * Basis for
project * Basic rule in converting PLD * Concerning the images in PLD *
-Running PLD under a variety of retrieval softwares * Encoding the
+Running PLD under a variety of retrieval software * Encoding the
database a hard-fought issue * Various features demonstrated * Importance
of user documentation * Limitations of the CD-ROM version *
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -1654,7 +1654,7 @@ anything demonstrated at the Workshop.
What cannot practically be done is go back and reconvert and re-encode
data, a time-consuming and extremely costly enterprise. CALALUCA sees
PLD as a database that can, and should, be run under a variety of
-retrieval softwares. This will permit the widest possible searches.
+retrieval software. This will permit the widest possible searches.
Consequently, the need to produce a CD-ROM of PLD, as well as to develop
software that could handle some 1.3 gigabyte of heavily encoded text,
developed out of conversations with collection development and reference
@@ -5034,7 +5034,7 @@ schemes every single discrete area of a text that might someday be
searched. That was another decision. Searching by a column number, an
author, a word, a volume, permitting combination searches, and tagging
notations seemed logical choices as core elements. 3) How does one make
-the data available? Tieing it to a CD-ROM edition creates limitations,
+the data available? Tying it to a CD-ROM edition creates limitations,
but a magnetic tape file that is very large, is accompanied by the
encoding specifications, and that allows one to make local modifications
also allows one to incorporate any changes one may desire within the
diff --git a/src/zlib-ng/test/deflate_quick_bi_valid.c b/src/zlib-ng/test/deflate_quick_bi_valid.c
deleted file mode 100644
index d27e0b1..0000000
--- a/src/zlib-ng/test/deflate_quick_bi_valid.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Generated by fuzzing - test bi_valid handling in deflate_quick(). */
-
-#include "zbuild.h"
-#ifdef ZLIB_COMPAT
-# include "zlib.h"
-#else
-# include "zlib-ng.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-int main() {
- PREFIX3(stream) strm;
- memset(&strm, 0, sizeof(strm));
-
- int ret = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, 31, 1, Z_FILTERED);
- if (ret != Z_OK) {
- fprintf(stderr, "deflateInit2() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
-
- z_const unsigned char next_in[554] =
- "\x8d\xff\xff\xff\xa2\x00\x00\xff\x00\x15\x1b\x1b\xa2\xa2\xaf\xa2"
- "\xa2\x00\x00\x00\x02\x00\x1b\x3f\x00\x00\x01\x00\x00\x00\x00\x0b"
- "\x00\xab\x00\x00\x00\x00\x01\x00\x01\x2b\x01\x00\x00\x00\x00\x00"
- "\x00\x01\x1e\x00\x00\x01\x40\x00\x00\x00\x07\x01\x18\x00\x22\x00"
- "\x00\x00\xfd\x39\xff\x00\x00\x00\x1b\xfd\x3b\x00\x68\x00\x00\x01"
- "\xff\xff\xff\x57\xf8\x1e\x00\x00\xf2\xf2\xf2\xf2\xfa\xff\xff\xff"
- "\xff\x7e\x00\x00\x4a\x00\xc5\x00\x41\x00\x00\x00\x01\x01\x00\x00"
- "\x00\x02\x01\x01\x00\xa2\x08\x00\x00\x00\x00\x27\x4a\x4a\x4a\x32"
- "\x00\xf9\xff\x00\x02\x9a\xff\x00\x00\x3f\x50\x00\x03\x00\x00\x00"
- "\x3d\x00\x08\x2f\x20\x00\x23\x00\x00\x00\x00\x23\x00\xff\xff\xff"
- "\xff\xff\xff\xff\x7a\x7a\x9e\xff\xff\x00\x1b\x1b\x04\x00\x1b\x1b"
- "\x1b\x1b\x00\x00\x00\xaf\xad\xaf\x00\x00\xa8\x00\x00\x00\x2e\xff"
- "\xff\x2e\xc1\x00\x10\x00\x00\x00\x06\x70\x00\x00\x00\xda\x67\x01"
- "\x47\x00\x00\x00\x0c\x02\x00\x00\x00\x00\x00\xff\x00\x01\x00\x3f"
- "\x54\x00\x00\x00\x1b\x00\x00\x00\x5c\x00\x00\x34\x3e\xc5\x00\x00"
- "\x00\x00\x00\x04\x00\x00\x7a\x00\x00\x00\x0a\x01\x00\x00\x00\x00"
- "\x00\x00\x7a\x7a\x7a\x7a\x7a\x00\x00\x00\x40\x1b\x1b\x88\x1b\x1b"
- "\x1b\x1b\x1b\x1b\x1b\x1f\x1b\x00\x00\x00\x00\x00\x0b\x00\x00\x00"
- "\x00\x04\x00\x00\x50\x3e\x7a\x7a\x00\x00\x40\x00\x40\x00\x00\x00"
- "\x00\x00\x00\x08\x87\x00\x00\xff\xff\xff\x00\x00\x00\x00\x00\x00"
- "\x01\x00\xff\x3d\x00\x11\x4d\x00\x00\x01\xd4\xd4\xd4\xd4\x2d\xd4"
- "\xd4\xff\xff\xff\xfa\x01\xd4\x00\xd4\x00\x00\xd4\xd4\xd4\xd4\xd4"
- "\xd4\x1e\x1e\x1e\x1e\x00\x00\xfe\xf9\x1e\x1e\x1e\x1e\x1e\x1e\x00"
- "\x16\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\xd4\x00\x00\x80\x20\x00\x00"
- "\xff\x2b\x2b\x2b\x2b\x35\xd4\xd4\x47\x3f\xd4\xd4\xd6\xd4\xd4\x00"
- "\x00\x00\x00\x00\x32\x4a\x4a\x4a\x4a\x71\x00\x1b\x1b\x1b\x1b\x1b"
- "\x1f\x1b\x1b\x1b\x57\x57\x57\x57\x00\x00\x1b\x08\x2b\x16\xc3\x00"
- "\x00\x00\x29\x30\x03\xff\x03\x03\x03\x03\x07\x00\x00\x01\x0b\xff"
- "\xff\xf5\xf5\xf5\x00\x00\xfe\xfa\x0f\x0f\x08\x00\xff\x00\x53\x3f"
- "\x00\x04\x5d\xa8\x2e\xff\xff\x00\x2f\x2f\x05\xff\xff\xff\x2f\x2f"
- "\x2f\x0a\x0a\x0a\x0a\x30\xff\xff\xff\xf0\x0a\x0a\x0a\x00\xff\x3f"
- "\x4f\x00\x00\x00\x00\x08\x00\x00\x71\x00\x2e\x00\x00\x00\x00\x00"
- "\x71\x71\x00\x71\x71\x71\xf5\x00\x00\x00\x00\x00\x00\x00\xf8\xff"
- "\xff\xff\x00\x00\x00\x00\x00\xdb\x3f\x00\xfa\x71\x71\x71\x00\x00"
- "\x00\x01\x00\x00\x00\x71\x71\x71\x71\x71";
- strm.next_in = next_in;
- unsigned char next_out[1236];
- strm.next_out = next_out;
-
- strm.avail_in = 554;
- strm.avail_out = 31;
- ret = PREFIX(deflate)(&strm, Z_FINISH);
- if (ret != Z_OK) {
- fprintf(stderr, "deflate() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
-
- strm.avail_in = 0;
- strm.avail_out = 498;
- ret = PREFIX(deflate)(&strm, Z_FINISH);
- if (ret != Z_STREAM_END) {
- fprintf(stderr, "deflate() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
-
- ret = PREFIX(deflateEnd)(&strm);
- if (ret != Z_OK) {
- fprintf(stderr, "deflateEnd() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
-}
diff --git a/src/zlib-ng/test/example.c b/src/zlib-ng/test/example.c
index 97ca002..33232de 100644
--- a/src/zlib-ng/test/example.c
+++ b/src/zlib-ng/test/example.c
@@ -12,21 +12,11 @@
#include "deflate.h"
#include <stdio.h>
-
-#include <string.h>
-#include <stdlib.h>
+#include <stdarg.h>
#include <inttypes.h>
-#include <stdint.h>
#define TESTFILE "foo.gz"
-#define CHECK_ERR(err, msg) { \
- if (err != Z_OK) { \
- fprintf(stderr, "%s error: %d\n", msg, err); \
- exit(1); \
- } \
-}
-
static const char hello[] = "hello, hello!";
/* "hello world" would be more standard, but the repeated "hello"
* stresses the compression code better, sorry...
@@ -35,6 +25,9 @@ static const char hello[] = "hello, hello!";
static const char dictionary[] = "hello";
static unsigned long dictId = 0; /* Adler32 value of the dictionary */
+/* Maximum dictionary size, according to inflateGetDictionary() description. */
+#define MAX_DICTIONARY_SIZE 32768
+
void test_compress (unsigned char *compr, z_size_t comprLen,unsigned char *uncompr, z_size_t uncomprLen);
void test_gzio (const char *fname, unsigned char *uncompr, z_size_t uncomprLen);
@@ -53,6 +46,24 @@ static alloc_func zalloc = NULL;
static free_func zfree = NULL;
/* ===========================================================================
+ * Display error message and exit
+ */
+void error(const char *format, ...) {
+ va_list va;
+
+ va_start(va, format);
+ vfprintf(stderr, format, va);
+ va_end(va);
+
+ exit(1);
+}
+
+#define CHECK_ERR(err, msg) { \
+ if (err != Z_OK) \
+ error("%s error: %d\n", msg, err); \
+}
+
+/* ===========================================================================
* Test compress() and uncompress()
*/
void test_compress(unsigned char *compr, z_size_t comprLen, unsigned char *uncompr, z_size_t uncomprLen) {
@@ -67,12 +78,10 @@ void test_compress(unsigned char *compr, z_size_t comprLen, unsigned char *uncom
err = PREFIX(uncompress)(uncompr, &uncomprLen, compr, comprLen);
CHECK_ERR(err, "uncompress");
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad uncompress\n");
- exit(1);
- } else {
+ if (strcmp((char*)uncompr, hello))
+ error("bad uncompress\n");
+ else
printf("uncompress(): %s\n", (char *)uncompr);
- }
}
/* ===========================================================================
@@ -91,145 +100,96 @@ void test_gzio(const char *fname, unsigned char *uncompr, z_size_t uncomprLen) {
/* Write gz file with test data */
file = PREFIX(gzopen)(fname, "wb");
- if (file == NULL) {
- fprintf(stderr, "gzopen error\n");
- exit(1);
- }
+ if (file == NULL)
+ error("gzopen error\n");
/* Write hello, hello! using gzputs and gzprintf */
PREFIX(gzputc)(file, 'h');
- if (PREFIX(gzputs)(file, "ello") != 4) {
- fprintf(stderr, "gzputs err: %s\n", PREFIX(gzerror)(file, &err));
- exit(1);
- }
- if (PREFIX(gzprintf)(file, ", %s!", "hello") != 8) {
- fprintf(stderr, "gzprintf err: %s\n", PREFIX(gzerror)(file, &err));
- exit(1);
- }
+ if (PREFIX(gzputs)(file, "ello") != 4)
+ error("gzputs err: %s\n", PREFIX(gzerror)(file, &err));
+ if (PREFIX(gzprintf)(file, ", %s!", "hello") != 8)
+ error("gzprintf err: %s\n", PREFIX(gzerror)(file, &err));
/* Write string null-teriminator using gzseek */
if (PREFIX(gzseek)(file, 1L, SEEK_CUR) < 0)
- {
- fprintf(stderr, "gzseek error, gztell=%ld\n", (long)PREFIX(gztell)(file));
- exit(1);
- }
+ error("gzseek error, gztell=%ld\n", (long)PREFIX(gztell)(file));
/* Write hello, hello! using gzfwrite using best compression level */
- if (PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY) != Z_OK) {
- fprintf(stderr, "gzsetparams err: %s\n", PREFIX(gzerror)(file, &err));
- exit(1);
- }
- if (PREFIX(gzfwrite)(hello, len, 1, file) == 0) {
- fprintf(stderr, "gzfwrite err: %s\n", PREFIX(gzerror)(file, &err));
- exit(1);
- }
+ if (PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY) != Z_OK)
+ error("gzsetparams err: %s\n", PREFIX(gzerror)(file, &err));
+ if (PREFIX(gzfwrite)(hello, len, 1, file) == 0)
+ error("gzfwrite err: %s\n", PREFIX(gzerror)(file, &err));
/* Flush compressed bytes to file */
- if (PREFIX(gzflush)(file, Z_SYNC_FLUSH) != Z_OK) {
- fprintf(stderr, "gzflush err: %s\n", PREFIX(gzerror)(file, &err));
- exit(1);
- }
+ if (PREFIX(gzflush)(file, Z_SYNC_FLUSH) != Z_OK)
+ error("gzflush err: %s\n", PREFIX(gzerror)(file, &err));
comprLen = PREFIX(gzoffset)(file);
- if (comprLen <= 0) {
- fprintf(stderr, "gzoffset err: %s\n", PREFIX(gzerror)(file, &err));
- exit(1);
- }
+ if (comprLen <= 0)
+ error("gzoffset err: %s\n", PREFIX(gzerror)(file, &err));
PREFIX(gzclose)(file);
/* Open gz file we previously wrote */
file = PREFIX(gzopen)(fname, "rb");
- if (file == NULL) {
- fprintf(stderr, "gzopen error\n");
- exit(1);
- }
+ if (file == NULL)
+ error("gzopen error\n");
+
/* Read uncompressed data - hello, hello! string twice */
strcpy((char*)uncompr, "garbages");
- if (PREFIX(gzread)(file, uncompr, (unsigned)uncomprLen) != (int)(len + len)) {
- fprintf(stderr, "gzread err: %s\n", PREFIX(gzerror)(file, &err));
- exit(1);
- }
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
- exit(1);
- } else {
+ if (PREFIX(gzread)(file, uncompr, (unsigned)uncomprLen) != (int)(len + len))
+ error("gzread err: %s\n", PREFIX(gzerror)(file, &err));
+ if (strcmp((char*)uncompr, hello))
+ error("bad gzread: %s\n", (char*)uncompr);
+ else
printf("gzread(): %s\n", (char*)uncompr);
- }
/* Check position at the end of the gz file */
- if (PREFIX(gzeof)(file) != 1) {
- fprintf(stderr, "gzeof err: not reporting end of stream\n");
- exit(1);
- }
+ if (PREFIX(gzeof)(file) != 1)
+ error("gzeof err: not reporting end of stream\n");
+
/* Seek backwards mid-string and check char reading with gzgetc and gzungetc */
pos = PREFIX(gzseek)(file, -22L, SEEK_CUR);
- if (pos != 6 || PREFIX(gztell)(file) != pos) {
- fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
- (long)pos, (long)PREFIX(gztell)(file));
- exit(1);
- }
- if (PREFIX(gzgetc)(file) != ' ') {
- fprintf(stderr, "gzgetc error\n");
- exit(1);
- }
- if (PREFIX(gzungetc)(' ', file) != ' ') {
- fprintf(stderr, "gzungetc error\n");
- exit(1);
- }
+ if (pos != 6 || PREFIX(gztell)(file) != pos)
+ error("gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)PREFIX(gztell)(file));
+ if (PREFIX(gzgetc)(file) != ' ')
+ error("gzgetc error\n");
+ if (PREFIX(gzungetc)(' ', file) != ' ')
+ error("gzungetc error\n");
/* Read first hello, hello! string with gzgets */
strcpy((char*)uncompr, "garbages");
PREFIX(gzgets)(file, (char*)uncompr, (int)uncomprLen);
- if (strlen((char*)uncompr) != 7) { /* " hello!" */
- fprintf(stderr, "gzgets err after gzseek: %s\n", PREFIX(gzerror)(file, &err));
- exit(1);
- }
- if (strcmp((char*)uncompr, hello + 6)) {
- fprintf(stderr, "bad gzgets after gzseek\n");
- exit(1);
- } else {
+ if (strlen((char*)uncompr) != 7) /* " hello!" */
+ error("gzgets err after gzseek: %s\n", PREFIX(gzerror)(file, &err));
+ if (strcmp((char*)uncompr, hello + 6))
+ error("bad gzgets after gzseek\n");
+ else
printf("gzgets() after gzseek: %s\n", (char*)uncompr);
- }
/* Seek to second hello, hello! string */
pos = PREFIX(gzseek)(file, 14L, SEEK_SET);
- if (pos != 14 || PREFIX(gztell)(file) != pos) {
- fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
- (long)pos, (long)PREFIX(gztell)(file));
- exit(1);
- }
+ if (pos != 14 || PREFIX(gztell)(file) != pos)
+ error("gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)PREFIX(gztell)(file));
/* Check position not at end of file */
- if (PREFIX(gzeof)(file) != 0) {
- fprintf(stderr, "gzeof err: reporting end of stream\n");
- exit(1);
- }
+ if (PREFIX(gzeof)(file) != 0)
+ error("gzeof err: reporting end of stream\n");
/* Read first hello, hello! string with gzfread */
strcpy((char*)uncompr, "garbages");
read = PREFIX(gzfread)(uncompr, uncomprLen, 1, file);
- if (strcmp((const char *)uncompr, hello) != 0) {
- fprintf(stderr, "bad gzgets\n");
- exit(1);
- } else {
+ if (strcmp((const char *)uncompr, hello) != 0)
+ error("bad gzgets\n");
+ else
printf("gzgets(): %s\n", (char*)uncompr);
- }
pos = PREFIX(gzoffset)(file);
- if (pos < 0 || pos != (comprLen + 10)) {
- fprintf(stderr, "gzoffset err: wrong offset at end\n");
- exit(1);
- }
+ if (pos < 0 || pos != (comprLen + 10))
+ error("gzoffset err: wrong offset at end\n");
/* Trigger an error and clear it with gzclearerr */
PREFIX(gzfread)(uncompr, (size_t)-1, (size_t)-1, file);
PREFIX(gzerror)(file, &err);
- if (err == 0) {
- fprintf(stderr, "gzerror err: no error returned\n");
- exit(1);
- }
+ if (err == 0)
+ error("gzerror err: no error returned\n");
PREFIX(gzclearerr)(file);
PREFIX(gzerror)(file, &err);
- if (err != 0) {
- fprintf(stderr, "gzclearerr err: not zero %d\n", err);
- exit(1);
- }
+ if (err != 0)
+ error("gzclearerr err: not zero %d\n", err);
PREFIX(gzclose)(file);
- if (PREFIX(gzclose)(NULL) != Z_STREAM_ERROR) {
- fprintf(stderr, "gzclose unexpected return when handle null\n");
- exit(1);
- }
- (void)read;
+ if (PREFIX(gzclose)(NULL) != Z_STREAM_ERROR)
+ error("gzclose unexpected return when handle null\n");
+ Z_UNUSED(read);
#endif
}
@@ -302,12 +262,10 @@ void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr,
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad inflate\n");
- exit(1);
- } else {
+ if (strcmp((char*)uncompr, hello))
+ error("bad inflate\n");
+ else
printf("inflate(): %s\n", (char *)uncompr);
- }
}
static unsigned int diff;
@@ -349,29 +307,22 @@ void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *un
c_stream.avail_in = (unsigned int)uncomprLen;
err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate");
- if (c_stream.avail_in != 0) {
- fprintf(stderr, "deflate not greedy\n");
- exit(1);
- }
+ if (c_stream.avail_in != 0)
+ error("deflate not greedy\n");
/* Feed in already compressed data and switch to no compression: */
if (zng_params) {
#ifndef ZLIB_COMPAT
zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
- if (level != Z_BEST_SPEED) {
- fprintf(stderr, "Expected compression level Z_BEST_SPEED, got %d\n", level);
- exit(1);
- }
- if (strategy != Z_DEFAULT_STRATEGY) {
- fprintf(stderr, "Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy);
- exit(1);
- }
+ if (level != Z_BEST_SPEED)
+ error("Expected compression level Z_BEST_SPEED, got %d\n", level);
+ if (strategy != Z_DEFAULT_STRATEGY)
+ error("Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy);
level = Z_NO_COMPRESSION;
strategy = Z_DEFAULT_STRATEGY;
zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
#else
- fprintf(stderr, "test_large_deflate() called with zng_params=1 in compat mode\n");
- exit(1);
+ error("test_large_deflate() called with zng_params=1 in compat mode\n");
#endif
} else {
PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
@@ -388,20 +339,15 @@ void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *un
level = -1;
strategy = -1;
zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
- if (level != Z_NO_COMPRESSION) {
- fprintf(stderr, "Expected compression level Z_NO_COMPRESSION, got %d\n", level);
- exit(1);
- }
- if (strategy != Z_DEFAULT_STRATEGY) {
- fprintf(stderr, "Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy);
- exit(1);
- }
+ if (level != Z_NO_COMPRESSION)
+ error("Expected compression level Z_NO_COMPRESSION, got %d\n", level);
+ if (strategy != Z_DEFAULT_STRATEGY)
+ error("Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy);
level = Z_BEST_COMPRESSION;
strategy = Z_FILTERED;
zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
#else
- fprintf(stderr, "test_large_deflate() called with zng_params=1 in compat mode\n");
- exit(1);
+ error("test_large_deflate() called with zng_params=1 in compat mode\n");
#endif
} else {
PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
@@ -412,10 +358,8 @@ void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *un
CHECK_ERR(err, "deflate");
err = PREFIX(deflate)(&c_stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- fprintf(stderr, "deflate should report Z_STREAM_END\n");
- exit(1);
- }
+ if (err != Z_STREAM_END)
+ error("deflate should report Z_STREAM_END\n");
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
}
@@ -452,12 +396,10 @@ void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *un
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
- if (d_stream.total_out != 2*uncomprLen + diff) {
- fprintf(stderr, "bad large inflate: %" PRIu64 "\n", (uint64_t)d_stream.total_out);
- exit(1);
- } else {
+ if (d_stream.total_out != 2*uncomprLen + diff)
+ error("bad large inflate: %" PRIu64 "\n", (uint64_t)d_stream.total_out);
+ else
printf("large_inflate(): OK\n");
- }
}
/* ===========================================================================
@@ -525,10 +467,8 @@ void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, si
CHECK_ERR(err, "inflateSync");
err = PREFIX(inflate)(&d_stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- fprintf(stderr, "inflate should report Z_STREAM_END\n");
- exit(1);
- }
+ if (err != Z_STREAM_END)
+ error("inflate should report Z_STREAM_END\n");
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
@@ -562,10 +502,8 @@ void test_dict_deflate(unsigned char *compr, size_t comprLen) {
c_stream.avail_in = (unsigned int)strlen(hello)+1;
err = PREFIX(deflate)(&c_stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- fprintf(stderr, "deflate should report Z_STREAM_END\n");
- exit(1);
- }
+ if (err != Z_STREAM_END)
+ error("deflate should report Z_STREAM_END\n");
err = PREFIX(deflateEnd)(&c_stream);
CHECK_ERR(err, "deflateEnd");
}
@@ -575,6 +513,8 @@ void test_dict_deflate(unsigned char *compr, size_t comprLen) {
*/
void test_dict_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
int err;
+ uint8_t check_dictionary[MAX_DICTIONARY_SIZE];
+ uint32_t check_dictionary_len = 0;
PREFIX3(stream) d_stream; /* decompression stream */
strcpy((char*)uncompr, "garbage garbage garbage");
@@ -596,25 +536,35 @@ void test_dict_inflate(unsigned char *compr, size_t comprLen, unsigned char *unc
err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break;
if (err == Z_NEED_DICT) {
- if (d_stream.adler != dictId) {
- fprintf(stderr, "unexpected dictionary");
- exit(1);
- }
+ if (d_stream.adler != dictId)
+ error("unexpected dictionary");
err = PREFIX(inflateSetDictionary)(&d_stream, (const unsigned char*)dictionary,
(int)sizeof(dictionary));
}
CHECK_ERR(err, "inflate with dict");
}
+
+ err = PREFIX(inflateGetDictionary)(&d_stream, NULL, &check_dictionary_len);
+ CHECK_ERR(err, "inflateGetDictionary");
+#ifndef S390_DFLTCC_INFLATE
+ if (check_dictionary_len < sizeof(dictionary))
+ error("bad dictionary length\n");
+#endif
+
+ err = PREFIX(inflateGetDictionary)(&d_stream, check_dictionary, &check_dictionary_len);
+ CHECK_ERR(err, "inflateGetDictionary");
+#ifndef S390_DFLTCC_INFLATE
+ if (memcmp(dictionary, check_dictionary, sizeof(dictionary)) != 0)
+ error("bad dictionary\n");
+#endif
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
- if (strncmp((char*)uncompr, hello, sizeof(hello))) {
- fprintf(stderr, "bad inflate with dict\n");
- exit(1);
- } else {
+ if (strncmp((char*)uncompr, hello, sizeof(hello)))
+ error("bad inflate with dict\n");
+ else
printf("inflate with dictionary: %s\n", (char *)uncompr);
- }
}
/* ===========================================================================
@@ -734,10 +684,8 @@ void test_deflate_get_dict(unsigned char *compr, size_t comprLen) {
err = PREFIX(deflate)(&c_stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- fprintf(stderr, "deflate should report Z_STREAM_END\n");
- exit(1);
- }
+ if (err != Z_STREAM_END)
+ error("deflate should report Z_STREAM_END\n");
dictNew = calloc(256, 1);
dictLen = (unsigned int *)calloc(4, 1);
@@ -889,14 +837,10 @@ void test_deflate_prime(unsigned char *compr, size_t comprLen, unsigned char *un
err = PREFIX(inflateEnd)(&d_stream);
CHECK_ERR(err, "inflateEnd");
- if (strcmp((const char *)uncompr, hello) != 0) {
- fprintf(stderr, "bad deflatePrime\n");
- exit(1);
- }
-
- if (err == Z_OK) {
+ if (strcmp((const char *)uncompr, hello) != 0)
+ error("bad deflatePrime\n");
+ if (err == Z_OK)
printf("deflatePrime(): OK\n");
- }
}
/* ===========================================================================
@@ -909,10 +853,8 @@ void test_deflate_set_header(unsigned char *compr, size_t comprLen) {
size_t len = strlen(hello)+1;
- if (head == NULL) {
- printf("out of memory\n");
- exit(1);
- }
+ if (head == NULL)
+ error("out of memory\n");
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
@@ -923,11 +865,18 @@ void test_deflate_set_header(unsigned char *compr, size_t comprLen) {
CHECK_ERR(err, "deflateInit2");
head->text = 1;
+ head->comment = (uint8_t *)"comment";
+ head->name = (uint8_t *)"name";
+ head->hcrc = 1;
+ head->extra = (uint8_t *)"extra";
+ head->extra_len = (uint32_t)strlen((const char *)head->extra);
+
err = PREFIX(deflateSetHeader)(&c_stream, head);
CHECK_ERR(err, "deflateSetHeader");
if (err == Z_OK) {
printf("deflateSetHeader(): OK\n");
}
+ PREFIX(deflateBound)(&c_stream, (unsigned long)comprLen);
c_stream.next_in = (unsigned char *)hello;
c_stream.next_out = compr;
@@ -1016,18 +965,16 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "warning: different zlib version\n");
}
- printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
- PREFIX2(VERSION), PREFIX2(VERNUM), PREFIX(zlibCompileFlags)());
+ printf("zlib-ng version %s = 0x%08lx, compile flags = 0x%lx\n",
+ ZLIBNG_VERSION, ZLIBNG_VERNUM, PREFIX(zlibCompileFlags)());
compr = (unsigned char*)calloc((unsigned int)comprLen, 1);
uncompr = (unsigned char*)calloc((unsigned int)uncomprLen, 1);
/* compr and uncompr are cleared to avoid reading uninitialized
* data and to ensure that uncompr compresses well.
*/
- if (compr == NULL || uncompr == NULL) {
- printf("out of memory\n");
- exit(1);
- }
+ if (compr == NULL || uncompr == NULL)
+ error("out of memory\n");
test_compress(compr, comprLen, uncompr, uncomprLen);
diff --git a/src/zlib-ng/test/fuzz/CMakeLists.txt b/src/zlib-ng/test/fuzz/CMakeLists.txt
new file mode 100644
index 0000000..c21f9c1
--- /dev/null
+++ b/src/zlib-ng/test/fuzz/CMakeLists.txt
@@ -0,0 +1,44 @@
+cmake_minimum_required(VERSION 3.5.1)
+
+if(CMAKE_C_COMPILER_ID MATCHES "Clang")
+ enable_language(CXX)
+
+ if(DEFINED ENV{LIB_FUZZING_ENGINE})
+ set(FUZZING_ENGINE $ENV{LIB_FUZZING_ENGINE})
+ set(FUZZING_ENGINE_FOUND ON)
+ else()
+ find_library(FUZZING_ENGINE "FuzzingEngine")
+ endif()
+endif()
+
+set(FUZZERS
+ fuzzer_checksum
+ fuzzer_compress
+ fuzzer_example_small
+ fuzzer_example_large
+ fuzzer_example_flush
+ fuzzer_example_dict
+ )
+
+if(WITH_GZFILEOP)
+ list(APPEND FUZZERS fuzzer_minigzip)
+endif()
+
+foreach(FUZZER ${FUZZERS})
+ add_executable(${FUZZER} ${FUZZER}.c)
+
+ if(NOT FUZZING_ENGINE_FOUND)
+ target_sources(${FUZZER} PRIVATE standalone_fuzz_target_runner.c)
+ endif()
+
+ target_link_libraries(${FUZZER} zlibstatic)
+ if(FUZZING_ENGINE_FOUND)
+ target_link_libraries(${FUZZER} ${FUZZING_ENGINE})
+ endif()
+
+ if(ZLIB_ENABLE_TESTS)
+ file(GLOB FUZZER_TEST_FILES ${CMAKE_SOURCE_DIR}/*)
+ set(FUZZER_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:${FUZZER}> ${FUZZER_TEST_FILES})
+ add_test(NAME ${FUZZER} COMMAND ${FUZZER_COMMAND})
+ endif()
+endforeach()
diff --git a/src/zlib-ng/test/fuzz/checksum_fuzzer.c b/src/zlib-ng/test/fuzz/fuzzer_checksum.c
index ef99421..cedd284 100644
--- a/src/zlib-ng/test/fuzz/checksum_fuzzer.c
+++ b/src/zlib-ng/test/fuzz/fuzzer_checksum.c
@@ -1,10 +1,5 @@
#include <stdio.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
#include <assert.h>
-#include <stdlib.h>
-#include <inttypes.h>
#include "zbuild.h"
#ifdef ZLIB_COMPAT
@@ -24,7 +19,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen) {
/* Checksum with a buffer of size equal to the first byte in the input. */
uint32_t buffSize = data[0];
uint32_t offset = 0;
- uint32_t op[32];
+ uint32_t op;
/* Discard inputs larger than 1Mb. */
static size_t kMaxSize = 1024 * 1024;
@@ -36,28 +31,28 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen) {
++buffSize;
/* CRC32 */
- PREFIX(crc32_combine_gen)(op, buffSize);
+ op = PREFIX(crc32_combine_gen)(buffSize);
for (offset = 0; offset + buffSize <= dataLen; offset += buffSize) {
uint32_t crc3 = PREFIX(crc32_z)(crc0, data + offset, buffSize);
uint32_t crc4 = PREFIX(crc32_combine_op)(crc1, crc3, op);
crc1 = PREFIX(crc32_z)(crc1, data + offset, buffSize);
assert(crc1 == crc4);
- (void)crc1;
- (void)crc4;
+ Z_UNUSED(crc1);
+ Z_UNUSED(crc4);
}
crc1 = PREFIX(crc32_z)(crc1, data + offset, dataLen % buffSize);
crc2 = PREFIX(crc32_z)(crc2, data, dataLen);
assert(crc1 == crc2);
- (void)crc1;
- (void)crc2;
+ Z_UNUSED(crc1);
+ Z_UNUSED(crc2);
combine1 = PREFIX(crc32_combine)(crc1, crc2, (z_off_t)dataLen);
combine2 = PREFIX(crc32_combine)(crc1, crc1, (z_off_t)dataLen);
assert(combine1 == combine2);
/* Fast CRC32 combine. */
- PREFIX(crc32_combine_gen)(op, (z_off_t)dataLen);
+ op = PREFIX(crc32_combine_gen)((z_off_t)dataLen);
combine1 = PREFIX(crc32_combine_op)(crc1, crc2, op);
combine2 = PREFIX(crc32_combine_op)(crc2, crc1, op);
assert(combine1 == combine2);
@@ -73,13 +68,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen) {
adler2 = PREFIX(adler32_z)(adler2, data, dataLen);
assert(adler1 == adler2);
- (void)adler1;
- (void)adler2;
+ Z_UNUSED(adler1);
+ Z_UNUSED(adler2);
combine1 = PREFIX(adler32_combine)(adler1, adler2, (z_off_t)dataLen);
combine2 = PREFIX(adler32_combine)(adler1, adler1, (z_off_t)dataLen);
assert(combine1 == combine2);
- (void)combine1;
- (void)combine2;
+ Z_UNUSED(combine1);
+ Z_UNUSED(combine2);
/* This function must return 0. */
return 0;
diff --git a/src/zlib-ng/test/fuzz/compress_fuzzer.c b/src/zlib-ng/test/fuzz/fuzzer_compress.c
index 9712e88..71cdf99 100644
--- a/src/zlib-ng/test/fuzz/compress_fuzzer.c
+++ b/src/zlib-ng/test/fuzz/fuzzer_compress.c
@@ -1,10 +1,5 @@
#include <stdio.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
#include <assert.h>
-#include <stdlib.h>
-#include <inttypes.h>
#include "zbuild.h"
#ifdef ZLIB_COMPAT
diff --git a/src/zlib-ng/test/fuzz/example_dict_fuzzer.c b/src/zlib-ng/test/fuzz/fuzzer_example_dict.c
index 027c9a8..053a3e1 100644
--- a/src/zlib-ng/test/fuzz/example_dict_fuzzer.c
+++ b/src/zlib-ng/test/fuzz/fuzzer_example_dict.c
@@ -1,10 +1,5 @@
#include <stdio.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
#include <assert.h>
-#include <stdlib.h>
-#include <inttypes.h>
#include "zbuild.h"
#ifdef ZLIB_COMPAT
@@ -42,13 +37,13 @@ void test_dict_deflate(unsigned char **compr, size_t *comprLen) {
int method = Z_DEFLATED; /* The deflate compression method (the only one
supported in this version) */
- int windowBits = 8 + data[0] % 8; /* The windowBits parameter is the base
+ int windowBits = 8 + data[(dataLen > 1) ? 1:0] % 8; /* The windowBits parameter is the base
two logarithm of the window size (the size of the history buffer). It
should be in the range 8..15 for this version of the library. */
- int memLevel = 1 + data[0] % 9; /* memLevel=1 uses minimum memory but is
+ int memLevel = 1 + data[(dataLen > 2) ? 2:0] % 9; /* memLevel=1 uses minimum memory but is
slow and reduces compression ratio; memLevel=9 uses maximum memory for
optimal speed. */
- int strategy = data[0] % 5; /* [0..4]
+ int strategy = data[(dataLen > 3) ? 3:0] % 5; /* [0..4]
#define Z_FILTERED 1
#define Z_HUFFMAN_ONLY 2
#define Z_RLE 3
diff --git a/src/zlib-ng/test/fuzz/example_flush_fuzzer.c b/src/zlib-ng/test/fuzz/fuzzer_example_flush.c
index 81ec7e3..baa6988 100644
--- a/src/zlib-ng/test/fuzz/example_flush_fuzzer.c
+++ b/src/zlib-ng/test/fuzz/fuzzer_example_flush.c
@@ -1,10 +1,5 @@
#include <stdio.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
#include <assert.h>
-#include <stdlib.h>
-#include <inttypes.h>
#include "zbuild.h"
#ifdef ZLIB_COMPAT
diff --git a/src/zlib-ng/test/fuzz/example_large_fuzzer.c b/src/zlib-ng/test/fuzz/fuzzer_example_large.c
index bd27a84..4114597 100644
--- a/src/zlib-ng/test/fuzz/example_large_fuzzer.c
+++ b/src/zlib-ng/test/fuzz/fuzzer_example_large.c
@@ -1,9 +1,5 @@
#include <stdio.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
#include <assert.h>
-#include <stdlib.h>
#include <inttypes.h>
#include "zbuild.h"
diff --git a/src/zlib-ng/test/fuzz/example_small_fuzzer.c b/src/zlib-ng/test/fuzz/fuzzer_example_small.c
index d02a812..e59c720 100644
--- a/src/zlib-ng/test/fuzz/example_small_fuzzer.c
+++ b/src/zlib-ng/test/fuzz/fuzzer_example_small.c
@@ -1,10 +1,5 @@
#include <stdio.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
#include <assert.h>
-#include <stdlib.h>
-#include <inttypes.h>
#include "zbuild.h"
#ifdef ZLIB_COMPAT
diff --git a/src/zlib-ng/test/fuzz/minigzip_fuzzer.c b/src/zlib-ng/test/fuzz/fuzzer_minigzip.c
index 7c5d3ef..819148d 100644
--- a/src/zlib-ng/test/fuzz/minigzip_fuzzer.c
+++ b/src/zlib-ng/test/fuzz/fuzzer_minigzip.c
@@ -12,9 +12,6 @@
* real thing.
*/
-#define _POSIX_SOURCE 1 /* This file needs POSIX for fileno(). */
-#define _POSIX_C_SOURCE 200112 /* For snprintf(). */
-
#include "zbuild.h"
#ifdef ZLIB_COMPAT
# include "zlib.h"
@@ -23,8 +20,6 @@
#endif
#include <stdio.h>
#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
#ifdef USE_MMAP
# include <sys/types.h>
@@ -265,7 +260,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen) {
snprintf(outmode, sizeof(outmode), "%s", "wb");
/* Compression level: [0..9]. */
- outmode[2] = data[0] % 10;
+ outmode[2] = '0' + (data[0] % 10);
switch (data[dataLen-1] % 6) {
default:
@@ -295,7 +290,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen) {
}
file_compress(inFileName, outmode);
- file_uncompress(outFileName);
+
+ /* gzopen does not support reading in direct mode */
+ if (outmode[3] == 'T')
+ inFileName = outFileName;
+ else
+ file_uncompress(outFileName);
/* Check that the uncompressed file matches the input data. */
in = fopen(inFileName, "rb");
diff --git a/src/zlib-ng/test/fuzz/standalone_fuzz_target_runner.c b/src/zlib-ng/test/fuzz/standalone_fuzz_target_runner.c
index a291b48..810a560 100644
--- a/src/zlib-ng/test/fuzz/standalone_fuzz_target_runner.c
+++ b/src/zlib-ng/test/fuzz/standalone_fuzz_target_runner.c
@@ -1,6 +1,7 @@
#include <assert.h>
#include <stdio.h>
-#include <stdlib.h>
+
+#include "zbuild.h"
extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size);
@@ -28,7 +29,7 @@ int main(int argc, char **argv) {
free(buf);
err = fclose(f);
assert(err == 0);
- (void)err;
+ Z_UNUSED(err);
fprintf(stderr, "Done: %s: (%d bytes)\n", argv[i], (int)n_read);
}
diff --git a/src/zlib-ng/test/gh1235.c b/src/zlib-ng/test/gh1235.c
new file mode 100644
index 0000000..472282d
--- /dev/null
+++ b/src/zlib-ng/test/gh1235.c
@@ -0,0 +1,39 @@
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include "zutil.h"
+
+int main(void) {
+ unsigned char plain[32];
+ unsigned char compressed[130];
+ PREFIX3(stream) strm;
+ int bound;
+ z_size_t bytes;
+
+ for (int i = 0; i <= 32; i++) {
+ memset(plain, 6, i);
+ memset(&strm, 0, sizeof(strm));
+ PREFIX(deflateInit2)(&strm, 0, 8, 31, 1, Z_DEFAULT_STRATEGY);
+ bound = PREFIX(deflateBound)(&strm, i);
+ strm.next_in = plain;
+ strm.next_out = compressed;
+ strm.avail_in = i;
+ strm.avail_out = sizeof(compressed);
+ if (PREFIX(deflate)(&strm, Z_FINISH) != Z_STREAM_END) return -1;
+ if (strm.avail_in != 0) return -1;
+ printf("bytes = %2i, deflateBound = %2i, total_out = %2zi\n", i, bound, strm.total_out);
+ if (bound < strm.total_out) return -1;
+ if (PREFIX(deflateEnd)(&strm) != Z_OK) return -1;
+ }
+ for (int i = 0; i <= 32; i++) {
+ bytes = sizeof(compressed);
+ for (int j = 0; j < i; j++) {
+ plain[j] = j;
+ }
+ bound = PREFIX(compressBound)(i);
+ if (PREFIX(compress2)(compressed, &bytes, plain, i, 1) != Z_OK) return -1;
+ printf("bytes = %2i, compressBound = %2i, total_out = %2zi\n", i, bound, (size_t)bytes);
+ if (bytes > bound) return -1;
+ }
+ return 0;
+}
diff --git a/src/zlib-ng/test/hash_head_0.c b/src/zlib-ng/test/hash_head_0.c
deleted file mode 100644
index 128ae34..0000000
--- a/src/zlib-ng/test/hash_head_0.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Generated by fuzzing - test hash_head == 0 handling. */
-
-#include "zbuild.h"
-#ifdef ZLIB_COMPAT
-# include "zlib.h"
-#else
-# include "zlib-ng.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-int main() {
- PREFIX3(stream) strm;
- memset(&strm, 0, sizeof(strm));
-
- int ret = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, -15, 4, Z_HUFFMAN_ONLY);
- if (ret != Z_OK) {
- fprintf(stderr, "deflateInit2() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
-
- unsigned char next_in[9698];
- memset(next_in, 0x30, sizeof(next_in));
- next_in[8193] = 0x00;
- next_in[8194] = 0x00;
- next_in[8195] = 0x00;
- next_in[8199] = 0x8a;
- strm.next_in = next_in;
- unsigned char next_out[21572];
- strm.next_out = next_out;
-
- strm.avail_in = 0;
- strm.avail_out = 1348;
- ret = PREFIX(deflateParams(&strm, 3, Z_FILTERED));
- if (ret != Z_OK) {
- fprintf(stderr, "deflateParams() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
-
- strm.avail_in = 6728;
- strm.avail_out = 2696;
- ret = PREFIX(deflate(&strm, Z_SYNC_FLUSH));
- if (ret != Z_OK) {
- fprintf(stderr, "deflate() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
-
- strm.avail_in = 15;
- strm.avail_out = 1348;
- ret = PREFIX(deflateParams(&strm, 9, Z_FILTERED));
- if (ret != Z_OK) {
- fprintf(stderr, "deflateParams() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
-
- strm.avail_in = 1453;
- strm.avail_out = 1348;
- ret = PREFIX(deflate(&strm, Z_FULL_FLUSH));
- if (ret != Z_OK) {
- fprintf(stderr, "deflate() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
-
- strm.avail_in = next_in + sizeof(next_in) - strm.next_in;
- strm.avail_out = next_out + sizeof(next_out) - strm.next_out;
- ret = PREFIX(deflate)(&strm, Z_FINISH);
- if (ret != Z_STREAM_END) {
- fprintf(stderr, "deflate() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
- uint32_t compressed_size = strm.next_out - next_out;
-
- ret = PREFIX(deflateEnd)(&strm);
- if (ret != Z_OK) {
- fprintf(stderr, "deflateEnd() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
-
- memset(&strm, 0, sizeof(strm));
- ret = PREFIX(inflateInit2)(&strm, -15);
- if (ret != Z_OK) {
- fprintf(stderr, "inflateInit2() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
-
- strm.next_in = next_out;
- strm.avail_in = compressed_size;
- unsigned char uncompressed[sizeof(next_in)];
- strm.next_out = uncompressed;
- strm.avail_out = sizeof(uncompressed);
-
- ret = PREFIX(inflate)(&strm, Z_NO_FLUSH);
- if (ret != Z_STREAM_END) {
- fprintf(stderr, "inflate() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
-
- ret = PREFIX(inflateEnd)(&strm);
- if (ret != Z_OK) {
- fprintf(stderr, "inflateEnd() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
-
- if (memcmp(uncompressed, next_in, sizeof(uncompressed)) != 0) {
- fprintf(stderr, "Uncompressed data differs from the original\n");
- return EXIT_FAILURE;
- }
-}
diff --git a/src/zlib-ng/test/infcover.c b/src/zlib-ng/test/infcover.c
index 3466b20..974185d 100644
--- a/src/zlib-ng/test/infcover.c
+++ b/src/zlib-ng/test/infcover.c
@@ -11,17 +11,11 @@
#undef NDEBUG
#include <assert.h>
#include <inttypes.h>
-#include <stdint.h>
/* get definition of internal structure so we can mess with it (see pull()),
and so we can call inflate_trees() (see cover5()) */
-#define ZLIB_INTERNAL
#include "zbuild.h"
-#ifdef ZLIB_COMPAT
-# include "zlib.h"
-#else
-# include "zlib-ng.h"
-#endif
+#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
@@ -348,7 +342,7 @@ static void inf(char *hex, char *what, unsigned step, int win, unsigned len, int
ret = PREFIX(inflateReset2)(&strm, -8); assert(ret == Z_OK);
ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK);
mem_done(&strm, what);
- (void)err;
+ Z_UNUSED(err);
}
/* cover all of the lines in inflate.c up to inflate() */
@@ -386,7 +380,7 @@ static void cover_support(void) {
ret = PREFIX(inflateInit)(&strm); assert(ret == Z_OK);
ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK);
fputs("inflate built-in memory routines\n", stderr);
- (void)ret;
+ Z_UNUSED(ret);
}
/* cover all inflate() header and trailer cases and code after inflate() */
@@ -470,7 +464,7 @@ static unsigned pull(void *desc, z_const unsigned char **buf) {
static int push(void *desc, unsigned char *buf, unsigned len) {
buf += len;
- (void)buf;
+ Z_UNUSED(buf);
return desc != NULL; /* force error if desc not null */
}
@@ -511,7 +505,7 @@ static void cover_back(void) {
assert(ret == Z_OK);
ret = PREFIX(inflateBackEnd)(&strm); assert(ret == Z_OK);
fputs("inflateBack built-in memory routines\n", stderr);
- (void)ret;
+ Z_UNUSED(ret);
}
/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */
@@ -647,7 +641,7 @@ static void cover_trees(void) {
ret = zng_inflate_table(DISTS, lens, 16, &next, &bits, work);
assert(ret == 1);
fputs("inflate_table not enough errors\n", stderr);
- (void)ret;
+ Z_UNUSED(ret);
}
/* cover remaining inffast.c decoding and window copying */
diff --git a/src/zlib-ng/test/minideflate.c b/src/zlib-ng/test/minideflate.c
index 3925168..148a277 100644
--- a/src/zlib-ng/test/minideflate.c
+++ b/src/zlib-ng/test/minideflate.c
@@ -4,34 +4,24 @@
*/
#include <stdio.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
#include <assert.h>
-#include <stdlib.h>
-#include <inttypes.h>
#include "zbuild.h"
-#ifdef ZLIB_COMPAT
-# include "zlib.h"
-#else
-# include "zlib-ng.h"
-#endif
+#include "zutil.h"
#if defined(_WIN32) || defined(__CYGWIN__)
# include <fcntl.h>
# include <io.h>
+# include <string.h>
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+# ifdef _MSC_VER
+# define strcasecmp _stricmp
+# endif
#else
+# include <strings.h>
# define SET_BINARY_MODE(file)
#endif
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-
#define CHECK_ERR(err, msg) { \
if (err != Z_OK) { \
fprintf(stderr, "%s error: %d\n", msg, err); \
@@ -39,6 +29,9 @@
} \
}
+/* Default read/write i/o buffer size based on GZBUFSIZE */
+#define BUFSIZE 131072
+
/* ===========================================================================
* deflate() using specialized parameters
*/
@@ -67,6 +60,8 @@ void deflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_
c_stream.opaque = (void *)0;
c_stream.total_in = 0;
c_stream.total_out = 0;
+ c_stream.next_out = write_buf;
+ c_stream.avail_out = write_buf_size;
err = PREFIX(deflateInit2)(&c_stream, level, Z_DEFLATED, window_bits, mem_level, strategy);
CHECK_ERR(err, "deflateInit2");
@@ -79,11 +74,9 @@ void deflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_
break;
c_stream.next_in = (z_const uint8_t *)read_buf;
- c_stream.next_out = write_buf;
c_stream.avail_in = read;
do {
- c_stream.avail_out = write_buf_size;
err = PREFIX(deflate)(&c_stream, flush);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "deflate");
@@ -91,6 +84,7 @@ void deflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_
if (c_stream.next_out == write_buf + write_buf_size) {
fwrite(write_buf, 1, write_buf_size, fout);
c_stream.next_out = write_buf;
+ c_stream.avail_out = write_buf_size;
}
} while (c_stream.next_in < read_buf + read);
} while (err == Z_OK);
@@ -102,13 +96,13 @@ void deflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_
if (c_stream.next_out == write_buf + write_buf_size) {
fwrite(write_buf, 1, write_buf_size, fout);
c_stream.next_out = write_buf;
+ c_stream.avail_out = write_buf_size;
}
- c_stream.avail_out = write_buf_size;
err = PREFIX(deflate)(&c_stream, Z_FINISH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "deflate");
- } while (err == Z_OK);
+ } while (1);
}
/* Output remaining data in write buffer */
@@ -152,6 +146,8 @@ void inflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_
d_stream.opaque = (void *)0;
d_stream.total_in = 0;
d_stream.total_out = 0;
+ d_stream.next_out = write_buf;
+ d_stream.avail_out = write_buf_size;
err = PREFIX(inflateInit2)(&d_stream, window_bits);
CHECK_ERR(err, "inflateInit2");
@@ -164,18 +160,17 @@ void inflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_
break;
d_stream.next_in = (z_const uint8_t *)read_buf;
- d_stream.next_out = write_buf;
d_stream.avail_in = read;
do {
- d_stream.avail_out = write_buf_size;
err = PREFIX(inflate)(&d_stream, flush);
if (err == Z_STREAM_END) break;
- CHECK_ERR(err, "deflate");
+ CHECK_ERR(err, "inflate");
if (d_stream.next_out == write_buf + write_buf_size) {
fwrite(write_buf, 1, write_buf_size, fout);
d_stream.next_out = write_buf;
+ d_stream.avail_out = write_buf_size;
}
} while (d_stream.next_in < read_buf + read);
} while (err == Z_OK);
@@ -187,13 +182,13 @@ void inflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_
if (d_stream.next_out == write_buf + write_buf_size) {
fwrite(write_buf, 1, write_buf_size, fout);
d_stream.next_out = write_buf;
+ d_stream.avail_out = write_buf_size;
}
- d_stream.avail_out = write_buf_size;
err = PREFIX(inflate)(&d_stream, Z_FINISH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "inflate");
- } while (err == Z_OK);
+ } while (1);
}
/* Output remaining data in write buffer */
@@ -209,15 +204,19 @@ void inflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_
}
void show_help(void) {
- printf("Usage: minideflate [-c] [-f|-h|-R|-F] [-m level] [-r/-t size] [-s flush] [-w bits] [-0 to -9] [input file]\n\n" \
+ printf("Usage: minideflate [-c][-d][-k] [-f|-h|-R|-F] [-m level] [-r/-t size] [-s flush] [-w bits] [-0 to -9] [input file]\n\n" \
" -c : write to standard output\n" \
" -d : decompress\n" \
+ " -k : keep input file\n" \
" -f : compress with Z_FILTERED\n" \
" -h : compress with Z_HUFFMAN_ONLY\n" \
" -R : compress with Z_RLE\n" \
" -F : compress with Z_FIXED\n" \
" -m : memory level (1 to 8)\n" \
- " -w : window bits (8 to 15 for gzip, -8 to -15 for zlib)\n" \
+ " -w : window bits..\n" \
+ " : -1 to -15 for raw deflate\n"
+ " : 0 to 15 for deflate (adler32)\n"
+ " : 16 to 31 for gzip (crc32)\n"
" -s : flush type (0 to 5)\n" \
" -r : read buffer size\n" \
" -t : write buffer size\n" \
@@ -227,18 +226,24 @@ void show_help(void) {
int main(int argc, char **argv) {
int32_t i;
int32_t mem_level = DEF_MEM_LEVEL;
- int32_t window_bits = MAX_WBITS;
+ int32_t window_bits = INT32_MAX;
int32_t strategy = Z_DEFAULT_STRATEGY;
int32_t level = Z_DEFAULT_COMPRESSION;
- int32_t read_buf_size = 4096;
- int32_t write_buf_size = 4096;
+ int32_t read_buf_size = BUFSIZE;
+ int32_t write_buf_size = BUFSIZE;
int32_t flush = Z_NO_FLUSH;
uint8_t copyout = 0;
uint8_t uncompr = 0;
- char out_file[320];
+ uint8_t keep = 0;
FILE *fin = stdin;
FILE *fout = stdout;
+
+ if (argc == 1) {
+ show_help();
+ return 64; /* EX_USAGE */
+ }
+
for (i = 1; i < argc; i++) {
if ((strcmp(argv[i], "-m") == 0) && (i + 1 < argc))
mem_level = atoi(argv[++i]);
@@ -254,8 +259,12 @@ int main(int argc, char **argv) {
copyout = 1;
else if (strcmp(argv[i], "-d") == 0)
uncompr = 1;
+ else if (strcmp(argv[i], "-k") == 0)
+ keep = 1;
else if (strcmp(argv[i], "-f") == 0)
strategy = Z_FILTERED;
+ else if (strcmp(argv[i], "-F") == 0)
+ strategy = Z_FIXED;
else if (strcmp(argv[i], "-h") == 0)
strategy = Z_HUFFMAN_ONLY;
else if (strcmp(argv[i], "-R") == 0)
@@ -268,12 +277,13 @@ int main(int argc, char **argv) {
} else if (argv[i][0] == '-') {
show_help();
return 64; /* EX_USAGE */
- } else
+ } else
break;
}
SET_BINARY_MODE(stdin);
SET_BINARY_MODE(stdout);
+
if (i != argc) {
fin = fopen(argv[i], "rb+");
if (fin == NULL) {
@@ -281,15 +291,53 @@ int main(int argc, char **argv) {
exit(1);
}
if (!copyout) {
- snprintf(out_file, sizeof(out_file), "%s%s", argv[i], (window_bits < 0) ? ".zz" : ".gz");
+ char *out_file = (char *)calloc(1, strlen(argv[i]) + 6);
+ if (out_file == NULL) {
+ fprintf(stderr, "Not enough memory\n");
+ exit(1);
+ }
+ strcat(out_file, argv[i]);
+ if (!uncompr) {
+ if (window_bits < 0) {
+ strcat(out_file, ".zraw");
+ } else if (window_bits > MAX_WBITS) {
+ strcat(out_file, ".gz");
+ } else {
+ strcat(out_file, ".z");
+ }
+ } else {
+ char *out_ext = strrchr(out_file, '.');
+ if (out_ext != NULL) {
+ if (strcasecmp(out_ext, ".zraw") == 0 && window_bits == INT32_MAX) {
+ fprintf(stderr, "Must specify window bits for raw deflate stream\n");
+ exit(1);
+ }
+ *out_ext = 0;
+ }
+ }
fout = fopen(out_file, "wb");
if (fout == NULL) {
fprintf(stderr, "Failed to open file: %s\n", out_file);
exit(1);
}
+ free(out_file);
}
}
+ if (window_bits == INT32_MAX) {
+ window_bits = MAX_WBITS;
+ /* Auto-detect wrapper for inflateInit */
+ if (uncompr)
+ window_bits += 32;
+ }
+
+ if (window_bits == INT32_MAX) {
+ window_bits = MAX_WBITS;
+ /* Auto-detect wrapper for inflateInit */
+ if (uncompr)
+ window_bits += 32;
+ }
+
if (uncompr) {
inflate_params(fin, fout, read_buf_size, write_buf_size, window_bits, flush);
} else {
@@ -298,6 +346,9 @@ int main(int argc, char **argv) {
if (fin != stdin) {
fclose(fin);
+ if (!copyout && !keep) {
+ unlink(argv[i]);
+ }
}
if (fout != stdout) {
fclose(fout);
diff --git a/src/zlib-ng/test/minigzip.c b/src/zlib-ng/test/minigzip.c
index 29729f3..34fc664 100644
--- a/src/zlib-ng/test/minigzip.c
+++ b/src/zlib-ng/test/minigzip.c
@@ -12,9 +12,6 @@
* real thing.
*/
-#define _POSIX_SOURCE 1 /* This file needs POSIX for fdopen(). */
-#define _POSIX_C_SOURCE 200112 /* For snprintf(). */
-
#include "zbuild.h"
#ifdef ZLIB_COMPAT
# include "zlib.h"
diff --git a/src/zlib-ng/test/pigz/CMakeLists.txt b/src/zlib-ng/test/pigz/CMakeLists.txt
new file mode 100644
index 0000000..0d5bc86
--- /dev/null
+++ b/src/zlib-ng/test/pigz/CMakeLists.txt
@@ -0,0 +1,212 @@
+# CMakeLists.txt -- Build madler/pigz against zlib variant
+
+# Copyright (C) 2021 Nathan Moinvaziri
+# Licensed under the Zlib license, see LICENSE.md for details
+
+# By default pigz will be linked against the system zlib and
+# pthread libraries if installed.
+
+# For compilation on Windows download and use shim:
+# https://github.com/zlib-ng/pigzbench/tree/master/pigz/win
+
+# Optional Variables
+# WITH_CODE_COVERAGE - Enable code coverage reporting
+# WITH_THREADS - Enable threading support
+# PIGZ_ENABLE_TESTS - Enable adding unit tests
+# PIGZ_VERSION - Set the version of pigz to build
+# ZLIB_ROOT - Path to the zlib source directory
+# PTHREADS4W_ROOT - Path to pthreads4w source directory on Windows.
+# If not specified then threading will be disabled.
+
+cmake_minimum_required(VERSION 3.11)
+
+include(CheckCCompilerFlag)
+include(FeatureSummary)
+include(FetchContent)
+
+include(../../cmake/detect-coverage.cmake)
+
+option(WITH_CODE_COVERAGE "Enable code coverage reporting" OFF)
+option(WITH_THREADS "Enable threading support" ON)
+option(PIGZ_ENABLE_TESTS "Build unit tests" ON)
+option(PIGZ_VERSION "Set the version of pigz to build" "")
+
+project(pigz LANGUAGES C)
+
+# Set code coverage compiler flags
+if(WITH_CODE_COVERAGE)
+ add_code_coverage()
+endif()
+
+# Compiler definitions
+if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ add_definitions(-fno-caret-diagnostics)
+elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5.0)
+ add_definitions(-Wno-unused-result)
+ endif()
+ if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8.0)
+ add_definitions(-fno-diagnostics-show-caret)
+ endif()
+elseif(WIN32)
+ add_definitions(-D_TIMESPEC_DEFINED)
+ if(MSVC)
+ add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
+ endif()
+endif()
+
+# Fetch pigz source code from official repository
+if(PIGZ_VERSION STREQUAL "")
+ set(PIGZ_TAG master)
+else()
+ set(PIGZ_TAG ${PIGZ_VERSION})
+endif()
+FetchContent_Declare(pigz
+ GIT_REPOSITORY https://github.com/madler/pigz.git
+ GIT_TAG ${PIGZ_TAG})
+FetchContent_MakeAvailable(pigz)
+FetchContent_GetProperties(pigz)
+
+if(NOT pigz_POPULATED)
+ FetchContent_Populate(pigz)
+endif()
+
+set(PIGZ_SRCS
+ ${pigz_SOURCE_DIR}/pigz.c
+ ${pigz_SOURCE_DIR}/try.c)
+
+set(PIGZ_HDRS
+ ${pigz_SOURCE_DIR}/try.h)
+
+add_executable(${PROJECT_NAME} ${PIGZ_SRCS} ${PIGZ_HDRS})
+add_definitions(-DNOZOPFLI)
+if(WIN32)
+ target_include_directories(${PROJECT_NAME} PRIVATE win)
+endif()
+
+# Find and link against pthreads or pthreads4w
+if(WITH_THREADS)
+ if(WIN32)
+ if(DEFINED PTHREADS4W_ROOT)
+ set(CLEANUP_STYLE VC)
+ set(PTHREADS4W_VERSION 3)
+
+ add_subdirectory(${PTHREADS4W_ROOT} ${PTHREADS4W_ROOT} EXCLUDE_FROM_ALL)
+ target_link_libraries(${PROJECT_NAME} pthreadVC3)
+ target_include_directories(${PROJECT_NAME} PRIVATE ${PTHREADS4W_ROOT})
+ else()
+ message(WARNING "Missing pthreads4w root directory")
+ set(WITH_THREADS OFF)
+ endif()
+ else()
+ find_package(Threads REQUIRED)
+ target_link_libraries(${PROJECT_NAME} Threads::Threads)
+ if(NOT APPLE)
+ target_link_libraries(${PROJECT_NAME} m)
+ endif()
+ endif()
+endif()
+
+# Disable threading support
+if(NOT WITH_THREADS)
+ add_definitions(-DNOTHREAD)
+else()
+ set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY SOURCES
+ ${pigz_SOURCE_DIR}/yarn.c
+ ${pigz_SOURCE_DIR}/yarn.h)
+endif()
+
+# Find and link against zlib
+if(NOT DEFINED ZLIB_ROOT)
+ find_package(Zlib REQUIRED)
+endif()
+
+set(ZLIB_COMPAT ON)
+set(ZLIB_ENABLE_TESTS OFF)
+
+add_subdirectory(${ZLIB_ROOT} ${CMAKE_CURRENT_BINARY_DIR}/zlib EXCLUDE_FROM_ALL)
+
+if(NOT DEFINED BUILD_SHARED_LIBS OR NOT BUILD_SHARED_LIBS)
+ set(ZLIB_TARGET zlibstatic)
+else()
+ set(ZLIB_TARGET zlib)
+endif()
+
+target_include_directories(${PROJECT_NAME} PRIVATE ${ZLIB_ROOT} ${CMAKE_CURRENT_BINARY_DIR}/zlib)
+target_link_libraries(${PROJECT_NAME} ${ZLIB_TARGET})
+
+if(NOT SKIP_INSTALL_BINARIES AND NOT SKIP_INSTALL_ALL)
+ install(TARGETS ${PROJECT_NAME} DESTINATION "bin")
+endif()
+
+# Add unit tests
+if(PIGZ_ENABLE_TESTS)
+ enable_testing()
+
+ set(PIGZ_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:pigz>)
+
+ macro(test_pigz name path)
+ # Construct compression arguments for pigz
+ set(compress_args -k -c)
+ foreach(extra_arg IN ITEMS "${ARGN}")
+ list(APPEND compress_args ${extra_arg})
+ endforeach()
+
+ # Create unique friendly string for test
+ string(REPLACE ";" "" arg_list "${ARGN}")
+ string(REPLACE " " "" arg_list "${arg_list}")
+ string(REPLACE "-" "" arg_list "${arg_list}")
+
+ set(test_id pigz-${name}-${arg_list})
+
+ if(NOT TEST ${test_id})
+ add_test(NAME ${test_id}
+ COMMAND ${CMAKE_COMMAND}
+ "-DTARGET=${PIGZ_COMMAND}"
+ "-DCOMPRESS_ARGS=${compress_args}"
+ "-DDECOMPRESS_ARGS=-d;-c"
+ -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${path}
+ -DTEST_NAME=${test_id}
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/test-compress.cmake)
+ endif()
+ endmacro()
+
+ set(TEST_CONFIGS
+ -U # RLE compression
+ #-H # Z_HUFFMAN_ONLY (broken in 2.6)
+ -0 # No compression
+ -1 # Deflate quick
+ -4 # Deflate medium (lazy matches)
+ -6 # Deflate medium
+ -9 # Deflate slow
+ )
+
+ file(GLOB_RECURSE TEST_FILE_PATHS
+ LIST_DIRECTORIES false
+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../data/*)
+
+ foreach(TEST_FILE_PATH ${TEST_FILE_PATHS})
+ if("${TEST_FILE_PATH}" MATCHES ".gz$" OR "${TEST_FILE_PATH}" MATCHES ".out$" OR
+ "${TEST_FILE_PATH}" MATCHES "/.git/" OR "${TEST_FILE_PATH}" MATCHES ".md$")
+ continue()
+ endif()
+ foreach(TEST_CONFIG ${TEST_CONFIGS})
+ get_filename_component(TEST_NAME ${TEST_FILE_PATH} NAME)
+ if (TEST_NAME STREQUAL "")
+ continue()
+ endif()
+ test_pigz(${TEST_NAME} ${TEST_FILE_PATH} ${TEST_CONFIG})
+ endforeach()
+ endforeach()
+
+ set(GH979_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:pigz>
+ -d -k -f ${CMAKE_CURRENT_SOURCE_DIR}/../GH-979/pigz-2.6.tar.gz)
+ add_test(NAME GH-979 COMMAND ${GH979_COMMAND})
+endif()
+
+add_feature_info(WITH_CODE_COVERAGE WITH_CODE_COVERAGE "Enable code coverage reporting")
+add_feature_info(WITH_THREADS WITH_THREADS "Enable threading support")
+add_feature_info(PIGZ_ENABLE_TESTS PIGZ_ENABLE_TESTS "Build unit tests")
+
+FEATURE_SUMMARY(WHAT ALL INCLUDE_QUIET_PACKAGES)
diff --git a/src/zlib-ng/test/switchlevels.c b/src/zlib-ng/test/switchlevels.c
index 0f85011..a065dbc 100644
--- a/src/zlib-ng/test/switchlevels.c
+++ b/src/zlib-ng/test/switchlevels.c
@@ -10,8 +10,6 @@
#endif
#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#if defined(_WIN32) || defined(__CYGWIN__)
# include <fcntl.h>
@@ -66,7 +64,7 @@ static int compress_chunk(PREFIX3(stream) *strm, int level, int size, int last)
goto done;
}
- compsize = 100 + 2 * PREFIX(deflateBound)(strm, size);
+ compsize = PREFIX(deflateBound)(strm, size);
buf = malloc(size + compsize);
if (buf == NULL) {
fprintf(stderr, "Out of memory\n");
diff --git a/src/zlib-ng/test/testCVEinputs.sh b/src/zlib-ng/test/testCVEinputs.sh
deleted file mode 100755
index 84f6b31..0000000
--- a/src/zlib-ng/test/testCVEinputs.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-TESTDIR="$(dirname "$0")"
-
-# check for QEMU if QEMU_RUN is set
-if [ ! -z "${QEMU_RUN}" ]; then
- QEMU_VERSION=$(${QEMU_RUN} --version 2> /dev/null)
- if [ -z "${QEMU_VERSION}" ]; then
- echo "**** You need QEMU to run tests on non-native platform"
- exit 1
- fi
-fi
-
-CVEs="CVE-2002-0059 CVE-2004-0797 CVE-2005-1849 CVE-2005-2096"
-
-for CVE in $CVEs; do
- fail=0
- for testcase in ${TESTDIR}/${CVE}/*.gz; do
- ${QEMU_RUN} ../minigzip${EXE} -d < "$testcase"
- # we expect that a 1 error code is OK
- # for a vulnerable failure we'd expect 134 or similar
- if [ $? -ne 1 ] && [ $? -ne 0 ]; then
- fail=1
- fi
- done
- if [ $fail -eq 0 ]; then
- echo " --- zlib not vulnerable to $CVE ---";
- else
- echo " --- zlib VULNERABLE to $CVE ---"; exit 1;
- fi
-done
diff --git a/src/zlib-ng/test/adler32_test.c b/src/zlib-ng/test/test_adler32.cc
index f681877..fa113da 100644
--- a/src/zlib-ng/test/adler32_test.c
+++ b/src/zlib-ng/test/test_adler32.cc
@@ -1,4 +1,4 @@
-/* adler32_test.c -- unit test for adler32 in the zlib compression library
+/* test_adler32.c -- unit test for adler32 in the zlib compression library
* Copyright (C) 2020 IBM Corporation
* Author: Rogerio Alves <rcardoso@linux.ibm.com>
* For conditions of distribution and use, see copyright notice in zlib.h
@@ -8,30 +8,20 @@
#include <string.h>
#include <stdlib.h>
-#include "zbuild.h"
-#ifdef ZLIB_COMPAT
-# include "zlib.h"
-#else
-# include "zlib-ng.h"
-#endif
+extern "C" {
+# include "zbuild.h"
+# include "cpu_features.h"
+}
+
+#include <gtest/gtest.h>
typedef struct {
- uint32_t line;
uint32_t adler;
const uint8_t *buf;
uint32_t len;
uint32_t expect;
} adler32_test;
-void test_adler32(uint32_t adler, const uint8_t *buf, uint32_t len, uint32_t chk, uint32_t line) {
- uint32_t res = PREFIX(adler32)(adler, buf, len);
- if (res != chk) {
- fprintf(stderr, "FAIL [%d]: adler32 returned 0x%08X expected 0x%08X\n",
- line, res, chk);
- exit(1);
- }
-}
-
static const uint8_t long_string[5552] = {
'q','j','d','w','q','4','8','m','B','u','k','J','V','U','z','V','V','f','M','j','i','q','S','W','L','5','G','n','F','S','P','Q',
'Q','D','i','6','m','E','9','Z','a','A','P','h','9','d','r','b','5','t','X','U','U','L','w','q','e','k','E','H','6','W','7','k',
@@ -209,157 +199,191 @@ static const uint8_t long_string[5552] = {
'y','K','B','A','5','2','7','b','y','R','K','q','A','u','3','J'};
static const adler32_test tests[] = {
- {__LINE__, 0x1, (const uint8_t *)0x0, 0, 0x1},
- {__LINE__, 0x1, (const uint8_t *)"", 1, 0x10001},
- {__LINE__, 0x1, (const uint8_t *)"a", 1, 0x620062},
- {__LINE__, 0x1, (const uint8_t *)"abacus", 6, 0x8400270},
- {__LINE__, 0x1, (const uint8_t *)"backlog", 7, 0xb1f02d4},
- {__LINE__, 0x1, (const uint8_t *)"campfire", 8, 0xea10348},
- {__LINE__, 0x1, (const uint8_t *)"delta", 5, 0x61a020b},
- {__LINE__, 0x1, (const uint8_t *)"executable", 10, 0x16fa0423},
- {__LINE__, 0x1, (const uint8_t *)"file", 4, 0x41401a1},
- {__LINE__, 0x1, (const uint8_t *)"greatest", 8, 0xefa0360},
- {__LINE__, 0x1, (const uint8_t *)"inverter", 8, 0xf6f0370},
- {__LINE__, 0x1, (const uint8_t *)"jigsaw", 6, 0x8bd0286},
- {__LINE__, 0x1, (const uint8_t *)"karate", 6, 0x8a50279},
- {__LINE__, 0x1, (const uint8_t *)"landscape", 9, 0x126a03ac},
- {__LINE__, 0x1, (const uint8_t *)"machine", 7, 0xb5302d6},
- {__LINE__, 0x1, (const uint8_t *)"nanometer", 9, 0x12d803ca},
- {__LINE__, 0x1, (const uint8_t *)"oblivion", 8, 0xf220363},
- {__LINE__, 0x1, (const uint8_t *)"panama", 6, 0x8a1026f},
- {__LINE__, 0x1, (const uint8_t *)"quest", 5, 0x6970233},
- {__LINE__, 0x1, (const uint8_t *)"resource", 8, 0xf8d0369},
- {__LINE__, 0x1, (const uint8_t *)"secret", 6, 0x8d10287},
- {__LINE__, 0x1, (const uint8_t *)"ultimate", 8, 0xf8d0366},
- {__LINE__, 0x1, (const uint8_t *)"vector", 6, 0x8fb0294},
- {__LINE__, 0x1, (const uint8_t *)"walrus", 6, 0x918029f},
- {__LINE__, 0x1, (const uint8_t *)"xeno", 4, 0x45e01bb},
- {__LINE__, 0x1, (const uint8_t *)"yelling", 7, 0xbfe02f5},
- {__LINE__, 0x1, (const uint8_t *)"zero", 4, 0x46e01c1},
- {__LINE__, 0x1, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0x3eef064d},
- {__LINE__, 0x1, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x425d065f},
- {__LINE__, 0x1, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0x4f1a073e},
- {__LINE__, 0x1, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x42290650},
- {__LINE__, 0x1, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0x43fd0690},
- {__LINE__, 0x1, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x3f770609},
- {__LINE__, 0x1, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0x4c7c0703},
- {__LINE__, 0x1, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x48ac06b7},
- {__LINE__, 0x1, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x489a0698},
- {__LINE__, 0x1, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x44a906e6},
- {__LINE__, 0x1, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0x4a29071c},
- {__LINE__, 0x1, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0x4a7706f9},
- {__LINE__, 0x1, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x4ce60769},
- {__LINE__, 0x1, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x48ae06e5},
- {__LINE__, 0x1, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x51d60750},
- {__LINE__, 0x1, (const uint8_t *)"70684206568419061514", 20, 0x2b100414},
- {__LINE__, 0x1, (const uint8_t *)"42015093765128581010", 20, 0x2a550405},
- {__LINE__, 0x1, (const uint8_t *)"88214814356148806939", 20, 0x2b450423},
- {__LINE__, 0x1, (const uint8_t *)"43472694284527343838", 20, 0x2b460421},
- {__LINE__, 0x1, (const uint8_t *)"49769333513942933689", 20, 0x2bc1042b},
- {__LINE__, 0x1, (const uint8_t *)"54979784887993251199", 20, 0x2ccd043d},
- {__LINE__, 0x1, (const uint8_t *)"58360544869206793220", 20, 0x2b68041a},
- {__LINE__, 0x1, (const uint8_t *)"27347953487840714234", 20, 0x2b84041d},
- {__LINE__, 0x1, (const uint8_t *)"07650690295365319082", 20, 0x2afa0417},
- {__LINE__, 0x1, (const uint8_t *)"42655507906821911703", 20, 0x2aff0412},
- {__LINE__, 0x1, (const uint8_t *)"29977409200786225655", 20, 0x2b8d0420},
- {__LINE__, 0x1, (const uint8_t *)"85181542907229116674", 20, 0x2b140419},
- {__LINE__, 0x1, (const uint8_t *)"87963594337989416799", 20, 0x2c8e043f},
- {__LINE__, 0x1, (const uint8_t *)"21395988329504168551", 20, 0x2b68041f},
- {__LINE__, 0x1, (const uint8_t *)"51991013580943379423", 20, 0x2af10417},
- {__LINE__, 0x1, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x7c9d0841},
- {__LINE__, 0x1, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x71060751},
- {__LINE__, 0x1, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x7095070a},
- {__LINE__, 0x1, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x82530815},
- {__LINE__, 0x1, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x61250661},
- {__LINE__, 0x1, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x642006a3},
- {__LINE__, 0x1, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x674206cb},
- {__LINE__, 0x1, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x67670680},
- {__LINE__, 0x1, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0x7547070f},
- {__LINE__, 0x1, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x69ea06ee},
- {__LINE__, 0x1, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x1b01e92},
- {__LINE__, 0x1, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xfbdb1e96},
- {__LINE__, 0x1, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0x47a61ec8},
- {__LINE__, 0x1, (const uint8_t *)long_string, 5552, 0x8b81718f},
- {__LINE__, 0x7a30360d, (const uint8_t *)0x0, 0, 0x1},
- {__LINE__, 0x6fd767ee, (const uint8_t *)"", 1, 0xd7c567ee},
- {__LINE__, 0xefeb7589, (const uint8_t *)"a", 1, 0x65e475ea},
- {__LINE__, 0x61cf7e6b, (const uint8_t *)"abacus", 6, 0x60b880da},
- {__LINE__, 0xdc712e2, (const uint8_t *)"backlog", 7, 0x9d0d15b5},
- {__LINE__, 0xad23c7fd, (const uint8_t *)"campfire", 8, 0xfbfecb44},
- {__LINE__, 0x85cb2317, (const uint8_t *)"delta", 5, 0x3b622521},
- {__LINE__, 0x9eed31b0, (const uint8_t *)"executable", 10, 0xa6db35d2},
- {__LINE__, 0xb94f34ca, (const uint8_t *)"file", 4, 0x9096366a},
- {__LINE__, 0xab058a2, (const uint8_t *)"greatest", 8, 0xded05c01},
- {__LINE__, 0x5bff2b7a, (const uint8_t *)"inverter", 8, 0xc7452ee9},
- {__LINE__, 0x605c9a5f, (const uint8_t *)"jigsaw", 6, 0x7899ce4},
- {__LINE__, 0x51bdeea5, (const uint8_t *)"karate", 6, 0xf285f11d},
- {__LINE__, 0x85c21c79, (const uint8_t *)"landscape", 9, 0x98732024},
- {__LINE__, 0x97216f56, (const uint8_t *)"machine", 7, 0xadf4722b},
- {__LINE__, 0x18444af2, (const uint8_t *)"nanometer", 9, 0xcdb34ebb},
- {__LINE__, 0xbe6ce359, (const uint8_t *)"oblivion", 8, 0xe8b7e6bb},
- {__LINE__, 0x843071f1, (const uint8_t *)"panama", 6, 0x389e745f},
- {__LINE__, 0xf2480c60, (const uint8_t *)"quest", 5, 0x36c90e92},
- {__LINE__, 0x2d2feb3d, (const uint8_t *)"resource", 8, 0x9705eea5},
- {__LINE__, 0x7490310a, (const uint8_t *)"secret", 6, 0xa3a63390},
- {__LINE__, 0x97d247d4, (const uint8_t *)"ultimate", 8, 0xe6154b39},
- {__LINE__, 0x93cf7599, (const uint8_t *)"vector", 6, 0x5e87782c},
- {__LINE__, 0x73c84278, (const uint8_t *)"walrus", 6, 0xbc84516},
- {__LINE__, 0x228a87d1, (const uint8_t *)"xeno", 4, 0x4646898b},
- {__LINE__, 0xa7a048d0, (const uint8_t *)"yelling", 7, 0xb1654bc4},
- {__LINE__, 0x1f0ded40, (const uint8_t *)"zero", 4, 0xd8a4ef00},
- {__LINE__, 0xa804a62f, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0xe34eac7b},
- {__LINE__, 0x508fae6a, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x33f2b4c8},
- {__LINE__, 0xe5adaf4f, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xe7b1b68c},
- {__LINE__, 0x67136a40, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0xf6a0708f},
- {__LINE__, 0xb00c4a10, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xbd8f509f},
- {__LINE__, 0x2e0c84b5, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xcc298abd},
- {__LINE__, 0x81238d44, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0xd7809446},
- {__LINE__, 0xf853aa92, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x9525b148},
- {__LINE__, 0x5a692325, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x620029bc},
- {__LINE__, 0x3275b9f, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x70916284},
- {__LINE__, 0x38371feb, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0xd52706},
- {__LINE__, 0xafc8bf62, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0xeeb4c65a},
- {__LINE__, 0x9b07db73, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xde3e2db},
- {__LINE__, 0xe75b214, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x4171b8f8},
- {__LINE__, 0x72d0fe6f, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0xa66a05cd},
- {__LINE__, 0xf857a4b1, (const uint8_t *)"70684206568419061514", 20, 0x1f9a8c4},
- {__LINE__, 0x54b8e14, (const uint8_t *)"42015093765128581010", 20, 0x49c19218},
- {__LINE__, 0xd6aa5616, (const uint8_t *)"88214814356148806939", 20, 0xbbfc5a38},
- {__LINE__, 0x11e63098, (const uint8_t *)"43472694284527343838", 20, 0x93434b8},
- {__LINE__, 0xbe92385, (const uint8_t *)"49769333513942933689", 20, 0xfe1827af},
- {__LINE__, 0x49511de0, (const uint8_t *)"54979784887993251199", 20, 0xcba8221c},
- {__LINE__, 0x3db13bc1, (const uint8_t *)"58360544869206793220", 20, 0x14643fda},
- {__LINE__, 0xbb899bea, (const uint8_t *)"27347953487840714234", 20, 0x1604a006},
- {__LINE__, 0xf6cd9436, (const uint8_t *)"07650690295365319082", 20, 0xb69f984c},
- {__LINE__, 0x9109e6c3, (const uint8_t *)"42655507906821911703", 20, 0xc43eead4},
- {__LINE__, 0x75770fc, (const uint8_t *)"29977409200786225655", 20, 0x707751b},
- {__LINE__, 0x69b1d19b, (const uint8_t *)"85181542907229116674", 20, 0xf5bdd5b3},
- {__LINE__, 0xc6132975, (const uint8_t *)"87963594337989416799", 20, 0x2fed2db3},
- {__LINE__, 0xd58cb00c, (const uint8_t *)"21395988329504168551", 20, 0xc2a2b42a},
- {__LINE__, 0xb63b8caa, (const uint8_t *)"51991013580943379423", 20, 0xdf0590c0},
- {__LINE__, 0x8a45a2b8, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x1980aaf8},
- {__LINE__, 0xcbe95b78, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xf58662c8},
- {__LINE__, 0x4ef8a54b, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x1f65ac54},
- {__LINE__, 0x76ad267a, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x7b792e8e},
- {__LINE__, 0x569e613c, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x1d61679c},
- {__LINE__, 0x36aa61da, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x12ec687c},
- {__LINE__, 0xf67222df, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x740329a9},
- {__LINE__, 0x74b34fd3, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x374c5652},
- {__LINE__, 0x351fd770, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xeadfde7e},
- {__LINE__, 0xc45aef77, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x3fcbf664},
- {__LINE__, 0xd034ea71, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x6b080911},
- {__LINE__, 0xdeadc0de, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0x355fdf73},
- {__LINE__, 0xba5eba11, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xb48bd8d8},
- {__LINE__, 0x7712aa45, (const uint8_t *)long_string, 5552, 0x7dc51be2},
+ {0x1, (const uint8_t *)0x0, 0, 0x1},
+ {0x1, (const uint8_t *)"", 1, 0x10001},
+ {0x1, (const uint8_t *)"a", 1, 0x620062},
+ {0x1, (const uint8_t *)"abacus", 6, 0x8400270},
+ {0x1, (const uint8_t *)"backlog", 7, 0xb1f02d4},
+ {0x1, (const uint8_t *)"campfire", 8, 0xea10348},
+ {0x1, (const uint8_t *)"delta", 5, 0x61a020b},
+ {0x1, (const uint8_t *)"executable", 10, 0x16fa0423},
+ {0x1, (const uint8_t *)"file", 4, 0x41401a1},
+ {0x1, (const uint8_t *)"greatest", 8, 0xefa0360},
+ {0x1, (const uint8_t *)"inverter", 8, 0xf6f0370},
+ {0x1, (const uint8_t *)"jigsaw", 6, 0x8bd0286},
+ {0x1, (const uint8_t *)"karate", 6, 0x8a50279},
+ {0x1, (const uint8_t *)"landscape", 9, 0x126a03ac},
+ {0x1, (const uint8_t *)"machine", 7, 0xb5302d6},
+ {0x1, (const uint8_t *)"nanometer", 9, 0x12d803ca},
+ {0x1, (const uint8_t *)"oblivion", 8, 0xf220363},
+ {0x1, (const uint8_t *)"panama", 6, 0x8a1026f},
+ {0x1, (const uint8_t *)"quest", 5, 0x6970233},
+ {0x1, (const uint8_t *)"resource", 8, 0xf8d0369},
+ {0x1, (const uint8_t *)"secret", 6, 0x8d10287},
+ {0x1, (const uint8_t *)"ultimate", 8, 0xf8d0366},
+ {0x1, (const uint8_t *)"vector", 6, 0x8fb0294},
+ {0x1, (const uint8_t *)"walrus", 6, 0x918029f},
+ {0x1, (const uint8_t *)"xeno", 4, 0x45e01bb},
+ {0x1, (const uint8_t *)"yelling", 7, 0xbfe02f5},
+ {0x1, (const uint8_t *)"zero", 4, 0x46e01c1},
+ {0x1, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0x3eef064d},
+ {0x1, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x425d065f},
+ {0x1, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0x4f1a073e},
+ {0x1, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x42290650},
+ {0x1, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0x43fd0690},
+ {0x1, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x3f770609},
+ {0x1, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0x4c7c0703},
+ {0x1, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x48ac06b7},
+ {0x1, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x489a0698},
+ {0x1, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x44a906e6},
+ {0x1, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0x4a29071c},
+ {0x1, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0x4a7706f9},
+ {0x1, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x4ce60769},
+ {0x1, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x48ae06e5},
+ {0x1, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x51d60750},
+ {0x1, (const uint8_t *)"70684206568419061514", 20, 0x2b100414},
+ {0x1, (const uint8_t *)"42015093765128581010", 20, 0x2a550405},
+ {0x1, (const uint8_t *)"88214814356148806939", 20, 0x2b450423},
+ {0x1, (const uint8_t *)"43472694284527343838", 20, 0x2b460421},
+ {0x1, (const uint8_t *)"49769333513942933689", 20, 0x2bc1042b},
+ {0x1, (const uint8_t *)"54979784887993251199", 20, 0x2ccd043d},
+ {0x1, (const uint8_t *)"58360544869206793220", 20, 0x2b68041a},
+ {0x1, (const uint8_t *)"27347953487840714234", 20, 0x2b84041d},
+ {0x1, (const uint8_t *)"07650690295365319082", 20, 0x2afa0417},
+ {0x1, (const uint8_t *)"42655507906821911703", 20, 0x2aff0412},
+ {0x1, (const uint8_t *)"29977409200786225655", 20, 0x2b8d0420},
+ {0x1, (const uint8_t *)"85181542907229116674", 20, 0x2b140419},
+ {0x1, (const uint8_t *)"87963594337989416799", 20, 0x2c8e043f},
+ {0x1, (const uint8_t *)"21395988329504168551", 20, 0x2b68041f},
+ {0x1, (const uint8_t *)"51991013580943379423", 20, 0x2af10417},
+ {0x1, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x7c9d0841},
+ {0x1, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x71060751},
+ {0x1, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x7095070a},
+ {0x1, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x82530815},
+ {0x1, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x61250661},
+ {0x1, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x642006a3},
+ {0x1, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x674206cb},
+ {0x1, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x67670680},
+ {0x1, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0x7547070f},
+ {0x1, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x69ea06ee},
+ {0x1, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x1b01e92},
+ {0x1, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xfbdb1e96},
+ {0x1, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0x47a61ec8},
+ {0x1, (const uint8_t *)long_string, 5552, 0x8b81718f},
+ {0x7a30360d, (const uint8_t *)0x0, 0, 0x1},
+ {0x6fd767ee, (const uint8_t *)"", 1, 0xd7c567ee},
+ {0xefeb7589, (const uint8_t *)"a", 1, 0x65e475ea},
+ {0x61cf7e6b, (const uint8_t *)"abacus", 6, 0x60b880da},
+ {0xdc712e2, (const uint8_t *)"backlog", 7, 0x9d0d15b5},
+ {0xad23c7fd, (const uint8_t *)"campfire", 8, 0xfbfecb44},
+ {0x85cb2317, (const uint8_t *)"delta", 5, 0x3b622521},
+ {0x9eed31b0, (const uint8_t *)"executable", 10, 0xa6db35d2},
+ {0xb94f34ca, (const uint8_t *)"file", 4, 0x9096366a},
+ {0xab058a2, (const uint8_t *)"greatest", 8, 0xded05c01},
+ {0x5bff2b7a, (const uint8_t *)"inverter", 8, 0xc7452ee9},
+ {0x605c9a5f, (const uint8_t *)"jigsaw", 6, 0x7899ce4},
+ {0x51bdeea5, (const uint8_t *)"karate", 6, 0xf285f11d},
+ {0x85c21c79, (const uint8_t *)"landscape", 9, 0x98732024},
+ {0x97216f56, (const uint8_t *)"machine", 7, 0xadf4722b},
+ {0x18444af2, (const uint8_t *)"nanometer", 9, 0xcdb34ebb},
+ {0xbe6ce359, (const uint8_t *)"oblivion", 8, 0xe8b7e6bb},
+ {0x843071f1, (const uint8_t *)"panama", 6, 0x389e745f},
+ {0xf2480c60, (const uint8_t *)"quest", 5, 0x36c90e92},
+ {0x2d2feb3d, (const uint8_t *)"resource", 8, 0x9705eea5},
+ {0x7490310a, (const uint8_t *)"secret", 6, 0xa3a63390},
+ {0x97d247d4, (const uint8_t *)"ultimate", 8, 0xe6154b39},
+ {0x93cf7599, (const uint8_t *)"vector", 6, 0x5e87782c},
+ {0x73c84278, (const uint8_t *)"walrus", 6, 0xbc84516},
+ {0x228a87d1, (const uint8_t *)"xeno", 4, 0x4646898b},
+ {0xa7a048d0, (const uint8_t *)"yelling", 7, 0xb1654bc4},
+ {0x1f0ded40, (const uint8_t *)"zero", 4, 0xd8a4ef00},
+ {0xa804a62f, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0xe34eac7b},
+ {0x508fae6a, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x33f2b4c8},
+ {0xe5adaf4f, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xe7b1b68c},
+ {0x67136a40, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0xf6a0708f},
+ {0xb00c4a10, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xbd8f509f},
+ {0x2e0c84b5, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xcc298abd},
+ {0x81238d44, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0xd7809446},
+ {0xf853aa92, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x9525b148},
+ {0x5a692325, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x620029bc},
+ {0x3275b9f, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x70916284},
+ {0x38371feb, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0xd52706},
+ {0xafc8bf62, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0xeeb4c65a},
+ {0x9b07db73, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xde3e2db},
+ {0xe75b214, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x4171b8f8},
+ {0x72d0fe6f, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0xa66a05cd},
+ {0xf857a4b1, (const uint8_t *)"70684206568419061514", 20, 0x1f9a8c4},
+ {0x54b8e14, (const uint8_t *)"42015093765128581010", 20, 0x49c19218},
+ {0xd6aa5616, (const uint8_t *)"88214814356148806939", 20, 0xbbfc5a38},
+ {0x11e63098, (const uint8_t *)"43472694284527343838", 20, 0x93434b8},
+ {0xbe92385, (const uint8_t *)"49769333513942933689", 20, 0xfe1827af},
+ {0x49511de0, (const uint8_t *)"54979784887993251199", 20, 0xcba8221c},
+ {0x3db13bc1, (const uint8_t *)"58360544869206793220", 20, 0x14643fda},
+ {0xbb899bea, (const uint8_t *)"27347953487840714234", 20, 0x1604a006},
+ {0xf6cd9436, (const uint8_t *)"07650690295365319082", 20, 0xb69f984c},
+ {0x9109e6c3, (const uint8_t *)"42655507906821911703", 20, 0xc43eead4},
+ {0x75770fc, (const uint8_t *)"29977409200786225655", 20, 0x707751b},
+ {0x69b1d19b, (const uint8_t *)"85181542907229116674", 20, 0xf5bdd5b3},
+ {0xc6132975, (const uint8_t *)"87963594337989416799", 20, 0x2fed2db3},
+ {0xd58cb00c, (const uint8_t *)"21395988329504168551", 20, 0xc2a2b42a},
+ {0xb63b8caa, (const uint8_t *)"51991013580943379423", 20, 0xdf0590c0},
+ {0x8a45a2b8, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x1980aaf8},
+ {0xcbe95b78, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xf58662c8},
+ {0x4ef8a54b, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x1f65ac54},
+ {0x76ad267a, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x7b792e8e},
+ {0x569e613c, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x1d61679c},
+ {0x36aa61da, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x12ec687c},
+ {0xf67222df, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x740329a9},
+ {0x74b34fd3, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x374c5652},
+ {0x351fd770, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xeadfde7e},
+ {0xc45aef77, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x3fcbf664},
+ {0xd034ea71, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x6b080911},
+ {0xdeadc0de, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0x355fdf73},
+ {0xba5eba11, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xb48bd8d8},
+ {0x7712aa45, (const uint8_t *)long_string, 5552, 0x7dc51be2},
+};
+
+class adler32_variant : public ::testing::TestWithParam<adler32_test> {
+public:
+ void hash(adler32_test param, adler32_func adler32) {
+ uint32_t adler = adler32((uint32_t)param.adler, param.buf, param.len);
+ EXPECT_EQ(adler, param.expect);
+ }
};
-static const int test_size = sizeof(tests) / sizeof(tests[0]);
+INSTANTIATE_TEST_SUITE_P(adler32, adler32_variant, testing::ValuesIn(tests));
-int main(void) {
- int i;
- for (i = 0; i < test_size; i++) {
- test_adler32(tests[i].adler, tests[i].buf, tests[i].len, tests[i].expect, tests[i].line);
+#define TEST_ADLER32(name, func, support_flag) \
+ TEST_P(adler32_variant, name) { \
+ if (!support_flag) { \
+ GTEST_SKIP(); \
+ return; \
+ } \
+ hash(GetParam(), func); \
}
- return 0;
-}
+TEST_ADLER32(c, adler32_c, 1)
+
+#ifdef ARM_NEON_ADLER32
+TEST_ADLER32(neon, adler32_neon, arm_cpu_has_neon)
+#elif defined(POWER8_VSX_ADLER32)
+TEST_ADLER32(power8, adler32_power8, power_cpu_has_arch_2_07)
+#elif defined(PPC_VMX_ADLER32)
+TEST_ADLER32(vmx, adler32_vmx, power_cpu_has_altivec)
+#endif
+
+#ifdef X86_SSSE3_ADLER32
+TEST_ADLER32(ssse3, adler32_ssse3, x86_cpu_has_ssse3)
+#endif
+#ifdef X86_SSE41_ADLER32
+TEST_ADLER32(sse41, adler32_sse41, x86_cpu_has_sse41)
+#endif
+#ifdef X86_AVX2_ADLER32
+TEST_ADLER32(avx2, adler32_avx2, x86_cpu_has_avx2)
+#endif
+#ifdef X86_AVX512_ADLER32
+TEST_ADLER32(avx512, adler32_avx512, x86_cpu_has_avx512)
+#endif
+#ifdef X86_AVX512VNNI_ADLER32
+TEST_ADLER32(avx512_vnni, adler32_avx512_vnni, x86_cpu_has_avx512vnni)
+#endif
diff --git a/src/zlib-ng/test/test_aligned_alloc.cc b/src/zlib-ng/test/test_aligned_alloc.cc
new file mode 100644
index 0000000..259d474
--- /dev/null
+++ b/src/zlib-ng/test/test_aligned_alloc.cc
@@ -0,0 +1,46 @@
+/* test_aligned_alloc.cc - Test zng_alloc_aligned and zng_free_aligned */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+
+extern "C" {
+# include "zbuild.h"
+# include "zutil.h"
+}
+
+#include <gtest/gtest.h>
+
+void *zng_calloc_unaligned(void *opaque, unsigned items, unsigned size) {
+ uint8_t *pointer = (uint8_t *)calloc(1, (items * size) + 2);
+ Z_UNUSED(opaque);
+ if (pointer == NULL)
+ return pointer;
+ /* Store whether or not our allocation is aligned */
+ *pointer = ((uint64_t)(intptr_t)pointer + 1) % 2 == 0;
+ pointer++;
+ if (*pointer) {
+ /* Return pointer that is off by one */
+ pointer++;
+ }
+ return (void *)pointer;
+}
+
+void zng_cfree_unaligned(void *opaque, void *ptr) {
+ uint8_t *pointer = (uint8_t *)ptr;
+ Z_UNUSED(opaque);
+ pointer--;
+ /* Get whether or not our original memory pointer was aligned */
+ if (*pointer) {
+ /* Return original aligned pointer to free() */
+ pointer--;
+ }
+ free(pointer);
+}
+
+TEST(zalloc, aligned_64) {
+ void *return_ptr = zng_alloc_aligned(zng_calloc_unaligned, 0, 1, 100, 64);
+ ASSERT_TRUE(return_ptr != NULL);
+ EXPECT_EQ((intptr_t)return_ptr % 64, 0);
+ zng_free_aligned(zng_cfree_unaligned, 0, return_ptr);
+}
diff --git a/src/zlib-ng/test/test_compare256.cc b/src/zlib-ng/test/test_compare256.cc
new file mode 100644
index 0000000..7c4dab9
--- /dev/null
+++ b/src/zlib-ng/test/test_compare256.cc
@@ -0,0 +1,80 @@
+/* test_compare256.cc -- compare256 unit tests
+ * Copyright (C) 2022 Nathan Moinvaziri
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+extern "C" {
+# include "zbuild.h"
+# include "zutil_p.h"
+# include "cpu_features.h"
+}
+
+#include <gtest/gtest.h>
+
+#define MAX_COMPARE_SIZE (256)
+
+/* Ensure that compare256 returns the correct match length */
+static inline void compare256_match_check(compare256_func compare256) {
+ int32_t match_len, i;
+ uint8_t *str1;
+ uint8_t *str2;
+
+ str1 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE);
+ ASSERT_TRUE(str1 != NULL);
+ memset(str1, 'a', MAX_COMPARE_SIZE);
+
+ str2 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE);
+ ASSERT_TRUE(str2 != NULL);
+ memset(str2, 'a', MAX_COMPARE_SIZE);
+
+ for (i = 0; i <= MAX_COMPARE_SIZE; i++) {
+ if (i < MAX_COMPARE_SIZE)
+ str2[i] = 0;
+
+ match_len = compare256(str1, str2);
+ EXPECT_EQ(match_len, i);
+
+ if (i < MAX_COMPARE_SIZE)
+ str2[i] = 'a';
+ }
+
+ zng_free(str1);
+ zng_free(str2);
+}
+
+#define TEST_COMPARE256(name, func, support_flag) \
+ TEST(compare256, name) { \
+ if (!support_flag) { \
+ GTEST_SKIP(); \
+ return; \
+ } \
+ compare256_match_check(func); \
+ }
+
+TEST_COMPARE256(c, compare256_c, 1)
+
+#ifdef UNALIGNED_OK
+TEST_COMPARE256(unaligned_16, compare256_unaligned_16, 1)
+#ifdef HAVE_BUILTIN_CTZ
+TEST_COMPARE256(unaligned_32, compare256_unaligned_32, 1)
+#endif
+#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL)
+TEST_COMPARE256(unaligned_64, compare256_unaligned_64, 1)
+#endif
+#endif
+#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ)
+TEST_COMPARE256(sse2, compare256_sse2, x86_cpu_has_sse2)
+#endif
+#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ)
+TEST_COMPARE256(avx2, compare256_avx2, x86_cpu_has_avx2)
+#endif
+#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL)
+TEST_COMPARE256(neon, compare256_neon, arm_cpu_has_neon)
+#endif
+#ifdef POWER9
+TEST_COMPARE256(power9, compare256_power9, power_cpu_has_arch_3_00)
+#endif
diff --git a/src/zlib-ng/test/test_compress.cc b/src/zlib-ng/test/test_compress.cc
new file mode 100644
index 0000000..9885b33
--- /dev/null
+++ b/src/zlib-ng/test/test_compress.cc
@@ -0,0 +1,33 @@
+/* test_compress.cc - Test compress() and uncompress() using hello world string */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(compress, basic) {
+ uint8_t compr[128], uncompr[128];
+ z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr);
+ int err;
+
+ err = PREFIX(compress)(compr, &compr_len, (const unsigned char *)hello, hello_len);
+ EXPECT_EQ(err, Z_OK);
+
+ strcpy((char*)uncompr, "garbage");
+
+ err = PREFIX(uncompress)(uncompr, &uncompr_len, compr, compr_len);
+ EXPECT_EQ(err, Z_OK);
+
+ EXPECT_STREQ((char *)uncompr, (char *)hello);
+}
diff --git a/src/zlib-ng/test/test_compress_bound.cc b/src/zlib-ng/test/test_compress_bound.cc
new file mode 100644
index 0000000..2757fb2
--- /dev/null
+++ b/src/zlib-ng/test/test_compress_bound.cc
@@ -0,0 +1,59 @@
+/* test_compress_bound.cc - Test compressBound() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+#define MAX_LENGTH (32)
+
+class compress_bound_variant : public testing::TestWithParam<z_size_t> {
+public:
+ void estimate(z_size_t level) {
+ z_size_t estimate_len = 0;
+ uint8_t *uncompressed = NULL;
+ uint8_t dest[128];
+ int err;
+
+ uncompressed = (uint8_t *)malloc(MAX_LENGTH);
+ ASSERT_TRUE(uncompressed != NULL);
+
+ /* buffer with values for worst case compression */
+ for (int32_t j = 0; j < MAX_LENGTH; j++) {
+ uncompressed[j] = (uint8_t)j;
+ }
+
+ for (z_size_t i = 0; i < MAX_LENGTH; i++) {
+ z_size_t dest_len = sizeof(dest);
+
+ /* calculate actual output length */
+ estimate_len = PREFIX(compressBound)(i);
+
+ err = PREFIX(compress2)(dest, &dest_len, uncompressed, i, level);
+ EXPECT_EQ(err, Z_OK);
+ EXPECT_GE(estimate_len, dest_len) <<
+ "level: " << level << "\n" <<
+ "length: " << i;
+ }
+
+ free(uncompressed);
+ }
+};
+
+TEST_P(compress_bound_variant, estimate) {
+ estimate(GetParam());
+}
+
+INSTANTIATE_TEST_SUITE_P(compress_bound, compress_bound_variant,
+ testing::Values(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
diff --git a/src/zlib-ng/test/test_crc32.cc b/src/zlib-ng/test/test_crc32.cc
new file mode 100644
index 0000000..1d839d7
--- /dev/null
+++ b/src/zlib-ng/test/test_crc32.cc
@@ -0,0 +1,219 @@
+/* test_crc32.cc -- crc32 unit test
+ * Copyright (C) 2019-2021 IBM Corporation
+ * Authors: Rogerio Alves <rogealve@br.ibm.com>
+ * Matheus Castanho <msc@linux.ibm.com>
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+extern "C" {
+# include "zbuild.h"
+# include "zutil_p.h"
+# include "cpu_features.h"
+}
+
+#include <gtest/gtest.h>
+
+typedef struct {
+ unsigned long crc;
+ const uint8_t *buf;
+ size_t len;
+ unsigned long expect;
+} crc32_test;
+
+static const crc32_test tests[] = {
+ {0x0, (const uint8_t *)0x0, 0, 0x0},
+ {0xffffffff, (const uint8_t *)0x0, 0, 0x0},
+ {0x0, (const uint8_t *)0x0, 255, 0x0}, /* BZ 174799. */
+ {0x0, (const uint8_t *)0x0, 256, 0x0},
+ {0x0, (const uint8_t *)0x0, 257, 0x0},
+ {0x0, (const uint8_t *)0x0, 32767, 0x0},
+ {0x0, (const uint8_t *)0x0, 32768, 0x0},
+ {0x0, (const uint8_t *)0x0, 32769, 0x0},
+ {0x0, (const uint8_t *)"", 0, 0x0},
+ {0xffffffff, (const uint8_t *)"", 0, 0xffffffff},
+ {0x0, (const uint8_t *)"abacus", 6, 0xc3d7115b},
+ {0x0, (const uint8_t *)"backlog", 7, 0x269205},
+ {0x0, (const uint8_t *)"campfire", 8, 0x22a515f8},
+ {0x0, (const uint8_t *)"delta", 5, 0x9643fed9},
+ {0x0, (const uint8_t *)"executable", 10, 0xd68eda01},
+ {0x0, (const uint8_t *)"file", 4, 0x8c9f3610},
+ {0x0, (const uint8_t *)"greatest", 8, 0xc1abd6cd},
+ {0x0, (const uint8_t *)"hello", 5, 0x3610a686},
+ {0x0, (const uint8_t *)"inverter", 8, 0xc9e962c9},
+ {0x0, (const uint8_t *)"jigsaw", 6, 0xce4e3f69},
+ {0x0, (const uint8_t *)"karate", 6, 0x890be0e2},
+ {0x0, (const uint8_t *)"landscape", 9, 0xc4e0330b},
+ {0x0, (const uint8_t *)"machine", 7, 0x1505df84},
+ {0x0, (const uint8_t *)"nanometer", 9, 0xd4e19f39},
+ {0x0, (const uint8_t *)"oblivion", 8, 0xdae9de77},
+ {0x0, (const uint8_t *)"panama", 6, 0x66b8979c},
+ {0x0, (const uint8_t *)"quest", 5, 0x4317f817},
+ {0x0, (const uint8_t *)"resource", 8, 0xbc91f416},
+ {0x0, (const uint8_t *)"secret", 6, 0x5ca2e8e5},
+ {0x0, (const uint8_t *)"test", 4, 0xd87f7e0c},
+ {0x0, (const uint8_t *)"ultimate", 8, 0x3fc79b0b},
+ {0x0, (const uint8_t *)"vector", 6, 0x1b6e485b},
+ {0x0, (const uint8_t *)"walrus", 6, 0xbe769b97},
+ {0x0, (const uint8_t *)"xeno", 4, 0xe7a06444},
+ {0x0, (const uint8_t *)"yelling", 7, 0xfe3944e5},
+ {0x0, (const uint8_t *)"zlib", 4, 0x73887d3a},
+ {0x0, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0xd487a5a1},
+ {0x0, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x61a0132e},
+ {0x0, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xdf02f76},
+ {0x0, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x579b2b0a},
+ {0x0, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xf7d16e2d},
+ {0x0, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x731788f5},
+ {0x0, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0x7112bb11},
+ {0x0, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0xf32a0dac},
+ {0x0, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x625437bb},
+ {0x0, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x896930f9},
+ {0x0, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0x8579a37},
+ {0x0, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0x632aa8e0},
+ {0x0, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xc829af29},
+ {0x0, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x1b08b7e8},
+ {0x0, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x4e33b192},
+ {0x0, (const uint8_t *)"70684206568419061514", 20, 0x59a179f0},
+ {0x0, (const uint8_t *)"42015093765128581010", 20, 0xcd1013d7},
+ {0x0, (const uint8_t *)"88214814356148806939", 20, 0xab927546},
+ {0x0, (const uint8_t *)"43472694284527343838", 20, 0x11f3b20c},
+ {0x0, (const uint8_t *)"49769333513942933689", 20, 0xd562d4ca},
+ {0x0, (const uint8_t *)"54979784887993251199", 20, 0x233395f7},
+ {0x0, (const uint8_t *)"58360544869206793220", 20, 0x2d167fd5},
+ {0x0, (const uint8_t *)"27347953487840714234", 20, 0x8b5108ba},
+ {0x0, (const uint8_t *)"07650690295365319082", 20, 0xc46b3cd8},
+ {0x0, (const uint8_t *)"42655507906821911703", 20, 0xc10b2662},
+ {0x0, (const uint8_t *)"29977409200786225655", 20, 0xc9a0f9d2},
+ {0x0, (const uint8_t *)"85181542907229116674", 20, 0x9341357b},
+ {0x0, (const uint8_t *)"87963594337989416799", 20, 0xf0424937},
+ {0x0, (const uint8_t *)"21395988329504168551", 20, 0xd7c4c31f},
+ {0x0, (const uint8_t *)"51991013580943379423", 20, 0xf11edcc4},
+ {0x0, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x40795df4},
+ {0x0, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xdd61a631},
+ {0x0, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xca907a99},
+ {0x0, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0xf652deac},
+ {0x0, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0xaf39a5a9},
+ {0x0, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x6bebb4cf},
+ {0x0, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x76430bac},
+ {0x0, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x6c80c388},
+ {0x0, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xd54d977d},
+ {0x0, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0xe3966ad5},
+ {0x0, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xe7c71db9},
+ {0x0, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xeaa52777},
+ {0x0, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xcd472048},
+ {0x7a30360d, (const uint8_t *)"abacus", 6, 0xf8655a84},
+ {0x6fd767ee, (const uint8_t *)"backlog", 7, 0x1ed834b1},
+ {0xefeb7589, (const uint8_t *)"campfire", 8, 0x686cfca},
+ {0x61cf7e6b, (const uint8_t *)"delta", 5, 0x1554e4b1},
+ {0xdc712e2, (const uint8_t *)"executable", 10, 0x761b4254},
+ {0xad23c7fd, (const uint8_t *)"file", 4, 0x7abdd09b},
+ {0x85cb2317, (const uint8_t *)"greatest", 8, 0x4ba91c6b},
+ {0x9eed31b0, (const uint8_t *)"inverter", 8, 0xd5e78ba5},
+ {0xb94f34ca, (const uint8_t *)"jigsaw", 6, 0x23649109},
+ {0xab058a2, (const uint8_t *)"karate", 6, 0xc5591f41},
+ {0x5bff2b7a, (const uint8_t *)"landscape", 9, 0xf10eb644},
+ {0x605c9a5f, (const uint8_t *)"machine", 7, 0xbaa0a636},
+ {0x51bdeea5, (const uint8_t *)"nanometer", 9, 0x6af89afb},
+ {0x85c21c79, (const uint8_t *)"oblivion", 8, 0xecae222b},
+ {0x97216f56, (const uint8_t *)"panama", 6, 0x47dffac4},
+ {0x18444af2, (const uint8_t *)"quest", 5, 0x70c2fe36},
+ {0xbe6ce359, (const uint8_t *)"resource", 8, 0x1471d925},
+ {0x843071f1, (const uint8_t *)"secret", 6, 0x50c9a0db},
+ {0xf2480c60, (const uint8_t *)"ultimate", 8, 0xf973daf8},
+ {0x2d2feb3d, (const uint8_t *)"vector", 6, 0x344ac03d},
+ {0x7490310a, (const uint8_t *)"walrus", 6, 0x6d1408ef},
+ {0x97d247d4, (const uint8_t *)"xeno", 4, 0xe62670b5},
+ {0x93cf7599, (const uint8_t *)"yelling", 7, 0x1b36da38},
+ {0x73c84278, (const uint8_t *)"zlib", 4, 0x6432d127},
+ {0x228a87d1, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0x997107d0},
+ {0xa7a048d0, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0xdc567274},
+ {0x1f0ded40, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xdcc63870},
+ {0xa804a62f, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x6926cffd},
+ {0x508fae6a, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xb52b38bc},
+ {0xe5adaf4f, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xf83b8178},
+ {0x67136a40, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0xc5213070},
+ {0xb00c4a10, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0xbc7648b0},
+ {0x2e0c84b5, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0xd8123a72},
+ {0x81238d44, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0xd5ac5620},
+ {0xf853aa92, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0xceae099d},
+ {0x5a692325, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0xb07d2b24},
+ {0x3275b9f, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x24ce91df},
+ {0x38371feb, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x707b3b30},
+ {0xafc8bf62, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x16abc6a9},
+ {0x9b07db73, (const uint8_t *)"70684206568419061514", 20, 0xae1fb7b7},
+ {0xe75b214, (const uint8_t *)"42015093765128581010", 20, 0xd4eecd2d},
+ {0x72d0fe6f, (const uint8_t *)"88214814356148806939", 20, 0x4660ec7},
+ {0xf857a4b1, (const uint8_t *)"43472694284527343838", 20, 0xfd8afdf7},
+ {0x54b8e14, (const uint8_t *)"49769333513942933689", 20, 0xc6d1b5f2},
+ {0xd6aa5616, (const uint8_t *)"54979784887993251199", 20, 0x32476461},
+ {0x11e63098, (const uint8_t *)"58360544869206793220", 20, 0xd917cf1a},
+ {0xbe92385, (const uint8_t *)"27347953487840714234", 20, 0x4ad14a12},
+ {0x49511de0, (const uint8_t *)"07650690295365319082", 20, 0xe37b5c6c},
+ {0x3db13bc1, (const uint8_t *)"42655507906821911703", 20, 0x7cc497f1},
+ {0xbb899bea, (const uint8_t *)"29977409200786225655", 20, 0x99781bb2},
+ {0xf6cd9436, (const uint8_t *)"85181542907229116674", 20, 0x132256a1},
+ {0x9109e6c3, (const uint8_t *)"87963594337989416799", 20, 0xbfdb2c83},
+ {0x75770fc, (const uint8_t *)"21395988329504168551", 20, 0x8d9d1e81},
+ {0x69b1d19b, (const uint8_t *)"51991013580943379423", 20, 0x7b6d4404},
+ {0xc6132975, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x8619f010},
+ {0xd58cb00c, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x15746ac3},
+ {0xb63b8caa, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xaccf812f},
+ {0x8a45a2b8, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x78af45de},
+ {0xcbe95b78, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x25b06b59},
+ {0x4ef8a54b, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x4ba0d08f},
+ {0x76ad267a, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0xe26b6aac},
+ {0x569e613c, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x7e2b0a66},
+ {0x36aa61da, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xb3430dc7},
+ {0xf67222df, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x626c17a},
+ {0x74b34fd3, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xccf98060},
+ {0x351fd770, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xd8b95312},
+ {0xc45aef77, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xbb1c9912},
+ {0xc45aef77, (const uint8_t *)
+ "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
+ "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
+ "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
+ "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
+ "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&"
+ "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 600, 0x888AFA5B}
+};
+
+class crc32_variant : public ::testing::TestWithParam<crc32_test> {
+public:
+ void hash(crc32_test param, crc32_func crc32) {
+ uint32_t crc = 0;
+ if (param.buf != NULL) {
+ if (param.len) {
+ crc = crc32(param.crc, param.buf, param.len);
+ } else {
+ crc = param.crc;
+ }
+ }
+ EXPECT_EQ(crc, param.expect);
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(crc32, crc32_variant, testing::ValuesIn(tests));
+
+#define TEST_CRC32(name, func, support_flag) \
+ TEST_P(crc32_variant, name) { \
+ if (!support_flag) { \
+ GTEST_SKIP(); \
+ return; \
+ } \
+ hash(GetParam(), func); \
+ }
+
+TEST_CRC32(braid, crc32_braid, 1)
+
+#ifdef ARM_ACLE_CRC_HASH
+TEST_CRC32(acle, crc32_acle, arm_cpu_has_crc32)
+#elif defined(POWER8_VSX_CRC32)
+TEST_CRC32(power8, crc32_power8, power_cpu_has_arch_2_07)
+#elif defined(S390_CRC32_VX)
+TEST_CRC32(vx, PREFIX(s390_crc32_vx), PREFIX(s390_cpu_has_vx))
+#elif defined(X86_PCLMULQDQ_CRC)
+TEST_CRC32(pclmulqdq, crc32_pclmulqdq, x86_cpu_has_pclmulqdq)
+#endif
diff --git a/src/zlib-ng/test/test_cve-2003-0107.cc b/src/zlib-ng/test/test_cve-2003-0107.cc
new file mode 100644
index 0000000..9d9e5b0
--- /dev/null
+++ b/src/zlib-ng/test/test_cve-2003-0107.cc
@@ -0,0 +1,28 @@
+// https://www.securityfocus.com/archive/1/312869 --- originally by Richard Kettlewell
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <gtest/gtest.h>
+
+#if !defined(_WIN32) && defined(ZLIB_COMPAT)
+TEST(gzip, cve_2003_0107) {
+ gzFile f;
+ int ret;
+
+ f = gzopen("/dev/null", "w");
+ EXPECT_TRUE(f != NULL);
+
+ ret = gzprintf(f, "%10240s", "");
+ printf("gzprintf -> %d\n", ret);
+ ret = gzclose(f);
+ printf("gzclose -> %d [%d]\n", ret, errno);
+}
+#endif
diff --git a/src/zlib-ng/test/test_deflate_bound.cc b/src/zlib-ng/test/test_deflate_bound.cc
new file mode 100644
index 0000000..27020c6
--- /dev/null
+++ b/src/zlib-ng/test/test_deflate_bound.cc
@@ -0,0 +1,90 @@
+/* test_deflate_bound.cc - Test deflateBound() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+#define MAX_LENGTH (32)
+
+typedef struct {
+ int32_t level;
+ int32_t window_size;
+ int32_t mem_level;
+} deflate_bound_test;
+
+static const deflate_bound_test tests[] = {
+ {0, MAX_WBITS + 16, 1},
+ {Z_BEST_SPEED, MAX_WBITS, MAX_MEM_LEVEL},
+ {Z_BEST_COMPRESSION, MAX_WBITS, MAX_MEM_LEVEL}
+};
+
+class deflate_bound_variant : public testing::TestWithParam<deflate_bound_test> {
+public:
+ void estimate(deflate_bound_test param) {
+ PREFIX3(stream) c_stream;
+ int estimate_len = 0;
+ uint8_t *uncompressed = NULL;
+ uint8_t *out_buf = NULL;
+ int err;
+
+ uncompressed = (uint8_t *)malloc(MAX_LENGTH);
+ ASSERT_TRUE(uncompressed != NULL);
+ memset(uncompressed, 'a', MAX_LENGTH);
+
+ for (int32_t i = 0; i < MAX_LENGTH; i++) {
+ memset(&c_stream, 0, sizeof(c_stream));
+
+ c_stream.avail_in = i;
+ c_stream.next_in = (z_const unsigned char *)uncompressed;
+ c_stream.avail_out = 0;
+ c_stream.next_out = out_buf;
+
+ err = PREFIX(deflateInit2)(&c_stream, param.level, Z_DEFLATED,
+ param.window_size, param.mem_level, Z_DEFAULT_STRATEGY);
+ EXPECT_EQ(err, Z_OK);
+
+ /* calculate actual output length and update structure */
+ estimate_len = PREFIX(deflateBound)(&c_stream, i);
+ out_buf = (uint8_t *)malloc(estimate_len);
+
+ if (out_buf != NULL) {
+ /* update zlib configuration */
+ c_stream.avail_out = estimate_len;
+ c_stream.next_out = out_buf;
+
+ /* do the compression */
+ err = PREFIX(deflate)(&c_stream, Z_FINISH);
+ EXPECT_EQ(err, Z_STREAM_END) <<
+ "level: " << param.level << "\n" <<
+ "window_size: " << param.window_size << "\n" <<
+ "mem_level: " << param.mem_level << "\n" <<
+ "length: " << i;
+
+ free(out_buf);
+ }
+
+ err = PREFIX(deflateEnd)(&c_stream);
+ EXPECT_EQ(err, Z_OK);
+ }
+
+ free(uncompressed);
+ }
+};
+
+TEST_P(deflate_bound_variant, estimate) {
+ estimate(GetParam());
+}
+
+INSTANTIATE_TEST_SUITE_P(deflate_bound, deflate_bound_variant, testing::ValuesIn(tests));
diff --git a/src/zlib-ng/test/test_deflate_copy.cc b/src/zlib-ng/test/test_deflate_copy.cc
new file mode 100644
index 0000000..4adc9be
--- /dev/null
+++ b/src/zlib-ng/test/test_deflate_copy.cc
@@ -0,0 +1,60 @@
+/* test_deflate_copy.cc - Test deflateCopy() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "deflate.h"
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, copy) {
+ PREFIX3(stream) c_stream, c_stream_copy;
+ uint8_t compr[128];
+ z_size_t compr_len = sizeof(compr);
+ int err;
+
+ memset(&c_stream, 0, sizeof(c_stream));
+ memset(&c_stream_copy, 0, sizeof(c_stream_copy));
+
+ err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
+ EXPECT_EQ(err, Z_OK);
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.next_out = compr;
+
+ while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) {
+ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+ err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+ EXPECT_EQ(err, Z_OK);
+ }
+
+ /* Finish the stream, still forcing small buffers: */
+ for (;;) {
+ c_stream.avail_out = 1;
+ err = PREFIX(deflate)(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ EXPECT_EQ(err, Z_OK);
+ }
+
+ err = PREFIX(deflateCopy)(&c_stream_copy, &c_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ EXPECT_EQ(c_stream.state->status, c_stream_copy.state->status);
+
+ err = PREFIX(deflateEnd)(&c_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ err = PREFIX(deflateEnd)(&c_stream_copy);
+ EXPECT_EQ(err, Z_OK);
+}
diff --git a/src/zlib-ng/test/test_deflate_dict.cc b/src/zlib-ng/test/test_deflate_dict.cc
new file mode 100644
index 0000000..7a060a8
--- /dev/null
+++ b/src/zlib-ng/test/test_deflate_dict.cc
@@ -0,0 +1,54 @@
+/* test_deflate_dict.cc - Test deflateGetDictionary() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, dictionary) {
+ PREFIX3(stream) c_stream;
+ uint8_t compr[128];
+ uint32_t compr_len = sizeof(compr);
+ uint8_t *dict_new = NULL;
+ uint32_t *dict_len;
+ int err;
+
+ memset(&c_stream, 0, sizeof(c_stream));
+
+ err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
+ EXPECT_EQ(err, Z_OK);
+
+ c_stream.next_out = compr;
+ c_stream.avail_out = compr_len;
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.avail_in = (uint32_t)hello_len;
+
+ err = PREFIX(deflate)(&c_stream, Z_FINISH);
+ EXPECT_EQ(err, Z_STREAM_END);
+
+ dict_new = (uint8_t *)calloc(256, 1);
+ ASSERT_TRUE(dict_new != NULL);
+ dict_len = (uint32_t *)calloc(4, 1);
+ ASSERT_TRUE(dict_len != NULL);
+
+ err = PREFIX(deflateGetDictionary)(&c_stream, dict_new, dict_len);
+ EXPECT_EQ(err, Z_OK);
+
+ err = PREFIX(deflateEnd)(&c_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ free(dict_new);
+ free(dict_len);
+}
diff --git a/src/zlib-ng/test/test_deflate_hash_head_0.cc b/src/zlib-ng/test/test_deflate_hash_head_0.cc
new file mode 100644
index 0000000..4a4e4b6
--- /dev/null
+++ b/src/zlib-ng/test/test_deflate_hash_head_0.cc
@@ -0,0 +1,83 @@
+/* Generated by fuzzing - test hash_head == 0 handling. */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, hash_head_0) {
+ PREFIX3(stream) strm;
+ int err;
+
+ memset(&strm, 0, sizeof(strm));
+ err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, -15, 4, Z_HUFFMAN_ONLY);
+ EXPECT_EQ(err, Z_OK);
+
+ unsigned char next_in[9698];
+ memset(next_in, 0x30, sizeof(next_in));
+ next_in[8193] = 0x00;
+ next_in[8194] = 0x00;
+ next_in[8195] = 0x00;
+ next_in[8199] = 0x8a;
+ strm.next_in = next_in;
+ unsigned char next_out[21572];
+ strm.next_out = next_out;
+
+ strm.avail_in = 0;
+ strm.avail_out = 1348;
+ err = PREFIX(deflateParams(&strm, 3, Z_FILTERED));
+ EXPECT_EQ(err, Z_OK);
+
+ strm.avail_in = 6728;
+ strm.avail_out = 2696;
+ err = PREFIX(deflate(&strm, Z_SYNC_FLUSH));
+ EXPECT_EQ(err, Z_OK);
+
+ strm.avail_in = 15;
+ strm.avail_out = 1348;
+ err = PREFIX(deflateParams(&strm, 9, Z_FILTERED));
+ EXPECT_EQ(err, Z_OK);
+
+ strm.avail_in = 1453;
+ strm.avail_out = 1348;
+ err = PREFIX(deflate(&strm, Z_FULL_FLUSH));
+ EXPECT_EQ(err, Z_OK);
+
+ strm.avail_in = (uint32_t)(next_in + sizeof(next_in) - strm.next_in);
+ strm.avail_out = (uint32_t)(next_out + sizeof(next_out) - strm.next_out);
+ err = PREFIX(deflate)(&strm, Z_FINISH);
+ EXPECT_EQ(err, Z_STREAM_END);
+
+ uint32_t compressed_size = (uint32_t)(strm.next_out - next_out);
+
+ err = PREFIX(deflateEnd)(&strm);
+ EXPECT_EQ(err, Z_OK);
+
+ memset(&strm, 0, sizeof(strm));
+ err = PREFIX(inflateInit2)(&strm, -15);
+ EXPECT_EQ(err, Z_OK);
+
+ strm.next_in = next_out;
+ strm.avail_in = compressed_size;
+ unsigned char uncompressed[sizeof(next_in)];
+ strm.next_out = uncompressed;
+ strm.avail_out = sizeof(uncompressed);
+
+ err = PREFIX(inflate)(&strm, Z_NO_FLUSH);
+ EXPECT_EQ(err, Z_STREAM_END);
+
+ err = PREFIX(inflateEnd)(&strm);
+ EXPECT_EQ(err, Z_OK);
+
+ EXPECT_TRUE(memcmp(uncompressed, next_in, sizeof(uncompressed)) == 0);
+}
diff --git a/src/zlib-ng/test/test_deflate_header.cc b/src/zlib-ng/test/test_deflate_header.cc
new file mode 100644
index 0000000..92f4612
--- /dev/null
+++ b/src/zlib-ng/test/test_deflate_header.cc
@@ -0,0 +1,68 @@
+/* test_deflate_header.cc - Test deflateSetHeader() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, header) {
+ PREFIX3(stream) c_stream;
+ PREFIX(gz_header) *head;
+ uint8_t compr[128];
+ z_size_t compr_len = sizeof(compr);
+ int err;
+
+ head = (PREFIX(gz_header) *)calloc(1, sizeof(PREFIX(gz_header)));
+ ASSERT_TRUE(head != NULL);
+
+ memset(&c_stream, 0, sizeof(c_stream));
+
+ /* gzip */
+ err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY);
+ EXPECT_EQ(err, Z_OK);
+
+ head->text = 1;
+ head->comment = (uint8_t *)"comment";
+ head->name = (uint8_t *)"name";
+ head->hcrc = 1;
+ head->extra = (uint8_t *)"extra";
+ head->extra_len = (uint32_t)strlen((const char *)head->extra);
+
+ err = PREFIX(deflateSetHeader)(&c_stream, head);
+ EXPECT_EQ(err, Z_OK);
+
+ PREFIX(deflateBound)(&c_stream, (unsigned long)compr_len);
+
+ c_stream.next_in = (unsigned char *)hello;
+ c_stream.next_out = compr;
+
+ while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) {
+ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+ err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+ EXPECT_EQ(err, Z_OK);
+ }
+
+ /* Finish the stream, still forcing small buffers: */
+ for (;;) {
+ c_stream.avail_out = 1;
+ err = PREFIX(deflate)(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ EXPECT_EQ(err, Z_OK);
+ }
+
+ err = PREFIX(deflateEnd)(&c_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ free(head);
+}
diff --git a/src/zlib-ng/test/test_deflate_params.cc b/src/zlib-ng/test/test_deflate_params.cc
new file mode 100644
index 0000000..f5f5066
--- /dev/null
+++ b/src/zlib-ng/test/test_deflate_params.cc
@@ -0,0 +1,143 @@
+/* test_deflate_params.cc - Test deflate() with dynamic change of compression level */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <time.h>
+
+#include "deflate.h"
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+#define COMPR_BUFFER_SIZE (48 * 1024)
+#define UNCOMPR_BUFFER_SIZE (64 * 1024)
+#define UNCOMPR_RAND_SIZE (8 * 1024)
+
+TEST(deflate, params) {
+ PREFIX3(stream) c_stream, d_stream;
+ uint8_t *compr, *uncompr;
+ uint32_t compr_len, uncompr_len;
+ uint32_t diff;
+ int32_t i;
+ time_t now;
+ int err;
+#ifndef ZLIB_COMPAT
+ int level = -1;
+ int strategy = -1;
+ zng_deflate_param_value params[2];
+
+ params[0].param = Z_DEFLATE_LEVEL;
+ params[0].buf = &level;
+ params[0].size = sizeof(level);
+
+ params[1].param = Z_DEFLATE_STRATEGY;
+ params[1].buf = &strategy;
+ params[1].size = sizeof(strategy);
+#endif
+
+ memset(&c_stream, 0, sizeof(c_stream));
+ memset(&d_stream, 0, sizeof(d_stream));
+
+ compr = (uint8_t *)calloc(1, COMPR_BUFFER_SIZE);
+ ASSERT_TRUE(compr != NULL);
+ uncompr = (uint8_t *)calloc(1, UNCOMPR_BUFFER_SIZE);
+ ASSERT_TRUE(uncompr != NULL);
+
+ compr_len = COMPR_BUFFER_SIZE;
+ uncompr_len = UNCOMPR_BUFFER_SIZE;
+
+ srand((unsigned)time(&now));
+ for (i = 0; i < UNCOMPR_RAND_SIZE; i++)
+ uncompr[i] = (uint8_t)(rand() % 256);
+
+ err = PREFIX(deflateInit)(&c_stream, Z_BEST_SPEED);
+ EXPECT_EQ(err, Z_OK);
+
+ c_stream.next_out = compr;
+ c_stream.avail_out = compr_len;
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = uncompr_len;
+
+ err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+ EXPECT_EQ(err, Z_OK);
+ EXPECT_EQ(c_stream.avail_in, 0);
+
+ /* Feed in already compressed data and switch to no compression: */
+#ifndef ZLIB_COMPAT
+ zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
+ EXPECT_EQ(level, Z_BEST_SPEED);
+ EXPECT_EQ(strategy, Z_DEFAULT_STRATEGY);
+
+ level = Z_NO_COMPRESSION;
+ strategy = Z_DEFAULT_STRATEGY;
+ zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
+#else
+ PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+#endif
+
+ c_stream.next_in = compr;
+ diff = (unsigned int)(c_stream.next_out - compr);
+ c_stream.avail_in = diff;
+ err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+ EXPECT_EQ(err, Z_OK);
+
+ /* Switch back to compressing mode: */
+#ifndef ZLIB_COMPAT
+ level = -1;
+ strategy = -1;
+ zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
+ EXPECT_EQ(level, Z_NO_COMPRESSION);
+ EXPECT_EQ(strategy, Z_DEFAULT_STRATEGY);
+
+ level = Z_BEST_COMPRESSION;
+ strategy = Z_FILTERED;
+ zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
+#else
+ PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+#endif
+
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (unsigned int)uncompr_len;
+ err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+ EXPECT_EQ(err, Z_OK);
+
+ err = PREFIX(deflate)(&c_stream, Z_FINISH);
+ EXPECT_EQ(err, Z_STREAM_END);
+
+ err = PREFIX(deflateEnd)(&c_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (unsigned int)compr_len;
+
+ err = PREFIX(inflateInit)(&d_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ do {
+ d_stream.next_out = uncompr; /* discard the output */
+ d_stream.avail_out = uncompr_len;
+ err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END)
+ break;
+ EXPECT_EQ(err, Z_OK);
+ } while (err == Z_OK);
+
+ err = PREFIX(inflateEnd)(&d_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ EXPECT_EQ(d_stream.total_out, (2 * uncompr_len) + diff);
+
+ free(compr);
+ free(uncompr);
+}
diff --git a/src/zlib-ng/test/test_deflate_pending.cc b/src/zlib-ng/test/test_deflate_pending.cc
new file mode 100644
index 0000000..b107dd4
--- /dev/null
+++ b/src/zlib-ng/test/test_deflate_pending.cc
@@ -0,0 +1,66 @@
+/* test_deflate_pending.cc - Test deflatePending() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, pending) {
+ PREFIX3(stream) c_stream;
+ uint8_t compr[128];
+ z_size_t compr_len = sizeof(compr);
+ int *bits;
+ unsigned *ped;
+ int err;
+
+
+ bits = (int *)calloc(256, 1);
+ ASSERT_TRUE(bits != NULL);
+ ped = (unsigned *)calloc(256, 1);
+ ASSERT_TRUE(ped != NULL);
+
+ memset(&c_stream, 0, sizeof(c_stream));
+
+ err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
+ EXPECT_EQ(err, Z_OK);
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.next_out = compr;
+
+ while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) {
+ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+ err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+ EXPECT_EQ(err, Z_OK);
+ }
+
+ err = PREFIX(deflatePending)(&c_stream, ped, bits);
+ EXPECT_EQ(err, Z_OK);
+
+ EXPECT_GE(*bits, 0);
+ EXPECT_LE(*bits, 7);
+
+ /* Finish the stream, still forcing small buffers: */
+ for (;;) {
+ c_stream.avail_out = 1;
+ err = PREFIX(deflate)(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ EXPECT_EQ(err, Z_OK);
+ }
+
+ err = PREFIX(deflateEnd)(&c_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ free(bits);
+ free(ped);
+}
diff --git a/src/zlib-ng/test/test_deflate_prime.cc b/src/zlib-ng/test/test_deflate_prime.cc
new file mode 100644
index 0000000..135a2d4
--- /dev/null
+++ b/src/zlib-ng/test/test_deflate_prime.cc
@@ -0,0 +1,91 @@
+/* test_deflate_prime.cc - Test deflatePrime() wrapping gzip around deflate stream */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, prime) {
+ PREFIX3(stream) c_stream, d_stream;
+ uint8_t compr[128], uncompr[128];
+ z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr);
+ uint32_t crc = 0;
+ int err;
+
+ memset(&c_stream, 0, sizeof(c_stream));
+ memset(&d_stream, 0, sizeof(d_stream));
+
+ /* Raw deflate windowBits is -15 */
+ err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
+ EXPECT_EQ(err, Z_OK);
+
+ /* Gzip magic number */
+ err = PREFIX(deflatePrime)(&c_stream, 16, 0x8b1f);
+ EXPECT_EQ(err, Z_OK);
+ /* Gzip compression method (deflate) */
+ err = PREFIX(deflatePrime)(&c_stream, 8, 0x08);
+ EXPECT_EQ(err, Z_OK);
+ /* Gzip flags (one byte, using two odd bit calls) */
+ err = PREFIX(deflatePrime)(&c_stream, 3, 0x0);
+ EXPECT_EQ(err, Z_OK);
+ err = PREFIX(deflatePrime)(&c_stream, 5, 0x0);
+ EXPECT_EQ(err, Z_OK);
+ /* Gzip modified time */
+ err = PREFIX(deflatePrime)(&c_stream, 32, 0x0);
+ EXPECT_EQ(err, Z_OK);
+ /* Gzip extra flags */
+ err = PREFIX(deflatePrime)(&c_stream, 8, 0x0);
+ EXPECT_EQ(err, Z_OK);
+ /* Gzip operating system */
+ err = PREFIX(deflatePrime)(&c_stream, 8, 255);
+ EXPECT_EQ(err, Z_OK);
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.avail_in = (uint32_t)hello_len;
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uint32_t)compr_len;
+
+ err = PREFIX(deflate)(&c_stream, Z_FINISH);
+ EXPECT_EQ(err, Z_STREAM_END);
+
+ /* Gzip uncompressed data crc32 */
+ crc = PREFIX(crc32)(0, (const uint8_t *)hello, (uint32_t)hello_len);
+ err = PREFIX(deflatePrime)(&c_stream, 32, crc);
+ EXPECT_EQ(err, Z_OK);
+ /* Gzip uncompressed data length */
+ err = PREFIX(deflatePrime)(&c_stream, 32, (uint32_t)hello_len);
+ EXPECT_EQ(err, Z_OK);
+
+ err = PREFIX(deflateEnd)(&c_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uint32_t)c_stream.total_out;
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uint32_t)uncompr_len;
+ d_stream.total_in = 0;
+ d_stream.total_out = 0;
+
+ /* Inflate with gzip header */
+ err = PREFIX(inflateInit2)(&d_stream, MAX_WBITS + 32);
+ EXPECT_EQ(err, Z_OK);
+
+ err = PREFIX(inflate)(&d_stream, Z_FINISH);
+ EXPECT_EQ(err, Z_BUF_ERROR);
+
+ err = PREFIX(inflateEnd)(&d_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ EXPECT_STREQ((char *)uncompr, hello);
+}
diff --git a/src/zlib-ng/test/test_deflate_quick_bi_valid.cc b/src/zlib-ng/test/test_deflate_quick_bi_valid.cc
new file mode 100644
index 0000000..8ce4c22
--- /dev/null
+++ b/src/zlib-ng/test/test_deflate_quick_bi_valid.cc
@@ -0,0 +1,80 @@
+/* Generated by fuzzing - test bi_valid handling in deflate_quick(). */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate_quick, bi_valid) {
+ PREFIX3(stream) strm;
+ int err;
+
+ memset(&strm, 0, sizeof(strm));
+
+ err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, 31, 1, Z_FILTERED);
+ EXPECT_EQ(err, Z_OK);
+
+ z_const unsigned char next_in[554] = {
+ 0x8d, 0xff, 0xff, 0xff, 0xa2, 0x00, 0x00, 0xff, 0x00, 0x15, 0x1b, 0x1b, 0xa2, 0xa2, 0xaf, 0xa2,
+ 0xa2, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1b, 0x3f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x1e, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x07, 0x01, 0x18, 0x00, 0x22, 0x00,
+ 0x00, 0x00, 0xfd, 0x39, 0xff, 0x00, 0x00, 0x00, 0x1b, 0xfd, 0x3b, 0x00, 0x68, 0x00, 0x00, 0x01,
+ 0xff, 0xff, 0xff, 0x57, 0xf8, 0x1e, 0x00, 0x00, 0xf2, 0xf2, 0xf2, 0xf2, 0xfa, 0xff, 0xff, 0xff,
+ 0xff, 0x7e, 0x00, 0x00, 0x4a, 0x00, 0xc5, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x02, 0x01, 0x01, 0x00, 0xa2, 0x08, 0x00, 0x00, 0x00, 0x00, 0x27, 0x4a, 0x4a, 0x4a, 0x32,
+ 0x00, 0xf9, 0xff, 0x00, 0x02, 0x9a, 0xff, 0x00, 0x00, 0x3f, 0x50, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x3d, 0x00, 0x08, 0x2f, 0x20, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x7a, 0x7a, 0x9e, 0xff, 0xff, 0x00, 0x1b, 0x1b, 0x04, 0x00, 0x1b, 0x1b,
+ 0x1b, 0x1b, 0x00, 0x00, 0x00, 0xaf, 0xad, 0xaf, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x2e, 0xff,
+ 0xff, 0x2e, 0xc1, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x70, 0x00, 0x00, 0x00, 0xda, 0x67, 0x01,
+ 0x47, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x01, 0x00, 0x3f,
+ 0x54, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x34, 0x3e, 0xc5, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x00, 0x00, 0x00, 0x40, 0x1b, 0x1b, 0x88, 0x1b, 0x1b,
+ 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1f, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x50, 0x3e, 0x7a, 0x7a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x87, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0xff, 0x3d, 0x00, 0x11, 0x4d, 0x00, 0x00, 0x01, 0xd4, 0xd4, 0xd4, 0xd4, 0x2d, 0xd4,
+ 0xd4, 0xff, 0xff, 0xff, 0xfa, 0x01, 0xd4, 0x00, 0xd4, 0x00, 0x00, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4,
+ 0xd4, 0x1e, 0x1e, 0x1e, 0x1e, 0x00, 0x00, 0xfe, 0xf9, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x00,
+ 0x16, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00,
+ 0xff, 0x2b, 0x2b, 0x2b, 0x2b, 0x35, 0xd4, 0xd4, 0x47, 0x3f, 0xd4, 0xd4, 0xd6, 0xd4, 0xd4, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x32, 0x4a, 0x4a, 0x4a, 0x4a, 0x71, 0x00, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
+ 0x1f, 0x1b, 0x1b, 0x1b, 0x57, 0x57, 0x57, 0x57, 0x00, 0x00, 0x1b, 0x08, 0x2b, 0x16, 0xc3, 0x00,
+ 0x00, 0x00, 0x29, 0x30, 0x03, 0xff, 0x03, 0x03, 0x03, 0x03, 0x07, 0x00, 0x00, 0x01, 0x0b, 0xff,
+ 0xff, 0xf5, 0xf5, 0xf5, 0x00, 0x00, 0xfe, 0xfa, 0x0f, 0x0f, 0x08, 0x00, 0xff, 0x00, 0x53, 0x3f,
+ 0x00, 0x04, 0x5d, 0xa8, 0x2e, 0xff, 0xff, 0x00, 0x2f, 0x2f, 0x05, 0xff, 0xff, 0xff, 0x2f, 0x2f,
+ 0x2f, 0x0a, 0x0a, 0x0a, 0x0a, 0x30, 0xff, 0xff, 0xff, 0xf0, 0x0a, 0x0a, 0x0a, 0x00, 0xff, 0x3f,
+ 0x4f, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x71, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x71, 0x71, 0x00, 0x71, 0x71, 0x71, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff,
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0x3f, 0x00, 0xfa, 0x71, 0x71, 0x71, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x71, 0x71, 0x71, 0x71, 0x71};
+ strm.next_in = next_in;
+ unsigned char next_out[1236];
+ strm.next_out = next_out;
+
+ strm.avail_in = 554;
+ strm.avail_out = 31;
+
+ err = PREFIX(deflate)(&strm, Z_FINISH);
+ EXPECT_EQ(err, Z_OK);
+
+ strm.avail_in = 0;
+ strm.avail_out = 498;
+ err = PREFIX(deflate)(&strm, Z_FINISH);
+ EXPECT_EQ(err, Z_STREAM_END);
+
+ err = PREFIX(deflateEnd)(&strm);
+ EXPECT_EQ(err, Z_OK);
+}
diff --git a/src/zlib-ng/test/deflate_quick_block_open.c b/src/zlib-ng/test/test_deflate_quick_block_open.cc
index 9526533..b8703ae 100644
--- a/src/zlib-ng/test/deflate_quick_block_open.c
+++ b/src/zlib-ng/test/test_deflate_quick_block_open.cc
@@ -11,17 +11,19 @@
#include <stdlib.h>
#include <string.h>
-int main() {
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate_quick, block_open) {
PREFIX3(stream) strm;
+ int err;
memset(&strm, 0, sizeof(strm));
- int ret = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, -15, 1, Z_FILTERED);
- if (ret != Z_OK) {
- fprintf(stderr, "deflateInit2() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
+ err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, -15, 1, Z_FILTERED);
+ EXPECT_EQ(err, Z_OK);
- z_const unsigned char next_in[494] =
+ z_const unsigned char next_in[495] =
"\x1d\x1d\x00\x00\x00\x4a\x4a\x4a\xaf\xaf\xaf\xaf\x4a\x4a\x4a\x4a"
"\x3f\x3e\xaf\xff\xff\xff\x11\xff\xff\xff\xff\xdf\x00\x00\x00\x01"
"\x3f\x7d\x00\x50\x00\x00\xc8\x01\x2b\x60\xc8\x00\x24\x06\xff\xff"
@@ -62,28 +64,19 @@ int main() {
strm.avail_out = (uint32_t)(next_out + sizeof(next_out) - strm.next_out);
if (strm.avail_out > 38)
strm.avail_out = 38;
- ret = PREFIX(deflate)(&strm, Z_FINISH);
- if (ret == Z_STREAM_END)
+ err = PREFIX(deflate)(&strm, Z_FINISH);
+ if (err == Z_STREAM_END)
break;
- if (ret != Z_OK) {
- fprintf(stderr, "deflate() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
+ EXPECT_EQ(err, Z_OK);
}
uint32_t compressed_size = (uint32_t)(strm.next_out - next_out);
- ret = PREFIX(deflateEnd)(&strm);
- if (ret != Z_OK) {
- fprintf(stderr, "deflateEnd() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
+ err = PREFIX(deflateEnd)(&strm);
+ EXPECT_EQ(err, Z_OK);
memset(&strm, 0, sizeof(strm));
- ret = PREFIX(inflateInit2)(&strm, -15);
- if (ret != Z_OK) {
- fprintf(stderr, "inflateInit2() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
+ err = PREFIX(inflateInit2)(&strm, -15);
+ EXPECT_EQ(err, Z_OK);
strm.next_in = next_out;
strm.avail_in = compressed_size;
@@ -91,20 +84,11 @@ int main() {
strm.next_out = uncompressed;
strm.avail_out = sizeof(uncompressed);
- ret = PREFIX(inflate)(&strm, Z_NO_FLUSH);
- if (ret != Z_STREAM_END) {
- fprintf(stderr, "inflate() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
+ err = PREFIX(inflate)(&strm, Z_NO_FLUSH);
+ EXPECT_EQ(err, Z_STREAM_END);
- ret = PREFIX(inflateEnd)(&strm);
- if (ret != Z_OK) {
- fprintf(stderr, "inflateEnd() failed with code %d\n", ret);
- return EXIT_FAILURE;
- }
+ err = PREFIX(inflateEnd)(&strm);
+ EXPECT_EQ(err, Z_OK);
- if (memcmp(uncompressed, next_in, sizeof(uncompressed)) != 0) {
- fprintf(stderr, "Uncompressed data differs from the original\n");
- return EXIT_FAILURE;
- }
+ EXPECT_TRUE(memcmp(uncompressed, next_in, sizeof(uncompressed)) == 0);
}
diff --git a/src/zlib-ng/test/test_deflate_tune.cc b/src/zlib-ng/test/test_deflate_tune.cc
new file mode 100644
index 0000000..9921ee6
--- /dev/null
+++ b/src/zlib-ng/test/test_deflate_tune.cc
@@ -0,0 +1,56 @@
+/* test_deflate_tune.cc - Test deflateTune() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, tune) {
+ PREFIX3(stream) c_stream;
+ uint8_t compr[128];
+ z_size_t compr_len = sizeof(compr);
+ int err;
+ int good_length = 3;
+ int max_lazy = 5;
+ int nice_length = 18;
+ int max_chain = 6;
+
+ memset(&c_stream, 0, sizeof(c_stream));
+
+ err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
+ EXPECT_EQ(err, Z_OK);
+
+ err = PREFIX(deflateTune)(&c_stream, good_length, max_lazy,nice_length, max_chain);
+ EXPECT_EQ(err, Z_OK);
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.next_out = compr;
+
+ while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) {
+ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+ err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+ EXPECT_EQ(err, Z_OK);
+ }
+
+ /* Finish the stream, still forcing small buffers: */
+ for (;;) {
+ c_stream.avail_out = 1;
+ err = PREFIX(deflate)(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ EXPECT_EQ(err, Z_OK);
+ }
+
+ err = PREFIX(deflateEnd)(&c_stream);
+ EXPECT_EQ(err, Z_OK);
+}
diff --git a/src/zlib-ng/test/test_dict.cc b/src/zlib-ng/test/test_dict.cc
new file mode 100644
index 0000000..af9662e
--- /dev/null
+++ b/src/zlib-ng/test/test_dict.cc
@@ -0,0 +1,96 @@
+/* test_dict.cc - Test deflate() and inflate() with preset dictionary */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+/* Maximum dictionary size, according to inflateGetDictionary() description. */
+#define MAX_DICTIONARY_SIZE 32768
+
+static const char dictionary[] = "hello";
+
+TEST(dictionary, basic) {
+ PREFIX3(stream) c_stream, d_stream;
+ uint8_t compr[128], uncompr[128];
+ z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr);
+ uint32_t dict_adler = 0;
+ uint8_t check_dict[MAX_DICTIONARY_SIZE];
+ uint32_t check_dict_len = 0;
+ int err;
+
+ memset(&c_stream, 0, sizeof(c_stream));
+ memset(&d_stream, 0, sizeof(d_stream));
+
+ err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
+ EXPECT_EQ(err, Z_OK);
+
+ err = PREFIX(deflateSetDictionary)(&c_stream,
+ (const unsigned char *)dictionary, (int)sizeof(dictionary));
+ EXPECT_EQ(err, Z_OK);
+
+ dict_adler = c_stream.adler;
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uint32_t)compr_len;
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.avail_in = (uint32_t)hello_len;
+
+ err = PREFIX(deflate)(&c_stream, Z_FINISH);
+ EXPECT_EQ(err, Z_STREAM_END);
+
+ err = PREFIX(deflateEnd)(&c_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ strcpy((char*)uncompr, "garbage garbage garbage");
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (unsigned int)compr_len;
+
+ err = PREFIX(inflateInit)(&d_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (unsigned int)uncompr_len;
+
+ for (;;) {
+ err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END)
+ break;
+ if (err == Z_NEED_DICT) {
+ EXPECT_EQ(d_stream.adler, dict_adler);
+ err = PREFIX(inflateSetDictionary)(&d_stream, (const unsigned char*)dictionary,
+ (uint32_t)sizeof(dictionary));
+ EXPECT_EQ(d_stream.adler, dict_adler);
+ }
+ EXPECT_EQ(err, Z_OK);
+ }
+
+ err = PREFIX(inflateGetDictionary)(&d_stream, NULL, &check_dict_len);
+ EXPECT_EQ(err, Z_OK);
+#ifndef S390_DFLTCC_INFLATE
+ EXPECT_GE(check_dict_len, sizeof(dictionary));
+#endif
+
+ err = PREFIX(inflateGetDictionary)(&d_stream, check_dict, &check_dict_len);
+ EXPECT_EQ(err, Z_OK);
+#ifndef S390_DFLTCC_INFLATE
+ EXPECT_TRUE(memcmp(dictionary, check_dict, sizeof(dictionary)) == 0);
+#endif
+
+ err = PREFIX(inflateEnd)(&d_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ EXPECT_TRUE(strncmp((char*)uncompr, hello, sizeof(hello)) == 0);
+}
diff --git a/src/zlib-ng/test/test_gzio.cc b/src/zlib-ng/test/test_gzio.cc
new file mode 100644
index 0000000..46baa02
--- /dev/null
+++ b/src/zlib-ng/test/test_gzio.cc
@@ -0,0 +1,105 @@
+/* test_gzio.cc - Test read/write of .gz files */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+#define TESTFILE "foo.gz"
+
+TEST(gzip, readwrite) {
+#ifdef NO_GZCOMPRESS
+ fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
+ GTEST_SKIP();
+#else
+ uint8_t compr[128], uncompr[128];
+ uint32_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr);
+ size_t read;
+ int64_t pos;
+ gzFile file;
+ int err;
+
+ /* Write gz file with test data */
+ file = PREFIX(gzopen)(TESTFILE, "wb");
+ ASSERT_TRUE(file != NULL);
+ /* Write hello, hello! using gzputs and gzprintf */
+ PREFIX(gzputc)(file, 'h');
+ EXPECT_EQ(PREFIX(gzputs)(file, "ello"), 4);
+ EXPECT_EQ(PREFIX(gzprintf)(file, ", %s!", "hello"), 8);
+ /* Write string null-teriminator using gzseek */
+ EXPECT_GE(PREFIX(gzseek)(file, 1L, SEEK_CUR), 0);
+ /* Write hello, hello! using gzfwrite using best compression level */
+ EXPECT_EQ(PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY), Z_OK);
+ EXPECT_NE(PREFIX(gzfwrite)(hello, hello_len, 1, file), 0);
+ /* Flush compressed bytes to file */
+ EXPECT_EQ(PREFIX(gzflush)(file, Z_SYNC_FLUSH), Z_OK);
+ compr_len = (uint32_t)PREFIX(gzoffset)(file);
+ EXPECT_GE(compr_len, 0UL);
+ PREFIX(gzclose)(file);
+
+ /* Open gz file we previously wrote */
+ file = PREFIX(gzopen)(TESTFILE, "rb");
+ ASSERT_TRUE(file != NULL);
+
+ /* Read uncompressed data - hello, hello! string twice */
+ strcpy((char*)uncompr, "garbages");
+ EXPECT_EQ(PREFIX(gzread)(file, uncompr, (unsigned)uncompr_len), (int)(hello_len + hello_len));
+ EXPECT_STREQ((char*)uncompr, hello);
+
+ /* Check position at the end of the gz file */
+ EXPECT_EQ(PREFIX(gzeof)(file), 1);
+
+ /* Seek backwards mid-string and check char reading with gzgetc and gzungetc */
+ pos = PREFIX(gzseek)(file, -22L, SEEK_CUR);
+ EXPECT_EQ(pos, 6);
+ EXPECT_EQ(PREFIX(gztell)(file), pos);
+ EXPECT_EQ(PREFIX(gzgetc)(file), ' ');
+ EXPECT_EQ(PREFIX(gzungetc)(' ', file), ' ');
+ /* Read first hello, hello! string with gzgets */
+ strcpy((char*)uncompr, "garbages");
+ PREFIX(gzgets)(file, (char*)uncompr, (int)uncompr_len);
+ EXPECT_EQ(strlen((char*)uncompr), 7); /* " hello!" */
+ EXPECT_STREQ((char*)uncompr, hello + 6);
+
+ /* Seek to second hello, hello! string */
+ pos = PREFIX(gzseek)(file, 14L, SEEK_SET);
+ EXPECT_EQ(pos, 14);
+ EXPECT_EQ(PREFIX(gztell)(file), pos);
+
+ /* Check position not at end of file */
+ EXPECT_EQ(PREFIX(gzeof)(file), 0);
+ /* Read first hello, hello! string with gzfread */
+ strcpy((char*)uncompr, "garbages");
+ read = PREFIX(gzfread)(uncompr, uncompr_len, 1, file);
+ EXPECT_STREQ((const char *)uncompr, hello);
+
+ pos = PREFIX(gzoffset)(file);
+ EXPECT_GE(pos, 0);
+ EXPECT_EQ(pos, (compr_len + 10));
+
+ /* Trigger an error and clear it with gzclearerr */
+ PREFIX(gzfread)(uncompr, (size_t)-1, (size_t)-1, file);
+ PREFIX(gzerror)(file, &err);
+ EXPECT_NE(err, 0);
+
+ PREFIX(gzclearerr)(file);
+ PREFIX(gzerror)(file, &err);
+ EXPECT_EQ(err, 0);
+
+ PREFIX(gzclose)(file);
+
+ EXPECT_EQ(PREFIX(gzclose)(NULL), Z_STREAM_ERROR);
+ Z_UNUSED(read);
+#endif
+}
diff --git a/src/zlib-ng/test/test_inflate_adler32.cc b/src/zlib-ng/test/test_inflate_adler32.cc
new file mode 100644
index 0000000..e17cf6b
--- /dev/null
+++ b/src/zlib-ng/test/test_inflate_adler32.cc
@@ -0,0 +1,48 @@
+/* GH-1066 - inflate small amount of data and validate with adler32 checksum. */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+const char* original = "The quick brown fox jumped over the lazy dog";
+
+z_const unsigned char compressed[] = {
+ 0x78, 0x9c, 0x0b, 0xc9, 0x48, 0x55, 0x28, 0x2c, 0xcd, 0x4c, 0xce, 0x56, 0x48,
+ 0x2a, 0xca, 0x2f, 0xcf, 0x53, 0x48, 0xcb, 0xaf, 0x50, 0xc8, 0x2a, 0xcd, 0x2d,
+ 0x48, 0x4d, 0x51, 0xc8, 0x2f, 0x4b, 0x2d, 0x52, 0x28, 0xc9, 0x48, 0x55, 0xc8,
+ 0x49, 0xac, 0xaa, 0x54, 0x48, 0xc9, 0x4f, 0x07, 0x00, 0x6b, 0x93, 0x10, 0x30
+};
+
+TEST(inflate, adler32) {
+ unsigned char uncompressed[1024];
+ PREFIX3(stream) strm;
+
+ memset(&strm, 0, sizeof(strm));
+
+ int err = PREFIX(inflateInit2)(&strm, 32 + MAX_WBITS);
+ EXPECT_EQ(err, Z_OK);
+
+ strm.next_in = compressed;
+ strm.avail_in = sizeof(compressed);
+ strm.next_out = uncompressed;
+ strm.avail_out = sizeof(uncompressed);
+
+ err = PREFIX(inflate)(&strm, Z_NO_FLUSH);
+ EXPECT_EQ(err, Z_STREAM_END);
+
+ err = PREFIX(inflateEnd)(&strm);
+ EXPECT_EQ(err, Z_OK);
+
+ EXPECT_TRUE(memcmp(uncompressed, original, MIN(strm.total_out, strlen(original))) == 0);
+}
diff --git a/src/zlib-ng/test/test_inflate_sync.cc b/src/zlib-ng/test/test_inflate_sync.cc
new file mode 100644
index 0000000..a79d867
--- /dev/null
+++ b/src/zlib-ng/test/test_inflate_sync.cc
@@ -0,0 +1,75 @@
+/* test_inflate_sync.cc - Test inflateSync using full flush deflate and corrupted data */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(inflate, sync) {
+ PREFIX3(stream) c_stream, d_stream;
+ uint8_t compr[128], uncompr[128];
+ z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr);
+ int err;
+
+ memset(&c_stream, 0, sizeof(c_stream));
+
+ /* build compressed stream with full flush */
+ err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
+ EXPECT_EQ(err, Z_OK);
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.next_out = compr;
+ c_stream.avail_in = 3;
+ c_stream.avail_out = (uint32_t)compr_len;
+
+ err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH);
+ EXPECT_EQ(err, Z_OK);
+
+ /* force an error in first compressed block */
+ compr[3]++;
+ c_stream.avail_in = hello_len-3;
+
+ err = PREFIX(deflate)(&c_stream, Z_FINISH);
+ EXPECT_EQ(err, Z_STREAM_END);
+
+ err = PREFIX(deflateEnd)(&c_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ compr_len = (z_size_t)c_stream.total_out;
+
+ memset(&d_stream, 0, sizeof(d_stream));
+ /* just read the zlib header */
+ d_stream.next_in = compr;
+ d_stream.avail_in = 2;
+
+ err = PREFIX(inflateInit)(&d_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uint32_t)uncompr_len;
+
+ err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
+ EXPECT_EQ(err, Z_OK);
+
+ /* read all compressed data, but skip damaged part */
+ d_stream.avail_in = (uint32_t)compr_len-2;
+ err = PREFIX(inflateSync)(&d_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ err = PREFIX(inflate)(&d_stream, Z_FINISH);
+ EXPECT_EQ(err, Z_STREAM_END);
+
+ err = PREFIX(inflateEnd)(&d_stream);
+ EXPECT_EQ(err, Z_OK);
+}
diff --git a/src/zlib-ng/test/test_large_buffers.cc b/src/zlib-ng/test/test_large_buffers.cc
new file mode 100644
index 0000000..9bf1339
--- /dev/null
+++ b/src/zlib-ng/test/test_large_buffers.cc
@@ -0,0 +1,87 @@
+/* test_large_buffers.cc - Test deflate() and inflate() with large buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+#define COMPR_BUFFER_SIZE (48 * 1024)
+#define UNCOMPR_BUFFER_SIZE (32 * 1024)
+#define UNCOMPR_RAND_SIZE (8 * 1024)
+
+TEST(deflate, large_buffers) {
+ PREFIX3(stream) c_stream, d_stream;
+ uint8_t *compr, *uncompr;
+ uint32_t compr_len, uncompr_len;
+ int32_t i;
+ time_t now;
+ int err;
+
+ memset(&c_stream, 0, sizeof(c_stream));
+ memset(&d_stream, 0, sizeof(d_stream));
+
+ compr = (uint8_t *)calloc(1, COMPR_BUFFER_SIZE);
+ ASSERT_TRUE(compr != NULL);
+ uncompr = (uint8_t *)calloc(1, UNCOMPR_BUFFER_SIZE);
+ ASSERT_TRUE(uncompr != NULL);
+
+ compr_len = COMPR_BUFFER_SIZE;
+ uncompr_len = UNCOMPR_BUFFER_SIZE;
+
+ srand((unsigned)time(&now));
+ for (i = 0; i < UNCOMPR_RAND_SIZE; i++)
+ uncompr[i] = (uint8_t)(rand() % 256);
+
+ err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
+ EXPECT_EQ(err, Z_OK);
+
+ c_stream.next_out = compr;
+ c_stream.avail_out = compr_len;
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = uncompr_len;
+
+ err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+ EXPECT_EQ(err, Z_OK);
+ EXPECT_EQ(c_stream.avail_in, 0);
+
+ err = PREFIX(deflate)(&c_stream, Z_FINISH);
+ EXPECT_EQ(err, Z_STREAM_END);
+
+ err = PREFIX(deflateEnd)(&c_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = compr_len;
+ d_stream.next_out = uncompr;
+
+ err = PREFIX(inflateInit)(&d_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ for (;;) {
+ d_stream.next_out = uncompr; /* discard the output */
+ d_stream.avail_out = uncompr_len;
+ err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ EXPECT_EQ(err, Z_OK);
+ }
+
+ err = PREFIX(inflateEnd)(&d_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ EXPECT_EQ(d_stream.total_out, uncompr_len);
+
+ free(compr);
+ free(uncompr);
+}
diff --git a/src/zlib-ng/test/test_main.cc b/src/zlib-ng/test/test_main.cc
new file mode 100644
index 0000000..c129db2
--- /dev/null
+++ b/src/zlib-ng/test/test_main.cc
@@ -0,0 +1,17 @@
+/* test_test.cc - Main entry point for test framework */
+
+#include <stdio.h>
+
+#include "gtest/gtest.h"
+
+extern "C" {
+# include "zbuild.h"
+# include "cpu_features.h"
+}
+
+GTEST_API_ int main(int argc, char **argv) {
+ printf("Running main() from %s\n", __FILE__);
+ cpu_check_features();
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+} \ No newline at end of file
diff --git a/src/zlib-ng/test/test_shared.h b/src/zlib-ng/test/test_shared.h
new file mode 100644
index 0000000..f942967
--- /dev/null
+++ b/src/zlib-ng/test/test_shared.h
@@ -0,0 +1,2 @@
+static const char hello[] = "hello, hello!";
+static const int hello_len = sizeof(hello);
diff --git a/src/zlib-ng/test/test_small_buffers.cc b/src/zlib-ng/test/test_small_buffers.cc
new file mode 100644
index 0000000..bb3449f
--- /dev/null
+++ b/src/zlib-ng/test/test_small_buffers.cc
@@ -0,0 +1,69 @@
+/* test_small_buffers.cc - Test deflate() and inflate() with small buffers */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(deflate, small_buffers) {
+ PREFIX3(stream) c_stream, d_stream;
+ uint8_t compr[128], uncompr[128];
+ z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr);
+ int err;
+
+ memset(&c_stream, 0, sizeof(c_stream));
+ memset(&d_stream, 0, sizeof(d_stream));
+
+ err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
+ EXPECT_EQ(err, Z_OK);
+
+ c_stream.next_in = (z_const unsigned char *)hello;
+ c_stream.next_out = compr;
+
+ while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) {
+ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+ err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
+ EXPECT_EQ(err, Z_OK);
+ }
+ /* Finish the stream, still forcing small buffers */
+ for (;;) {
+ c_stream.avail_out = 1;
+ err = PREFIX(deflate)(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ EXPECT_EQ(err, Z_OK);
+ }
+
+ err = PREFIX(deflateEnd)(&c_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.next_in = compr;
+ d_stream.next_out = uncompr;
+
+ err = PREFIX(inflateInit)(&d_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ while (d_stream.total_out < uncompr_len && d_stream.total_in < compr_len) {
+ d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+ err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ EXPECT_EQ(err, Z_OK);
+ }
+
+ err = PREFIX(inflateEnd)(&d_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ EXPECT_STREQ((char*)uncompr, hello);
+}
diff --git a/src/zlib-ng/test/test_version.cc b/src/zlib-ng/test/test_version.cc
new file mode 100644
index 0000000..fda8790
--- /dev/null
+++ b/src/zlib-ng/test/test_version.cc
@@ -0,0 +1,27 @@
+/* test_version.cc - Test zVersion() and zlibCompileFlags() */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test_shared.h"
+
+#include <gtest/gtest.h>
+
+TEST(version, basic) {
+ static const char *my_version = PREFIX2(VERSION);
+
+ EXPECT_EQ(zVersion()[0], my_version[0]);
+ EXPECT_STREQ(zVersion(), PREFIX2(VERSION));
+
+ printf("zlib-ng version %s = 0x%08lx, compile flags = 0x%lx\n",
+ ZLIBNG_VERSION, ZLIBNG_VERNUM, PREFIX(zlibCompileFlags)());
+}