tor-commits
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 216106 discussions
20 Jul '12
commit 5b0749cf7d62047d604fd5b8bfd5b96063d153c0
Author: Zack Weinberg <zackw(a)cmu.edu>
Date: Mon Apr 30 11:21:47 2012 -0700
Use zlib's crc32c. Add tests for crc32c.
---
Makefile.am | 4 +-
src/crc32.cc | 86 ------------------------
src/crc32.h | 10 ---
src/test/unittest_zlib.cc | 158 +++++++++++++++++++++++++++++++++++++++++++++
src/zpack.cc | 24 ++++++-
src/zpack.h | 2 +
6 files changed, 184 insertions(+), 100 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 11f8ac3..3ded164 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -30,7 +30,6 @@ STEGANOGRAPHERS = \
libstegotorus_a_SOURCES = \
src/base64.cc \
- src/crc32.cc \
src/connections.cc \
src/crypt.cc \
src/network.cc \
@@ -52,7 +51,8 @@ UTGROUPS = \
src/test/unittest_pdfsteg.cc \
src/test/unittest_socks.cc \
src/test/unittest_config.cc \
- src/test/unittest_transfer.cc
+ src/test/unittest_transfer.cc \
+ src/test/unittest_zlib.cc
unittests_SOURCES = \
src/test/tinytest.cc \
diff --git a/src/crc32.cc b/src/crc32.cc
deleted file mode 100644
index 151eae1..0000000
--- a/src/crc32.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Copyright 2011, 2012 SRI International
- * See LICENSE for other credits and copying information
- */
-#include "util.h"
-#include "crc32.h"
-
-#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
-
-static const unsigned int crc_c[256] = {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
- 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
- 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
- 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
- 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
- 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
- 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
- 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
- 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
- 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
- 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
- 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
- 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
- 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
- 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
- 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
- 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
- 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
- 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
- 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
- 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
- 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
- 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
- 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
- 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
- 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
- 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
- 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
- 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
- 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
- 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
- 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
- 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
- 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
- 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
- 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
- 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
- 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
- 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
- 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
- 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
- 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
- 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
- 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
- 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
- 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
- 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
- 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
- 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
- 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
- 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
- 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
-};
-
-unsigned int
-generate_crc32c(const char *buffer, size_t length)
-{
- size_t i;
- unsigned int crc32 = ~0L;
-
- for (i = 0; i < length; i++){
- CRC32C(crc32, (unsigned char)buffer[i]);
- }
- return ~crc32;
-}
diff --git a/src/crc32.h b/src/crc32.h
deleted file mode 100644
index 67bb48a..0000000
--- a/src/crc32.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Copyright 2011, 2012 SRI International
- * See LICENSE for other credits and copying information
- */
-
-#ifndef _CRC32_H
-#define _CRC32_H
-
-unsigned int generate_crc32c(const char *string, size_t length);
-
-#endif
diff --git a/src/test/unittest_zlib.cc b/src/test/unittest_zlib.cc
new file mode 100644
index 0000000..fa447dd
--- /dev/null
+++ b/src/test/unittest_zlib.cc
@@ -0,0 +1,158 @@
+/* Copyright 2012 SRI International
+ * See LICENSE for other credits and copying information
+ */
+
+#include "util.h"
+#include "unittest.h"
+
+#include "zlib.h"
+#include "zpack.h"
+
+/* Smoke tests for zlib. */
+
+static void
+test_zlib_crc32(void *)
+{
+ // Test vectors generated using a standalone crc32 implementation
+ // of unknown provenance, and then validated with the implementation
+ // built into zlib. If anyone knows a reliable source for "official"
+ // test vectors for the 0x04C11DB7 polynomial, please let us know.
+
+ struct hash_testvec
+ {
+ const uint8_t *text;
+ size_t tlen;
+ uint32_t digest;
+ };
+ static const struct hash_testvec tests[] = {
+#define T(s, d) { (const uint8_t *)s, sizeof s - 1, 0x##d }
+
+ // the empty string
+ T("", 00000000),
+
+ // 4-byte messages
+ T("\x00\x00\x00\x00", 2144df1c),
+ T("\x11\x11\x11\x11", ed6c2543),
+ T("\x22\x22\x22\x22", 62642de3),
+ T("\x33\x33\x33\x33", ae4cd7bc),
+ T("\x44\x44\x44\x44", a7053ae2),
+ T("\x55\x55\x55\x55", 6b2dc0bd),
+ T("\x66\x66\x66\x66", e425c81d),
+ T("\x77\x77\x77\x77", 280d3242),
+ T("\x88\x88\x88\x88", f6b612a1),
+ T("\x99\x99\x99\x99", 3a9ee8fe),
+ T("\xaa\xaa\xaa\xaa", b596e05e),
+ T("\xbb\xbb\xbb\xbb", 79be1a01),
+ T("\xcc\xcc\xcc\xcc", 70f7f75f),
+ T("\xdd\xdd\xdd\xdd", bcdf0d00),
+ T("\xee\xee\xee\xee", 33d705a0),
+ T("\xff\xff\xff\xff", ffffffff),
+ T("\x40\x49\x0f\xdb", 538226fd), // pi (IEEE single)
+
+ // 8-byte messages
+ T("\x00\x00\x00\x00\x00\x00\x00\x00", 6522df69),
+ T("\x00\x00\x00\x00\xff\xff\xff\xff", bb99ff8a),
+ T("\xff\xff\xff\xff\x00\x00\x00\x00", ffffffff),
+ T("\xff\xff\xff\xff\xff\xff\xff\xff", 2144df1c),
+ T("\x55\x55\x55\x55\x55\x55\x55\x55", efd02285),
+ T("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", abb622f0),
+ T("\x40\x09\x21\xfb\x54\x44\x2d\x18", 2a8990d8), // pi (IEEE double)
+
+ // 32-byte messages: all possible bytes occur once
+ T("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ 91267e8a),
+ T("\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f",
+ f6a606e3),
+ T("\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f",
+ 5e268e58),
+ T("\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f",
+ 39a6f631),
+ T("\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f",
+ d456996f),
+ T("\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf",
+ b3d6e106),
+ T("\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf",
+ 1b5669bd),
+ T("\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ 7cd611d4),
+
+ // 26- to 40-letter pangrams from Wikipedia, all nonletters removed,
+ // all lowercase
+ T("cwmfjordbankglyphsvextquiz", 81308910),
+ T("nymphsblitzquickvexdwarfjog", c9b201ae),
+ T("brickquizwhangsjumpyveldtfox", c17836eb),
+ T("vexednymphsgoforquickwaltzjob", ea8c2360),
+ T("bothfickledwarvesjinxmypigquiz", 3c7c5f5f),
+ T("ficklejinxbogdwarvesspymathquiz", 75862807),
+ T("averybadquackmightjinxzippyfowls", 563373aa),
+ T("aquickbrownfoxjumpsoverthelazydog", 56df6600),
+ T("quizzicaltwinsprovedmyhijackbugfix", b7140701),
+ T("whenzombiesarrivequicklyfaxjudgepat", c398efae),
+ T("heavyboxesperformquickwaltzesandjigs", bb60c571),
+ T("fakebugsputinwaxjonquilsdrivehimcrazy", a1c524f0),
+ T("wovensilkpyjamasexchangedforbluequartz", 9a7f064e),
+ T("thequickonyxgoblinjumpsoverthelazydwarf", 3b478712),
+ T("amazinglyfewdiscothequesprovidejukeboxes", 7ddde4a3),
+
+ // self-describing pangram by Lee Sallows (SciAm, 1984)
+ T("This Pangram contains four as, one b, two cs, one d, thirty es, "
+ "six fs, five gs, seven hs, eleven is, one j, one k, two ls, two ms, "
+ "eighteen ns, fifteen os, two ps, one q, five rs, twenty-seven ss, "
+ "eighteen ts, two us, seven vs, eight ws, two xs, three ys, & one z.",
+ 3ab5b411),
+
+ // "Lion-Eating Poet in the Stone Den" by Chao Yuen Ren,
+ // Simplified Chinese text in UTF-8
+ T("\xe3\x80\x8a\xe6\x96\xbd\xe6\xb0\x8f\xe9\xa3\x9f\xe7\x8b\xae\xe5\x8f"
+ "\xb2\xe3\x80\x8b \xe7\x9f\xb3\xe5\xae\xa4\xe8\xaf\x97\xe5\xa3\xab\xe6"
+ "\x96\xbd\xe6\xb0\x8f\xef\xbc\x8c\xe5\x97\x9c\xe7\x8b\xae\xef\xbc\x8c"
+ "\xe8\xaa\x93\xe9\xa3\x9f\xe5\x8d\x81\xe7\x8b\xae\xe3\x80\x82 \xe6\xb0"
+ "\x8f\xe6\x97\xb6\xe6\x97\xb6\xe9\x80\x82\xe5\xb8\x82\xe8\xa7\x86\xe7"
+ "\x8b\xae\xe3\x80\x82 \xe5\x8d\x81\xe6\x97\xb6\xef\xbc\x8c\xe9\x80\x82"
+ "\xe5\x8d\x81\xe7\x8b\xae\xe9\x80\x82\xe5\xb8\x82\xe3\x80\x82 \xe6\x98"
+ "\xaf\xe6\x97\xb6\xef\xbc\x8c\xe9\x80\x82\xe6\x96\xbd\xe6\xb0\x8f\xe9"
+ "\x80\x82\xe5\xb8\x82\xe3\x80\x82 \xe6\xb0\x8f\xe8\xa7\x86\xe6\x98\xaf"
+ "\xe5\x8d\x81\xe7\x8b\xae\xef\xbc\x8c\xe6\x81\x83\xe7\x9f\xa2\xe5\x8a"
+ "\xbf\xef\xbc\x8c\xe4\xbd\xbf\xe6\x98\xaf\xe5\x8d\x81\xe7\x8b\xae\xe9"
+ "\x80\x9d\xe4\xb8\x96\xe3\x80\x82 \xe6\xb0\x8f\xe6\x8b\xbe\xe6\x98\xaf"
+ "\xe5\x8d\x81\xe7\x8b\xae\xe5\xb0\xb8\xef\xbc\x8c\xe9\x80\x82\xe7\x9f"
+ "\xb3\xe5\xae\xa4\xe3\x80\x82 \xe7\x9f\xb3\xe5\xae\xa4\xe6\xb9\xbf\xef"
+ "\xbc\x8c\xe6\xb0\x8f\xe4\xbd\xbf\xe4\xbe\x8d\xe6\x8b\xad\xe7\x9f\xb3"
+ "\xe5\xae\xa4\xe3\x80\x82 \xe7\x9f\xb3\xe5\xae\xa4\xe6\x8b\xad\xef\xbc"
+ "\x8c\xe6\xb0\x8f\xe5\xa7\x8b\xe8\xaf\x95\xe9\xa3\x9f\xe6\x98\xaf\xe5"
+ "\x8d\x81\xe7\x8b\xae\xe3\x80\x82 \xe9\xa3\x9f\xe6\x97\xb6\xef\xbc\x8c"
+ "\xe5\xa7\x8b\xe8\xaf\x86\xe6\x98\xaf\xe5\x8d\x81\xe7\x8b\xae\xe5\xb0"
+ "\xb8\xef\xbc\x8c\xe5\xae\x9e\xe5\x8d\x81\xe7\x9f\xb3\xe7\x8b\xae\xe5"
+ "\xb0\xb8\xe3\x80\x82 \xe8\xaf\x95\xe9\x87\x8a\xe6\x98\xaf\xe4\xba\x8b"
+ "\xe3\x80\x82",
+ 1fa606e5),
+
+ { 0, 0, 0 }
+#undef T
+ };
+
+ int i;
+ uint32_t h;
+ for (i = 0; tests[i].text; i++) {
+ h = generate_crc32c(tests[i].text, tests[i].tlen);
+ tt_assert_op_type(h,==,tests[i].digest, unsigned int, "%08x");
+ }
+
+ end:;
+}
+
+#define T(name) \
+ { #name, test_zlib_##name, 0, 0, 0 }
+
+struct testcase_t zlib_tests[] = {
+ T(crc32),
+ END_OF_TESTCASES
+};
diff --git a/src/zpack.cc b/src/zpack.cc
index 751c96e..2a7adfc 100644
--- a/src/zpack.cc
+++ b/src/zpack.cc
@@ -4,7 +4,8 @@
#include "util.h"
#include "zpack.h"
#include "zlib.h"
-#include "crc32.h"
+
+#include <limits>
#define CHUNK 16384
@@ -296,7 +297,7 @@ gzDeflate(const char *source, size_t slen, char *dest, size_t dlen,
return -1;
}
- crc = generate_crc32c(source, slen);
+ crc = generate_crc32c((const uint8_t *)source, slen);
c = (unsigned char *)dest + 10 + z.total_out;
c[0] = (crc >> 0) & 0xff;
@@ -312,3 +313,22 @@ gzDeflate(const char *source, size_t slen, char *dest, size_t dlen,
return -1;
return 10 + z.total_out + 8;
}
+
+uint32_t
+generate_crc32c(const uint8_t *string, size_t length)
+{
+ // zlib doesn't believe in size_t. When size_t is bigger than uInt,
+ // we theoretically could break the operation up into uInt-sized
+ // chunks to support the full range of size_t, but I doubt we will
+ // ever need to crc32 more than 2^32 bytes, so I'm not bothering.
+ // -- zw, 2012
+ log_assert(length <= std::numeric_limits<uInt>::max());
+
+ uLong crc = crc32(crc32(0, 0, 0), string, length);
+
+ // zlib also doesn't believe 'long' can be more than 32 bits wide.
+ // This shouldn't ever fire unless there is a bug in zlib.
+ log_assert(crc <= std::numeric_limits<uint32_t>::max());
+
+ return crc;
+}
diff --git a/src/zpack.h b/src/zpack.h
index 18bb531..e1e1c2c 100644
--- a/src/zpack.h
+++ b/src/zpack.h
@@ -12,4 +12,6 @@ ssize_t gzInflate(const char *source, size_t slen, char *dest, size_t dlen);
ssize_t gzDeflate(const char *source, size_t slen, char *dest, size_t dlen,
time_t mtime);
+uint32_t generate_crc32c(const uint8_t *string, size_t length);
+
#endif
1
0
[stegotorus/master] Add tests for compression and decompression. Label gzipped data as OS-unknown, not OS-unix.
by zwol@torproject.org 20 Jul '12
by zwol@torproject.org 20 Jul '12
20 Jul '12
commit 7b53fb86cd204afe7e2d410b5fd06cf52c8a186a
Author: Zack Weinberg <zackw(a)cmu.edu>
Date: Mon Apr 30 14:00:10 2012 -0700
Add tests for compression and decompression. Label gzipped data as OS-unknown, not OS-unix.
---
src/test/unittest_zlib.cc | 611 +++++++++++++++++++++++++++++++++++----------
src/zpack.cc | 2 +-
2 files changed, 481 insertions(+), 132 deletions(-)
diff --git a/src/test/unittest_zlib.cc b/src/test/unittest_zlib.cc
index fa447dd..2d655b2 100644
--- a/src/test/unittest_zlib.cc
+++ b/src/test/unittest_zlib.cc
@@ -8,142 +8,487 @@
#include "zlib.h"
#include "zpack.h"
-/* Smoke tests for zlib. */
+// Smoke tests for zlib.
+//
+// CRC values generated using a standalone crc32 implementation of
+// unknown provenance, and then validated with the implementation
+// built into zlib.
+//
+// Compressed strings generated with Python's 'zlib' and 'gzip'
+// modules, which wrap zlib, so they only constitute a round-trip
+// test, not a proper test. Z_DEFAULT_COMPRESSION (6) used in all cases.
+//
+// If anyone knows a reliable source for "official" test vectors for
+// CRC polynomial 04C11DB7 and/or RFC 1950 through 1952, please let us
+// know.
+
+struct zlib_testvec
+{
+ const uint8_t *text;
+ size_t tlen;
+ const uint8_t *zlibbed;
+ size_t zlen;
+ const uint8_t *gzipped;
+ size_t glen;
+ uint32_t crc32;
+};
+
+#define GZH(g) \
+ "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff" g
+
+#define T(t, z, g, c) \
+ { (const uint8_t *)t, sizeof t - 1, \
+ (const uint8_t *)z, sizeof z - 1, \
+ (const uint8_t *)GZH(g), sizeof GZH(g) - 1, \
+ 0x##c }
+
+const zlib_testvec testvecs[] = {
+ // the empty string
+ T("",
+ "\x78\x9c\x03\x00\x00\x00\x00\x01",
+ "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 00000000),
+
+ // 4-byte messages
+ T("\x00\x00\x00\x00",
+ "\x78\x9c\x63\x60\x60\x60\x00\x00\x00\x04\x00\x01",
+ "\x63\x60\x60\x60\x00\x00\x1c\xdf\x44\x21\x04\x00\x00\x00",
+ 2144df1c),
+ T("\x11\x11\x11\x11",
+ "\x78\x9c\x13\x14\x14\x14\x04\x00\x00\xae\x00\x45",
+ "\x13\x14\x14\x14\x04\x00\x43\x25\x6c\xed\x04\x00\x00\x00",
+ ed6c2543),
+ T("\x22\x22\x22\x22",
+ "\x78\x9c\x53\x52\x52\x52\x02\x00\x01\x58\x00\x89",
+ "\x53\x52\x52\x52\x02\x00\xe3\x2d\x64\x62\x04\x00\x00\x00",
+ 62642de3),
+ T("\x33\x33\x33\x33",
+ "\x78\x9c\x33\x36\x36\x36\x06\x00\x02\x02\x00\xcd",
+ "\x33\x36\x36\x36\x06\x00\xbc\xd7\x4c\xae\x04\x00\x00\x00",
+ ae4cd7bc),
+ T("\x44\x44\x44\x44",
+ "\x78\x9c\x73\x71\x71\x71\x01\x00\x02\xac\x01\x11",
+ "\x73\x71\x71\x71\x01\x00\xe2\x3a\x05\xa7\x04\x00\x00\x00",
+ a7053ae2),
+ T("\x55\x55\x55\x55",
+ "\x78\x9c\x0b\x0d\x0d\x0d\x05\x00\x03\x56\x01\x55",
+ "\x0b\x0d\x0d\x0d\x05\x00\xbd\xc0\x2d\x6b\x04\x00\x00\x00",
+ 6b2dc0bd),
+ T("\x66\x66\x66\x66",
+ "\x78\x9c\x4b\x4b\x4b\x4b\x03\x00\x04\x00\x01\x99",
+ "\x4b\x4b\x4b\x4b\x03\x00\x1d\xc8\x25\xe4\x04\x00\x00\x00",
+ e425c81d),
+ T("\x77\x77\x77\x77",
+ "\x78\x9c\x2b\x2f\x2f\x2f\x07\x00\x04\xaa\x01\xdd",
+ "\x2b\x2f\x2f\x2f\x07\x00\x42\x32\x0d\x28\x04\x00\x00\x00",
+ 280d3242),
+ T("\x88\x88\x88\x88",
+ "\x78\x9c\xeb\xe8\xe8\xe8\x00\x00\x05\x54\x02\x21",
+ "\xeb\xe8\xe8\xe8\x00\x00\xa1\x12\xb6\xf6\x04\x00\x00\x00",
+ f6b612a1),
+ T("\x99\x99\x99\x99",
+ "\x78\x9c\x9b\x39\x73\xe6\x4c\x00\x05\xfe\x02\x65",
+ "\x9b\x39\x73\xe6\x4c\x00\xfe\xe8\x9e\x3a\x04\x00\x00\x00",
+ 3a9ee8fe),
+ T("\xaa\xaa\xaa\xaa",
+ "\x78\x9c\x5b\xb5\x6a\xd5\x2a\x00\x06\xa8\x02\xa9",
+ "\x5b\xb5\x6a\xd5\x2a\x00\x5e\xe0\x96\xb5\x04\x00\x00\x00",
+ b596e05e),
+ T("\xbb\xbb\xbb\xbb",
+ "\x78\x9c\xdb\xbd\x7b\xf7\x6e\x00\x07\x52\x02\xed",
+ "\xdb\xbd\x7b\xf7\x6e\x00\x01\x1a\xbe\x79\x04\x00\x00\x00",
+ 79be1a01),
+ T("\xcc\xcc\xcc\xcc",
+ "\x78\x9c\x3b\x73\xe6\xcc\x19\x00\x07\xfc\x03\x31",
+ "\x3b\x73\xe6\xcc\x19\x00\x5f\xf7\xf7\x70\x04\x00\x00\x00",
+ 70f7f75f),
+ T("\xdd\xdd\xdd\xdd",
+ "\x78\x9c\xbb\x7b\xf7\xee\x5d\x00\x08\xa6\x03\x75",
+ "\xbb\x7b\xf7\xee\x5d\x00\x00\x0d\xdf\xbc\x04\x00\x00\x00",
+ bcdf0d00),
+ T("\xee\xee\xee\xee",
+ "\x78\x9c\x7b\xf7\xee\xdd\x3b\x00\x09\x50\x03\xb9",
+ "\x7b\xf7\xee\xdd\x3b\x00\xa0\x05\xd7\x33\x04\x00\x00\x00",
+ 33d705a0),
+ T("\xff\xff\xff\xff",
+ "\x78\x9c\xfb\xff\xff\xff\x7f\x00\x09\xfa\x03\xfd",
+ "\xfb\xff\xff\xff\x7f\x00\xff\xff\xff\xff\x04\x00\x00\x00",
+ ffffffff),
+ T("\x40\x49\x0f\xdb",
+ "\x78\x9c\x73\xf0\xe4\xbf\x0d\x00\x02\xd8\x01\x74",
+ "\x73\xf0\xe4\xbf\x0d\x00\xfd\x26\x82\x53\x04\x00\x00\x00",
+ 538226fd), // pi (IEEE single)
+
+ // 8-byte messages
+ T("\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x78\x9c\x63\x60\x80\x00\x00\x00\x08\x00\x01",
+ "\x63\x60\x80\x00\x00\x69\xdf\x22\x65\x08\x00\x00\x00",
+ 6522df69),
+ T("\x00\x00\x00\x00\xff\xff\xff\xff",
+ "\x78\x9c\x63\x60\x60\x60\xf8\x0f\x04\x00\x09\xfe\x03\xfd",
+ "\x63\x60\x60\x60\xf8\x0f\x04\x00\x8a\xff\x99\xbb\x08\x00\x00\x00",
+ bb99ff8a),
+ T("\xff\xff\xff\xff\x00\x00\x00\x00",
+ "\x78\x9c\xfb\xff\xff\xff\x7f\x06\x20\x00\x00\x19\xee\x03\xfd",
+ "\xfb\xff\xff\xff\x7f\x06\x20\x00\x00\xff\xff\xff\xff\x08\x00\x00\x00",
+ ffffffff),
+ T("\xff\xff\xff\xff\xff\xff\xff\xff",
+ "\x78\x9c\xfb\xff\x1f\x02\x00\x23\xe4\x07\xf9",
+ "\xfb\xff\x1f\x02\x00\x1c\xdf\x44\x21\x08\x00\x00\x00",
+ 2144df1c),
+ T("\x55\x55\x55\x55\x55\x55\x55\x55",
+ "\x78\x9c\x0b\x0d\x85\x00\x00\x0b\xfc\x02\xa9",
+ "\x0b\x0d\x85\x00\x00\x85\x22\xd0\xef\x08\x00\x00\x00",
+ efd02285),
+ T("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ "\x78\x9c\x5b\xb5\x0a\x02\x00\x17\xf0\x05\x51",
+ "\x5b\xb5\x0a\x02\x00\xf0\x22\xb6\xab\x08\x00\x00\x00",
+ abb622f0),
+ T("\x40\x09\x21\xfb\x54\x44\x2d\x18",
+ "\x78\x9c\x73\xe0\x54\xfc\x1d\xe2\xa2\x2b\x01\x00\x0a\x82\x02\x43",
+ "\x73\xe0\x54\xfc\x1d\xe2\xa2\x2b\x01\x00\xd8\x90\x89\x2a\x08\x00\x00\x00",
+ 2a8990d8), // pi (IEEE double)
+
+ // 32-byte messages: all possible bytes occur once
+ T("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ "\x78\x9c\x63\x60\x64\x62\x66\x61\x65\x63\xe7\xe0\xe4\xe2\xe6\xe1"
+ "\xe5\xe3\x17\x10\x14\x12\x16\x11\x15\x13\x97\x90\x94\x92\x96\x91"
+ "\x95\x93\x07\x00\x15\x70\x01\xf1",
+ "\x63\x60\x64\x62\x66\x61\x65\x63\xe7\xe0\xe4\xe2\xe6\xe1\xe5\xe3"
+ "\x17\x10\x14\x12\x16\x11\x15\x13\x97\x90\x94\x92\x96\x91\x95\x93"
+ "\x07\x00\x8a\x7e\x26\x91\x20\x00\x00\x00",
+ 91267e8a),
+ T("\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f",
+ "\x78\x9c\x53\x50\x54\x52\x56\x51\x55\x53\xd7\xd0\xd4\xd2\xd6\xd1"
+ "\xd5\xd3\x37\x30\x34\x32\x36\x31\x35\x33\xb7\xb0\xb4\xb2\xb6\xb1"
+ "\xb5\xb3\x07\x00\x57\x70\x05\xf1",
+ "\x53\x50\x54\x52\x56\x51\x55\x53\xd7\xd0\xd4\xd2\xd6\xd1\xd5\xd3"
+ "\x37\x30\x34\x32\x36\x31\x35\x33\xb7\xb0\xb4\xb2\xb6\xb1\xb5\xb3"
+ "\x07\x00\xe3\x06\xa6\xf6\x20\x00\x00\x00",
+ f6a606e3),
+ T("\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f",
+ "\x78\x9c\x73\x70\x74\x72\x76\x71\x75\x73\xf7\xf0\xf4\xf2\xf6\xf1"
+ "\xf5\xf3\x0f\x08\x0c\x0a\x0e\x09\x0d\x0b\x8f\x88\x8c\x8a\x8e\x89"
+ "\x8d\x8b\x07\x00\x99\x70\x09\xf1",
+ "\x73\x70\x74\x72\x76\x71\x75\x73\xf7\xf0\xf4\xf2\xf6\xf1\xf5\xf3"
+ "\x0f\x08\x0c\x0a\x0e\x09\x0d\x0b\x8f\x88\x8c\x8a\x8e\x89\x8d\x8b"
+ "\x07\x00\x58\x8e\x26\x5e\x20\x00\x00\x00",
+ 5e268e58),
+ T("\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f",
+ "\x78\x9c\x4b\x48\x4c\x4a\x4e\x49\x4d\x4b\xcf\xc8\xcc\xca\xce\xc9"
+ "\xcd\xcb\x2f\x28\x2c\x2a\x2e\x29\x2d\x2b\xaf\xa8\xac\xaa\xae\xa9"
+ "\xad\xab\x07\x00\xdb\x70\x0d\xf1",
+ "\x4b\x48\x4c\x4a\x4e\x49\x4d\x4b\xcf\xc8\xcc\xca\xce\xc9\xcd\xcb"
+ "\x2f\x28\x2c\x2a\x2e\x29\x2d\x2b\xaf\xa8\xac\xaa\xae\xa9\xad\xab"
+ "\x07\x00\x31\xf6\xa6\x39\x20\x00\x00\x00",
+ 39a6f631),
+ T("\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f",
+ "\x78\x9c\x01\x20\x00\xdf\xff\x80\x81\x82\x83\x84\x85\x86\x87\x88"
+ "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98"
+ "\x99\x9a\x9b\x9c\x9d\x9e\x9f\x1d\x7f\x11\xf1",
+ "\x01\x20\x00\xdf\xff\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a"
+ "\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a"
+ "\x9b\x9c\x9d\x9e\x9f\x6f\x99\x56\xd4\x20\x00\x00\x00",
+ d456996f),
+ T("\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf",
+ "\x78\x9c\x01\x20\x00\xdf\xff\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+ "\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+ "\xb9\xba\xbb\xbc\xbd\xbe\xbf\x5f\x7f\x15\xf1",
+ "\x01\x20\x00\xdf\xff\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa"
+ "\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba"
+ "\xbb\xbc\xbd\xbe\xbf\x06\xe1\xd6\xb3\x20\x00\x00\x00",
+ b3d6e106),
+ T("\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf",
+ "\x78\x9c\x01\x20\x00\xdf\xff\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8"
+ "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
+ "\xd9\xda\xdb\xdc\xdd\xde\xdf\xa1\x7f\x19\xf1",
+ "\x01\x20\x00\xdf\xff\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca"
+ "\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda"
+ "\xdb\xdc\xdd\xde\xdf\xbd\x69\x56\x1b\x20\x00\x00\x00",
+ 1b5669bd),
+ T("\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ "\x78\x9c\x01\x20\x00\xdf\xff\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
+ "\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8"
+ "\xf9\xfa\xfb\xfc\xfd\xfe\xff\xe3\x7f\x1d\xf1",
+ "\x01\x20\x00\xdf\xff\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea"
+ "\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa"
+ "\xfb\xfc\xfd\xfe\xff\xd4\x11\xd6\x7c\x20\x00\x00\x00",
+ 7cd611d4),
+
+ // 26- to 40-letter pangrams from Wikipedia, all nonletters removed,
+ // all lowercase
+ T("cwmfjordbankglyphsvextquiz",
+ "\x78\x9c\x4b\x2e\xcf\x4d\xcb\xca\x2f\x4a\x49\x4a\xcc\xcb\x4e\xcf"
+ "\xa9\x2c\xc8\x28\x2e\x4b\xad\x28\x29\x2c\xcd\xac\x02\x00\x93\xd9"
+ "\x0b\x20",
+ "\x4b\x2e\xcf\x4d\xcb\xca\x2f\x4a\x49\x4a\xcc\xcb\x4e\xcf\xa9\x2c"
+ "\xc8\x28\x2e\x4b\xad\x28\x29\x2c\xcd\xac\x02\x00\x10\x89\x30\x81"
+ "\x1a\x00\x00\x00",
+ 81308910),
+ T("nymphsblitzquickvexdwarfjog",
+ "\x78\x9c\xcb\xab\xcc\x2d\xc8\x28\x4e\xca\xc9\x2c\xa9\x2a\x2c\xcd"
+ "\x4c\xce\x2e\x4b\xad\x48\x29\x4f\x2c\x4a\xcb\xca\x4f\x07\x00\xa2"
+ "\xd1\x0b\x89",
+ "\xcb\xab\xcc\x2d\xc8\x28\x4e\xca\xc9\x2c\xa9\x2a\x2c\xcd\x4c\xce"
+ "\x2e\x4b\xad\x48\x29\x4f\x2c\x4a\xcb\xca\x4f\x07\x00\xae\x01\xb2"
+ "\xc9\x1b\x00\x00\x00",
+ c9b201ae),
+ T("brickquizwhangsjumpyveldtfox",
+ "\x78\x9c\x4b\x2a\xca\x4c\xce\x2e\x2c\xcd\xac\x2a\xcf\x48\xcc\x4b"
+ "\x2f\xce\x2a\xcd\x2d\xa8\x2c\x4b\xcd\x49\x29\x49\xcb\xaf\x00\x00"
+ "\xac\xcf\x0b\xfe",
+ "\x4b\x2a\xca\x4c\xce\x2e\x2c\xcd\xac\x2a\xcf\x48\xcc\x4b\x2f\xce"
+ "\x2a\xcd\x2d\xa8\x2c\x4b\xcd\x49\x29\x49\xcb\xaf\x00\x00\xeb\x36"
+ "\x78\xc1\x1c\x00\x00\x00",
+ c17836eb),
+ T("vexednymphsgoforquickwaltzjob",
+ "\x78\x9c\x2b\x4b\xad\x48\x4d\xc9\xab\xcc\x2d\xc8\x28\x4e\xcf\x4f"
+ "\xcb\x2f\x2a\x2c\xcd\x4c\xce\x2e\x4f\xcc\x29\xa9\xca\xca\x4f\x02"
+ "\x00\xba\x43\x0c\x63",
+ "\x2b\x4b\xad\x48\x4d\xc9\xab\xcc\x2d\xc8\x28\x4e\xcf\x4f\xcb\x2f"
+ "\x2a\x2c\xcd\x4c\xce\x2e\x4f\xcc\x29\xa9\xca\xca\x4f\x02\x00\x60"
+ "\x23\x8c\xea\x1d\x00\x00\x00",
+ ea8c2360),
+ T("bothfickledwarvesjinxmypigquiz",
+ "\x78\x9c\x4b\xca\x2f\xc9\x48\xcb\x4c\xce\xce\x49\x4d\x29\x4f\x2c"
+ "\x2a\x4b\x2d\xce\xca\xcc\xab\xc8\xad\x2c\xc8\x4c\x2f\x2c\xcd\xac"
+ "\x02\x00\xc2\xd3\x0c\xc0",
+ "\x4b\xca\x2f\xc9\x48\xcb\x4c\xce\xce\x49\x4d\x29\x4f\x2c\x2a\x4b"
+ "\x2d\xce\xca\xcc\xab\xc8\xad\x2c\xc8\x4c\x2f\x2c\xcd\xac\x02\x00"
+ "\x5f\x5f\x7c\x3c\x1e\x00\x00\x00",
+ 3c7c5f5f),
+ T("ficklejinxbogdwarvesspymathquiz",
+ "\x78\x9c\x4b\xcb\x4c\xce\xce\x49\xcd\xca\xcc\xab\x48\xca\x4f\x4f"
+ "\x29\x4f\x2c\x2a\x4b\x2d\x2e\x2e\xa8\xcc\x4d\x2c\xc9\x28\x2c\xcd"
+ "\xac\x02\x00\xcf\x8d\x0d\x2b",
+ "\x4b\xcb\x4c\xce\xce\x49\xcd\xca\xcc\xab\x48\xca\x4f\x4f\x29\x4f"
+ "\x2c\x2a\x4b\x2d\x2e\x2e\xa8\xcc\x4d\x2c\xc9\x28\x2c\xcd\xac\x02"
+ "\x00\x07\x28\x86\x75\x1f\x00\x00\x00",
+ 75862807),
+ T("averybadquackmightjinxzippyfowls",
+ "\x78\x9c\x4b\x2c\x4b\x2d\xaa\x4c\x4a\x4c\x29\x2c\x4d\x4c\xce\xce"
+ "\xcd\x4c\xcf\x28\xc9\xca\xcc\xab\xa8\xca\x2c\x28\xa8\x4c\xcb\x2f"
+ "\xcf\x29\x06\x00\xdd\xb8\x0d\x9d",
+ "\x4b\x2c\x4b\x2d\xaa\x4c\x4a\x4c\x29\x2c\x4d\x4c\xce\xce\xcd\x4c"
+ "\xcf\x28\xc9\xca\xcc\xab\xa8\xca\x2c\x28\xa8\x4c\xcb\x2f\xcf\x29"
+ "\x06\x00\xaa\x73\x33\x56\x20\x00\x00\x00",
+ 563373aa),
+ T("aquickbrownfoxjumpsoverthelazydog",
+ "\x78\x9c\x4b\x2c\x2c\xcd\x4c\xce\x4e\x2a\xca\x2f\xcf\x4b\xcb\xaf"
+ "\xc8\x2a\xcd\x2d\x28\xce\x2f\x4b\x2d\x2a\xc9\x48\xcd\x49\xac\xaa"
+ "\x4c\xc9\x4f\x07\x00\xef\x3d\x0e\x1a",
+ "\x4b\x2c\x2c\xcd\x4c\xce\x4e\x2a\xca\x2f\xcf\x4b\xcb\xaf\xc8\x2a"
+ "\xcd\x2d\x28\xce\x2f\x4b\x2d\x2a\xc9\x48\xcd\x49\xac\xaa\x4c\xc9"
+ "\x4f\x07\x00\x00\x66\xdf\x56\x21\x00\x00\x00",
+ 56df6600),
+ T("quizzicaltwinsprovedmyhijackbugfix",
+ "\x78\x9c\x2b\x2c\xcd\xac\xaa\xca\x4c\x4e\xcc\x29\x29\xcf\xcc\x2b"
+ "\x2e\x28\xca\x2f\x4b\x4d\xc9\xad\xcc\xc8\xcc\x4a\x4c\xce\x4e\x2a"
+ "\x4d\x4f\xcb\xac\x00\x00\xff\xe8\x0e\x77",
+ "\x2b\x2c\xcd\xac\xaa\xca\x4c\x4e\xcc\x29\x29\xcf\xcc\x2b\x2e\x28"
+ "\xca\x2f\x4b\x4d\xc9\xad\xcc\xc8\xcc\x4a\x4c\xce\x4e\x2a\x4d\x4f"
+ "\xcb\xac\x00\x00\x01\x07\x14\xb7\x22\x00\x00\x00",
+ b7140701),
+ T("whenzombiesarrivequicklyfaxjudgepat",
+ "\x78\x9c\x2b\xcf\x48\xcd\xab\xca\xcf\x4d\xca\x4c\x2d\x4e\x2c\x2a"
+ "\xca\x2c\x4b\x2d\x2c\xcd\x4c\xce\xce\xa9\x4c\x4b\xac\xc8\x2a\x4d"
+ "\x49\x4f\x2d\x48\x2c\x01\x00\x0b\x5d\x0e\xca",
+ "\x2b\xcf\x48\xcd\xab\xca\xcf\x4d\xca\x4c\x2d\x4e\x2c\x2a\xca\x2c"
+ "\x4b\x2d\x2c\xcd\x4c\xce\xce\xa9\x4c\x4b\xac\xc8\x2a\x4d\x49\x4f"
+ "\x2d\x48\x2c\x01\x00\xae\xef\x98\xc3\x23\x00\x00\x00",
+ c398efae),
+ T("heavyboxesperformquickwaltzesandjigs",
+ "\x78\x9c\xcb\x48\x4d\x2c\xab\x4c\xca\xaf\x48\x2d\x2e\x48\x2d\x4a"
+ "\xcb\x2f\xca\x2d\x2c\xcd\x4c\xce\x2e\x4f\xcc\x29\xa9\x4a\x2d\x4e"
+ "\xcc\x4b\xc9\xca\x4c\x2f\x06\x00\x1a\xc0\x0f\x41",
+ "\xcb\x48\x4d\x2c\xab\x4c\xca\xaf\x48\x2d\x2e\x48\x2d\x4a\xcb\x2f"
+ "\xca\x2d\x2c\xcd\x4c\xce\x2e\x4f\xcc\x29\xa9\x4a\x2d\x4e\xcc\x4b"
+ "\xc9\xca\x4c\x2f\x06\x00\x71\xc5\x60\xbb\x24\x00\x00\x00",
+ bb60c571),
+ T("fakebugsputinwaxjonquilsdrivehimcrazy",
+ "\x78\x9c\x4b\x4b\xcc\x4e\x4d\x2a\x4d\x2f\x2e\x28\x2d\xc9\xcc\x2b"
+ "\x4f\xac\xc8\xca\xcf\x2b\x2c\xcd\xcc\x29\x4e\x29\xca\x2c\x4b\xcd"
+ "\xc8\xcc\x4d\x2e\x4a\xac\xaa\x04\x00\x29\x9e\x0f\xbf",
+ "\x4b\x4b\xcc\x4e\x4d\x2a\x4d\x2f\x2e\x28\x2d\xc9\xcc\x2b\x4f\xac"
+ "\xc8\xca\xcf\x2b\x2c\xcd\xcc\x29\x4e\x29\xca\x2c\x4b\xcd\xc8\xcc"
+ "\x4d\x2e\x4a\xac\xaa\x04\x00\xf0\x24\xc5\xa1\x25\x00\x00\x00",
+ a1c524f0),
+ T("wovensilkpyjamasexchangedforbluequartz",
+ "\x78\x9c\x2b\xcf\x2f\x4b\xcd\x2b\xce\xcc\xc9\x2e\xa8\xcc\x4a\xcc"
+ "\x4d\x2c\x4e\xad\x48\xce\x48\xcc\x4b\x4f\x4d\x49\xcb\x2f\x4a\xca"
+ "\x29\x4d\x2d\x2c\x4d\x2c\x2a\xa9\x02\x00\x39\xef\x10\x15",
+ "\x2b\xcf\x2f\x4b\xcd\x2b\xce\xcc\xc9\x2e\xa8\xcc\x4a\xcc\x4d\x2c"
+ "\x4e\xad\x48\xce\x48\xcc\x4b\x4f\x4d\x49\xcb\x2f\x4a\xca\x29\x4d"
+ "\x2d\x2c\x4d\x2c\x2a\xa9\x02\x00\x4e\x06\x7f\x9a\x26\x00\x00\x00",
+ 9a7f064e),
+ T("thequickonyxgoblinjumpsoverthelazydwarf",
+ "\x78\x9c\x2b\xc9\x48\x2d\x2c\xcd\x4c\xce\xce\xcf\xab\xac\x48\xcf"
+ "\x4f\xca\xc9\xcc\xcb\x2a\xcd\x2d\x28\xce\x2f\x4b\x2d\x2a\xc9\x48"
+ "\xcd\x49\xac\xaa\x4c\x29\x4f\x2c\x4a\x03\x00\x4d\x76\x10\xa8",
+ "\x2b\xc9\x48\x2d\x2c\xcd\x4c\xce\xce\xcf\xab\xac\x48\xcf\x4f\xca"
+ "\xc9\xcc\xcb\x2a\xcd\x2d\x28\xce\x2f\x4b\x2d\x2a\xc9\x48\xcd\x49"
+ "\xac\xaa\x4c\x29\x4f\x2c\x4a\x03\x00\x12\x87\x47\x3b\x27\x00\x00\x00",
+ 3b478712),
+ T("amazinglyfewdiscothequesprovidejukeboxes",
+ "\x78\x9c\x4b\xcc\x4d\xac\xca\xcc\x4b\xcf\xa9\x4c\x4b\x2d\x4f\xc9"
+ "\x2c\x4e\xce\x2f\xc9\x48\x2d\x2c\x4d\x2d\x2e\x28\xca\x2f\xcb\x4c"
+ "\x49\xcd\x2a\xcd\x4e\x4d\xca\xaf\x48\x2d\x06\x00\x59\xbe\x10\xe9",
+ "\x4b\xcc\x4d\xac\xca\xcc\x4b\xcf\xa9\x4c\x4b\x2d\x4f\xc9\x2c\x4e"
+ "\xce\x2f\xc9\x48\x2d\x2c\x4d\x2d\x2e\x28\xca\x2f\xcb\x4c\x49\xcd"
+ "\x2a\xcd\x4e\x4d\xca\xaf\x48\x2d\x06\x00\xa3\xe4\xdd\x7d\x28\x00\x00\x00",
+ 7ddde4a3),
+
+ // self-describing pangram by Lee Sallows (SciAm, 1984)
+ T("This Pangram contains four as, one b, two cs, one d, thirty es, "
+ "six fs, five gs, seven hs, eleven is, one j, one k, two ls, two ms, "
+ "eighteen ns, fifteen os, two ps, one q, five rs, twenty-seven ss, "
+ "eighteen ts, two us, seven vs, eight ws, two xs, three ys, & one z.",
+ "\x78\x9c\x4d\x4e\xcd\x1a\xc2\x20\x0c\x7b\x95\x9c\x3c\x4d\x9f\xc5"
+ "\x83\x2f\x80\xb3\x8c\xea\x56\x14\xd8\x0f\x3e\xbd\x0c\xaa\x9f\xa7"
+ "\xa4\x69\x92\xf6\xe2\x38\xe2\x6c\x64\x08\x66\x42\xef\x25\x19\x96"
+ "\x08\xeb\xe7\x00\x13\x3b\x78\x21\x5c\x3b\xa4\xd5\xa3\xd7\xf1\x56"
+ "\x46\xc7\x21\x65\x50\x51\x22\x6f\xb0\x05\x2d\x2f\x84\x61\x17\x68"
+ "\x21\x81\x2b\x8c\xc6\x4a\x59\x73\xf7\x06\x8f\xd6\x36\xc6\x86\xd3"
+ "\x6e\xe4\xc1\x25\x2a\x56\xa9\x45\xb6\x72\xaf\x86\xa7\xc6\x5f\x7a"
+ "\x23\x54\x9d\x24\xe5\x63\x3b\x15\xff\x1b\x92\xa6\xe6\xdf\x27\xcb"
+ "\x77\x8d\x55\x77\xdb\x8e\x2e\x10\x21\x17\x76\xa8\xed\xef\xd3\x07"
+ "\xaa\x0c\x59\x5f",
+ "\x4d\x4e\xcd\x1a\xc2\x20\x0c\x7b\x95\x9c\x3c\x4d\x9f\xc5\x83\x2f"
+ "\x80\xb3\x8c\xea\x56\x14\xd8\x0f\x3e\xbd\x0c\xaa\x9f\xa7\xa4\x69"
+ "\x92\xf6\xe2\x38\xe2\x6c\x64\x08\x66\x42\xef\x25\x19\x96\x08\xeb"
+ "\xe7\x00\x13\x3b\x78\x21\x5c\x3b\xa4\xd5\xa3\xd7\xf1\x56\x46\xc7"
+ "\x21\x65\x50\x51\x22\x6f\xb0\x05\x2d\x2f\x84\x61\x17\x68\x21\x81"
+ "\x2b\x8c\xc6\x4a\x59\x73\xf7\x06\x8f\xd6\x36\xc6\x86\xd3\x6e\xe4"
+ "\xc1\x25\x2a\x56\xa9\x45\xb6\x72\xaf\x86\xa7\xc6\x5f\x7a\x23\x54"
+ "\x9d\x24\xe5\x63\x3b\x15\xff\x1b\x92\xa6\xe6\xdf\x27\xcb\x77\x8d"
+ "\x55\x77\xdb\x8e\x2e\x10\x21\x17\x76\xa8\xed\xef\xd3\x07\x11\xb4"
+ "\xb5\x3a\x09\x01\x00\x00",
+ 3ab5b411),
+
+ // "Lion-Eating Poet in the Stone Den" by Chao Yuen Ren,
+ // Simplified Chinese text in UTF-8
+ T("\xe3\x80\x8a\xe6\x96\xbd\xe6\xb0\x8f\xe9\xa3\x9f\xe7\x8b\xae\xe5\x8f"
+ "\xb2\xe3\x80\x8b \xe7\x9f\xb3\xe5\xae\xa4\xe8\xaf\x97\xe5\xa3\xab\xe6"
+ "\x96\xbd\xe6\xb0\x8f\xef\xbc\x8c\xe5\x97\x9c\xe7\x8b\xae\xef\xbc\x8c"
+ "\xe8\xaa\x93\xe9\xa3\x9f\xe5\x8d\x81\xe7\x8b\xae\xe3\x80\x82 \xe6\xb0"
+ "\x8f\xe6\x97\xb6\xe6\x97\xb6\xe9\x80\x82\xe5\xb8\x82\xe8\xa7\x86\xe7"
+ "\x8b\xae\xe3\x80\x82 \xe5\x8d\x81\xe6\x97\xb6\xef\xbc\x8c\xe9\x80\x82"
+ "\xe5\x8d\x81\xe7\x8b\xae\xe9\x80\x82\xe5\xb8\x82\xe3\x80\x82 \xe6\x98"
+ "\xaf\xe6\x97\xb6\xef\xbc\x8c\xe9\x80\x82\xe6\x96\xbd\xe6\xb0\x8f\xe9"
+ "\x80\x82\xe5\xb8\x82\xe3\x80\x82 \xe6\xb0\x8f\xe8\xa7\x86\xe6\x98\xaf"
+ "\xe5\x8d\x81\xe7\x8b\xae\xef\xbc\x8c\xe6\x81\x83\xe7\x9f\xa2\xe5\x8a"
+ "\xbf\xef\xbc\x8c\xe4\xbd\xbf\xe6\x98\xaf\xe5\x8d\x81\xe7\x8b\xae\xe9"
+ "\x80\x9d\xe4\xb8\x96\xe3\x80\x82 \xe6\xb0\x8f\xe6\x8b\xbe\xe6\x98\xaf"
+ "\xe5\x8d\x81\xe7\x8b\xae\xe5\xb0\xb8\xef\xbc\x8c\xe9\x80\x82\xe7\x9f"
+ "\xb3\xe5\xae\xa4\xe3\x80\x82 \xe7\x9f\xb3\xe5\xae\xa4\xe6\xb9\xbf\xef"
+ "\xbc\x8c\xe6\xb0\x8f\xe4\xbd\xbf\xe4\xbe\x8d\xe6\x8b\xad\xe7\x9f\xb3"
+ "\xe5\xae\xa4\xe3\x80\x82 \xe7\x9f\xb3\xe5\xae\xa4\xe6\x8b\xad\xef\xbc"
+ "\x8c\xe6\xb0\x8f\xe5\xa7\x8b\xe8\xaf\x95\xe9\xa3\x9f\xe6\x98\xaf\xe5"
+ "\x8d\x81\xe7\x8b\xae\xe3\x80\x82 \xe9\xa3\x9f\xe6\x97\xb6\xef\xbc\x8c"
+ "\xe5\xa7\x8b\xe8\xaf\x86\xe6\x98\xaf\xe5\x8d\x81\xe7\x8b\xae\xe5\xb0"
+ "\xb8\xef\xbc\x8c\xe5\xae\x9e\xe5\x8d\x81\xe7\x9f\xb3\xe7\x8b\xae\xe5"
+ "\xb0\xb8\xe3\x80\x82 \xe8\xaf\x95\xe9\x87\x8a\xe6\x98\xaf\xe4\xba\x8b"
+ "\xe3\x80\x82",
+ "\x78\x9c\x65\x8f\xdd\x0a\x82\x40\x10\x46\x5f\xc5\x47\x5d\x0d\x0c"
+ "\xdc\xc4\x8b\x48\xbb\xa8\x84\x0c\x84\xc2\x1f\x12\xc2\x22\xf5\x61"
+ "\x74\x56\xbd\xea\x15\xfa\x76\xd7\x0c\x0a\xf6\x62\x66\xcf\x99\x6f"
+ "\x67\x5b\xe6\x08\xbf\x12\xb9\x37\x46\x61\xcf\x53\xf2\xae\x2d\xe3"
+ "\x46\x1f\x16\x94\x9e\x86\x2c\xa0\xe8\xa2\xf1\xeb\xb9\xa2\x60\x07"
+ "\x03\xc5\x70\x5e\xc3\x26\xd7\x44\xdb\x32\xcb\x00\x16\xc1\x0d\x67"
+ "\x64\x16\x95\xd6\x10\xdb\x13\x80\x82\x5b\x4c\x48\xa0\x74\x6d\xa8"
+ "\xa1\x6d\x36\xb3\x69\x83\x2f\xcb\x3d\x84\xc0\xd0\x43\x90\x84\xb9"
+ "\xe8\xc3\x23\x39\x0d\xea\xae\x6a\x66\x34\xb2\x7d\x57\xfa\x9f\x25"
+ "\x78\x3d\x03\xca\x4b\x9d\xad\xbf\x22\x0d\x5d\x89\xbb\xcc\x80\x8d"
+ "\x98\xae\x76\x05\x4f\xfe\x0c\x9e\x68\x83\x62\x3e\x64\x1b\x7c\x75"
+ "\x4e\x95\x92\xec\xd5\xe2\x0a\xdb\x3f\x2f\x52\x7a\x90\x6d\x58\xe8"
+ "\x1b\x39\x20\x33\x96\x0e\xbc\xee\xc1\xd1\xbf\x01\xae\x11\xff\x53",
+ "\x65\x8f\xdd\x0a\x82\x40\x10\x46\x5f\xc5\x47\x5d\x0d\x0c\xdc\xc4"
+ "\x8b\x48\xbb\xa8\x84\x0c\x84\xc2\x1f\x12\xc2\x22\xf5\x61\x74\x56"
+ "\xbd\xea\x15\xfa\x76\xd7\x0c\x0a\xf6\x62\x66\xcf\x99\x6f\x67\x5b"
+ "\xe6\x08\xbf\x12\xb9\x37\x46\x61\xcf\x53\xf2\xae\x2d\xe3\x46\x1f"
+ "\x16\x94\x9e\x86\x2c\xa0\xe8\xa2\xf1\xeb\xb9\xa2\x60\x07\x03\xc5"
+ "\x70\x5e\xc3\x26\xd7\x44\xdb\x32\xcb\x00\x16\xc1\x0d\x67\x64\x16"
+ "\x95\xd6\x10\xdb\x13\x80\x82\x5b\x4c\x48\xa0\x74\x6d\xa8\xa1\x6d"
+ "\x36\xb3\x69\x83\x2f\xcb\x3d\x84\xc0\xd0\x43\x90\x84\xb9\xe8\xc3"
+ "\x23\x39\x0d\xea\xae\x6a\x66\x34\xb2\x7d\x57\xfa\x9f\x25\x78\x3d"
+ "\x03\xca\x4b\x9d\xad\xbf\x22\x0d\x5d\x89\xbb\xcc\x80\x8d\x98\xae"
+ "\x76\x05\x4f\xfe\x0c\x9e\x68\x83\x62\x3e\x64\x1b\x7c\x75\x4e\x95"
+ "\x92\xec\xd5\xe2\x0a\xdb\x3f\x2f\x52\x7a\x90\x6d\x58\xe8\x1b\x39"
+ "\x20\x33\x96\x0e\xbc\xee\xc1\xd1\xbf\x01\xe5\x06\xa6\x1f\x72\x01"
+ "\x00\x00",
+ 1fa606e5),
+
+ { 0, 0, 0, 0, 0, 0, 0 }
+};
+
+#undef T
+#undef GZH
static void
test_zlib_crc32(void *)
{
- // Test vectors generated using a standalone crc32 implementation
- // of unknown provenance, and then validated with the implementation
- // built into zlib. If anyone knows a reliable source for "official"
- // test vectors for the 0x04C11DB7 polynomial, please let us know.
-
- struct hash_testvec
- {
- const uint8_t *text;
- size_t tlen;
- uint32_t digest;
- };
- static const struct hash_testvec tests[] = {
-#define T(s, d) { (const uint8_t *)s, sizeof s - 1, 0x##d }
-
- // the empty string
- T("", 00000000),
-
- // 4-byte messages
- T("\x00\x00\x00\x00", 2144df1c),
- T("\x11\x11\x11\x11", ed6c2543),
- T("\x22\x22\x22\x22", 62642de3),
- T("\x33\x33\x33\x33", ae4cd7bc),
- T("\x44\x44\x44\x44", a7053ae2),
- T("\x55\x55\x55\x55", 6b2dc0bd),
- T("\x66\x66\x66\x66", e425c81d),
- T("\x77\x77\x77\x77", 280d3242),
- T("\x88\x88\x88\x88", f6b612a1),
- T("\x99\x99\x99\x99", 3a9ee8fe),
- T("\xaa\xaa\xaa\xaa", b596e05e),
- T("\xbb\xbb\xbb\xbb", 79be1a01),
- T("\xcc\xcc\xcc\xcc", 70f7f75f),
- T("\xdd\xdd\xdd\xdd", bcdf0d00),
- T("\xee\xee\xee\xee", 33d705a0),
- T("\xff\xff\xff\xff", ffffffff),
- T("\x40\x49\x0f\xdb", 538226fd), // pi (IEEE single)
-
- // 8-byte messages
- T("\x00\x00\x00\x00\x00\x00\x00\x00", 6522df69),
- T("\x00\x00\x00\x00\xff\xff\xff\xff", bb99ff8a),
- T("\xff\xff\xff\xff\x00\x00\x00\x00", ffffffff),
- T("\xff\xff\xff\xff\xff\xff\xff\xff", 2144df1c),
- T("\x55\x55\x55\x55\x55\x55\x55\x55", efd02285),
- T("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", abb622f0),
- T("\x40\x09\x21\xfb\x54\x44\x2d\x18", 2a8990d8), // pi (IEEE double)
-
- // 32-byte messages: all possible bytes occur once
- T("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
- "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
- 91267e8a),
- T("\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
- "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f",
- f6a606e3),
- T("\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
- "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f",
- 5e268e58),
- T("\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
- "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f",
- 39a6f631),
- T("\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
- "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f",
- d456996f),
- T("\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
- "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf",
- b3d6e106),
- T("\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
- "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf",
- 1b5669bd),
- T("\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
- "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
- 7cd611d4),
-
- // 26- to 40-letter pangrams from Wikipedia, all nonletters removed,
- // all lowercase
- T("cwmfjordbankglyphsvextquiz", 81308910),
- T("nymphsblitzquickvexdwarfjog", c9b201ae),
- T("brickquizwhangsjumpyveldtfox", c17836eb),
- T("vexednymphsgoforquickwaltzjob", ea8c2360),
- T("bothfickledwarvesjinxmypigquiz", 3c7c5f5f),
- T("ficklejinxbogdwarvesspymathquiz", 75862807),
- T("averybadquackmightjinxzippyfowls", 563373aa),
- T("aquickbrownfoxjumpsoverthelazydog", 56df6600),
- T("quizzicaltwinsprovedmyhijackbugfix", b7140701),
- T("whenzombiesarrivequicklyfaxjudgepat", c398efae),
- T("heavyboxesperformquickwaltzesandjigs", bb60c571),
- T("fakebugsputinwaxjonquilsdrivehimcrazy", a1c524f0),
- T("wovensilkpyjamasexchangedforbluequartz", 9a7f064e),
- T("thequickonyxgoblinjumpsoverthelazydwarf", 3b478712),
- T("amazinglyfewdiscothequesprovidejukeboxes", 7ddde4a3),
-
- // self-describing pangram by Lee Sallows (SciAm, 1984)
- T("This Pangram contains four as, one b, two cs, one d, thirty es, "
- "six fs, five gs, seven hs, eleven is, one j, one k, two ls, two ms, "
- "eighteen ns, fifteen os, two ps, one q, five rs, twenty-seven ss, "
- "eighteen ts, two us, seven vs, eight ws, two xs, three ys, & one z.",
- 3ab5b411),
-
- // "Lion-Eating Poet in the Stone Den" by Chao Yuen Ren,
- // Simplified Chinese text in UTF-8
- T("\xe3\x80\x8a\xe6\x96\xbd\xe6\xb0\x8f\xe9\xa3\x9f\xe7\x8b\xae\xe5\x8f"
- "\xb2\xe3\x80\x8b \xe7\x9f\xb3\xe5\xae\xa4\xe8\xaf\x97\xe5\xa3\xab\xe6"
- "\x96\xbd\xe6\xb0\x8f\xef\xbc\x8c\xe5\x97\x9c\xe7\x8b\xae\xef\xbc\x8c"
- "\xe8\xaa\x93\xe9\xa3\x9f\xe5\x8d\x81\xe7\x8b\xae\xe3\x80\x82 \xe6\xb0"
- "\x8f\xe6\x97\xb6\xe6\x97\xb6\xe9\x80\x82\xe5\xb8\x82\xe8\xa7\x86\xe7"
- "\x8b\xae\xe3\x80\x82 \xe5\x8d\x81\xe6\x97\xb6\xef\xbc\x8c\xe9\x80\x82"
- "\xe5\x8d\x81\xe7\x8b\xae\xe9\x80\x82\xe5\xb8\x82\xe3\x80\x82 \xe6\x98"
- "\xaf\xe6\x97\xb6\xef\xbc\x8c\xe9\x80\x82\xe6\x96\xbd\xe6\xb0\x8f\xe9"
- "\x80\x82\xe5\xb8\x82\xe3\x80\x82 \xe6\xb0\x8f\xe8\xa7\x86\xe6\x98\xaf"
- "\xe5\x8d\x81\xe7\x8b\xae\xef\xbc\x8c\xe6\x81\x83\xe7\x9f\xa2\xe5\x8a"
- "\xbf\xef\xbc\x8c\xe4\xbd\xbf\xe6\x98\xaf\xe5\x8d\x81\xe7\x8b\xae\xe9"
- "\x80\x9d\xe4\xb8\x96\xe3\x80\x82 \xe6\xb0\x8f\xe6\x8b\xbe\xe6\x98\xaf"
- "\xe5\x8d\x81\xe7\x8b\xae\xe5\xb0\xb8\xef\xbc\x8c\xe9\x80\x82\xe7\x9f"
- "\xb3\xe5\xae\xa4\xe3\x80\x82 \xe7\x9f\xb3\xe5\xae\xa4\xe6\xb9\xbf\xef"
- "\xbc\x8c\xe6\xb0\x8f\xe4\xbd\xbf\xe4\xbe\x8d\xe6\x8b\xad\xe7\x9f\xb3"
- "\xe5\xae\xa4\xe3\x80\x82 \xe7\x9f\xb3\xe5\xae\xa4\xe6\x8b\xad\xef\xbc"
- "\x8c\xe6\xb0\x8f\xe5\xa7\x8b\xe8\xaf\x95\xe9\xa3\x9f\xe6\x98\xaf\xe5"
- "\x8d\x81\xe7\x8b\xae\xe3\x80\x82 \xe9\xa3\x9f\xe6\x97\xb6\xef\xbc\x8c"
- "\xe5\xa7\x8b\xe8\xaf\x86\xe6\x98\xaf\xe5\x8d\x81\xe7\x8b\xae\xe5\xb0"
- "\xb8\xef\xbc\x8c\xe5\xae\x9e\xe5\x8d\x81\xe7\x9f\xb3\xe7\x8b\xae\xe5"
- "\xb0\xb8\xe3\x80\x82 \xe8\xaf\x95\xe9\x87\x8a\xe6\x98\xaf\xe4\xba\x8b"
- "\xe3\x80\x82",
- 1fa606e5),
-
- { 0, 0, 0 }
-#undef T
- };
+ for (const zlib_testvec *t = testvecs; t->text; t++) {
+ uint32_t h = generate_crc32c(t->text, t->tlen);
+ tt_assert_op_type(h, ==, t->crc32, unsigned int, "%08x");
+ }
- int i;
- uint32_t h;
- for (i = 0; tests[i].text; i++) {
- h = generate_crc32c(tests[i].text, tests[i].tlen);
- tt_assert_op_type(h,==,tests[i].digest, unsigned int, "%08x");
+ end:;
+}
+
+static void
+test_zlib_compress_zlib(void *)
+{
+ uint8_t obuf[1024];
+ for (const zlib_testvec *t = testvecs; t->text; t++) {
+ ssize_t n = def(t->text, t->tlen, obuf, sizeof obuf, 6);
+ tt_uint_op(n, ==, t->zlen);
+ tt_mem_op(obuf, ==, t->zlibbed, t->zlen);
+ }
+
+ end:;
+}
+
+static void
+test_zlib_decompress_zlib(void *)
+{
+ uint8_t obuf[1024];
+ for (const zlib_testvec *t = testvecs; t->text; t++) {
+ ssize_t n = inf(t->zlibbed, t->zlen, obuf, sizeof obuf);
+ tt_uint_op(n, ==, t->tlen);
+ tt_mem_op(obuf, ==, t->text, t->tlen);
+ }
+
+ end:;
+}
+
+static void
+test_zlib_compress_gzip(void *)
+{
+ uint8_t obuf[1024];
+ for (const zlib_testvec *t = testvecs; t->text; t++) {
+ ssize_t n = gzDeflate(t->text, t->tlen, obuf, sizeof obuf, 0);
+ tt_uint_op(n, ==, t->glen);
+ tt_mem_op(obuf, ==, t->gzipped, t->glen);
+ }
+
+ end:;
+}
+static void
+test_zlib_decompress_gzip(void *)
+{
+ uint8_t obuf[1024];
+ for (const zlib_testvec *t = testvecs; t->text; t++) {
+ ssize_t n = gzInflate(t->gzipped, t->glen, obuf, sizeof obuf);
+ tt_uint_op(n, ==, t->tlen);
+ tt_mem_op(obuf, ==, t->text, t->tlen);
}
end:;
@@ -154,5 +499,9 @@ test_zlib_crc32(void *)
struct testcase_t zlib_tests[] = {
T(crc32),
+ T(compress_zlib),
+ T(decompress_zlib),
+ T(compress_gzip),
+ T(decompress_gzip),
END_OF_TESTCASES
};
diff --git a/src/zpack.cc b/src/zpack.cc
index 24c64fd..c851f12 100644
--- a/src/zpack.cc
+++ b/src/zpack.cc
@@ -284,7 +284,7 @@ gzDeflate(const uint8_t *source, size_t slen, uint8_t *dest, size_t dlen,
dest[6] = (mtime >> 16) & 0xff;
dest[7] = (mtime >> 24) & 0xff;
dest[8] = 0x00; /* extra flags */
- dest[9] = 0x03; /* UNIX */
+ dest[9] = 0xFF; /* unknown */
z.next_out = dest + 10;
z.avail_out = dlen - 10 - 8;
1
0
[stegotorus/master] Simplify zpack.cc by not rebuffering and by using zlib's built-in gzip-format support.
by zwol@torproject.org 20 Jul '12
by zwol@torproject.org 20 Jul '12
20 Jul '12
commit 1e6bd79436b04dcc4dfc56b4ca393a93a487b203
Author: Zack Weinberg <zackw(a)cmu.edu>
Date: Mon Apr 30 14:58:15 2012 -0700
Simplify zpack.cc by not rebuffering and by using zlib's built-in gzip-format support.
---
src/zpack.cc | 360 ++++++++++++++++------------------------------------------
1 files changed, 100 insertions(+), 260 deletions(-)
diff --git a/src/zpack.cc b/src/zpack.cc
index c851f12..3ffd065 100644
--- a/src/zpack.cc
+++ b/src/zpack.cc
@@ -7,319 +7,159 @@
#include <limits>
-#define CHUNK 16384
-
-/* Compress from file source to file dest until EOF on source.
- def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
- allocated for processing, Z_STREAM_ERROR if an invalid compression
- level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
- version of the library linked do not match, or Z_ERRNO if there is
- an error reading or writing the files. */
-
+// zlib doesn't believe in size_t. When size_t is bigger than uInt, we
+// theoretically could break operations up into uInt-sized chunks to
+// support the full range of size_t, but I doubt we will ever need to
+// compress, decompress, or crc32 more than 2^32 bytes in one
+// operation, so I'm not bothering. -- zw, 2012
+//
+// The indirection through ZLIB_UINT_MAX makes some versions of gcc
+// not produce a 'comparison is always (true/false)' warning.
+const size_t ZLIB_UINT_MAX = std::numeric_limits<uInt>::max();
+const size_t ZLIB_CEILING = (SIZE_T_CEILING > ZLIB_UINT_MAX
+ ? ZLIB_UINT_MAX : SIZE_T_CEILING);
+
+// Compress from 'source' to 'dest', producing 'zlib' (RFC 1950) format,
+// with compression level 'level'.
ssize_t
def(const uint8_t *source, size_t slen, uint8_t *dest, size_t dlen, int level)
{
- int ret, flush;
- size_t have;
- z_stream strm;
- uint8_t in[CHUNK];
- uint8_t out[CHUNK];
- size_t dlen_orig = dlen;
-
- if (slen > SIZE_T_CEILING || dlen > SIZE_T_CEILING)
+ if (slen > ZLIB_CEILING || dlen > ZLIB_CEILING)
return -1;
- /* allocate deflate state */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- ret = deflateInit(&strm, level);
- if (ret != Z_OK)
- return ret;
-
- /* compress until end of file */
- do {
- if (slen > CHUNK)
- strm.avail_in = CHUNK;
- else
- strm.avail_in = slen;
-
- memcpy (in, source, strm.avail_in);
- slen = slen - strm.avail_in;
- source = source + strm.avail_in;
-
- flush = (slen == 0) ? Z_FINISH : Z_NO_FLUSH;
- strm.next_in = in;
-
- /* run deflate() on input until output buffer not full, finish
- compression if all of source has been read in */
- do {
- strm.avail_out = CHUNK;
- strm.next_out = out;
- ret = deflate(&strm, flush); /* no bad return value */
- log_assert(ret != Z_STREAM_ERROR); /* state not clobbered */
- have = CHUNK - strm.avail_out;
-
- if (dlen < have) {
- log_warn("dest buf too small - have %lu, need %lu",
- (unsigned long)dlen, (unsigned long)have);
- return Z_ERRNO;
- }
+ z_stream strm;
+ memset(&strm, 0, sizeof strm);
+ int ret = deflateInit(&strm, level);
+ if (ret != Z_OK) {
+ log_warn("compression failure (initialization): %s", strm.msg);
+ return -1;
+ }
- memcpy(dest, out, have);
- dest += have;
- dlen = dlen - have;
- } while (strm.avail_out == 0);
- log_assert(strm.avail_in == 0); /* all input will be used */
+ strm.next_in = const_cast<Bytef*>(source);
+ strm.avail_in = slen;
+ strm.next_out = dest;
+ strm.avail_out = dlen;
- /* done when last data in file processed */
- } while (flush != Z_FINISH);
- log_assert(ret == Z_STREAM_END); /* stream will be complete */
+ ret = deflate(&strm, Z_FINISH);
+ if (ret != Z_STREAM_END) {
+ log_warn("compression failure: %s", strm.msg);
+ deflateEnd(&strm);
+ return -1;
+ }
- /* clean up and return */
deflateEnd(&strm);
- return (dlen_orig - dlen);
+ return strm.total_out;
}
-/* Decompress from file source to file dest until stream ends or EOF.
- inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
- allocated for processing, Z_DATA_ERROR if the deflate data is
- invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
- the version of the library linked do not match, or Z_ERRNO if there
- is an error reading or writing the files. */
-
+// Decompress 'zlib'-format data from 'source' to 'dest'.
ssize_t
inf(const uint8_t *source, size_t slen, uint8_t *dest, size_t dlen)
{
- int ret;
- size_t have;
- z_stream strm;
- uint8_t in[CHUNK];
- uint8_t out[CHUNK];
- size_t dlen_orig = dlen;
-
- if (slen > SIZE_T_CEILING || dlen > SIZE_T_CEILING)
+ if (slen > ZLIB_CEILING || dlen > ZLIB_CEILING)
return -1;
/* allocate inflate state */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.avail_in = 0;
- strm.next_in = Z_NULL;
- ret = inflateInit(&strm);
- if (ret != Z_OK)
- return ret;
-
- /* decompress until deflate stream ends or end of file */
- do {
- if (slen == 0)
- break;
-
- if (slen > CHUNK)
- strm.avail_in = CHUNK;
- else
- strm.avail_in = slen;
-
- memcpy(in, source, strm.avail_in);
- slen = slen - strm.avail_in;
- source = source + strm.avail_in;
- strm.next_in = in;
-
- /* run inflate() on input until output buffer not full */
- do {
- strm.avail_out = CHUNK;
- strm.next_out = out;
- ret = inflate(&strm, Z_NO_FLUSH);
- log_assert(ret != Z_STREAM_ERROR); /* state not clobbered */
- switch (ret) {
- case Z_NEED_DICT:
- case Z_DATA_ERROR:
- case Z_MEM_ERROR:
- inflateEnd(&strm);
- return ret;
- }
- have = CHUNK - strm.avail_out;
-
- if (dlen < have) {
- log_warn("dest buf too small - have %lu, need %lu",
- (unsigned long)dlen, (unsigned long)have);
- return Z_ERRNO;
- }
-
- memcpy(dest, out, have);
- dest += have;
- dlen = dlen - have;
+ z_stream strm;
+ memset(&strm, 0, sizeof strm);
+ int ret = inflateInit(&strm);
+ if (ret != Z_OK) {
+ log_warn("decompression failure (initialization): %s", strm.msg);
+ return -1;
+ }
- } while (strm.avail_out == 0);
+ strm.next_in = const_cast<Bytef*>(source);
+ strm.avail_in = slen;
+ strm.next_out = dest;
+ strm.avail_out = dlen;
- /* done when inflate() says it's done */
- } while (ret != Z_STREAM_END);
+ ret = inflate(&strm, Z_FINISH);
+ if (ret != Z_STREAM_END) {
+ log_warn("decompression failure: %s", strm.msg);
+ inflateEnd(&strm);
+ return -1;
+ }
- /* clean up and return */
inflateEnd(&strm);
-
- if (ret == Z_STREAM_END)
- return dlen_orig - dlen;
- return Z_DATA_ERROR;
+ return strm.total_out;
}
-/* assumes that we know there is exactly 10 bytes of gzip header */
-
ssize_t
gzInflate(const uint8_t *source, size_t slen, uint8_t *dest, size_t dlen)
{
- int ret;
- size_t have;
- z_stream strm;
- uint8_t in[CHUNK];
- uint8_t out[CHUNK];
- size_t dlen_orig = dlen;
-
- if (slen > SIZE_T_CEILING || dlen > SIZE_T_CEILING)
+ if (slen > ZLIB_CEILING || dlen > ZLIB_CEILING)
return -1;
- /* allocate inflate state */
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.avail_in = 0;
- strm.next_in = Z_NULL;
-
- ret = inflateInit2(&strm, -MAX_WBITS);
- if (ret != Z_OK)
- return ret;
-
- source = source + 10;
- slen -= 10;
-
- /* decompress until deflate stream ends or end of file */
- do {
- if (slen == 0)
- break;
-
- if (slen > CHUNK)
- strm.avail_in = CHUNK;
- else
- strm.avail_in = slen;
-
- memcpy(in, source, strm.avail_in);
- slen = slen - strm.avail_in;
- source = source + strm.avail_in;
- strm.next_in = in;
-
- /* run inflate() on input until output buffer not full */
- do {
- strm.avail_out = CHUNK;
- strm.next_out = out;
- ret = inflate(&strm, Z_NO_FLUSH);
- log_assert(ret != Z_STREAM_ERROR); /* state not clobbered */
- switch (ret) {
- case Z_NEED_DICT:
- ret = Z_DATA_ERROR; /* and fall through */
- case Z_DATA_ERROR:
- case Z_MEM_ERROR:
- inflateEnd(&strm);
- return ret;
- }
- have = CHUNK - strm.avail_out;
-
- if (dlen < have) {
- log_warn("dest buf too small - have %lu, need %lu",
- (unsigned long)dlen, (unsigned long)have);
- return Z_ERRNO;
- }
+ z_stream strm;
+ memset(&strm, 0, sizeof strm);
+ int ret = inflateInit2(&strm, MAX_WBITS|16); // 16 = decode gzip (only)
- memcpy(dest, out, have);
- dest += have;
- dlen = dlen - have;
+ if (ret != Z_OK) {
+ log_warn("decompression failure (initialization): %s", strm.msg);
+ return -1;
+ }
- } while (strm.avail_out == 0);
+ strm.next_in = const_cast<Bytef*>(source);
+ strm.avail_in = slen;
+ strm.next_out = dest;
+ strm.avail_out = dlen;
- /* done when inflate() says it's done */
- } while (ret != Z_STREAM_END);
+ ret = inflate(&strm, Z_FINISH);
+ if (ret != Z_STREAM_END) {
+ log_warn("decompression failure: %s", strm.msg);
+ inflateEnd(&strm);
+ return -1;
+ }
- /* clean up and return */
inflateEnd(&strm);
-
- if (ret == Z_STREAM_END)
- return dlen_orig - dlen;
- return Z_DATA_ERROR;
+ return strm.total_out;
}
ssize_t
gzDeflate(const uint8_t *source, size_t slen, uint8_t *dest, size_t dlen,
time_t mtime)
{
- uint32_t crc;
- z_stream z;
-
- if (slen > SIZE_T_CEILING || dlen > SIZE_T_CEILING)
+ if (slen > ZLIB_CEILING || dlen > ZLIB_CEILING)
return -1;
- z.zalloc = Z_NULL;
- z.zfree = Z_NULL;
- z.opaque = Z_NULL;
-
- if (Z_OK != deflateInit2(&z,
- Z_DEFAULT_COMPRESSION,
- Z_DEFLATED,
- -MAX_WBITS, /* supress zlib-header */
- 8,
- Z_DEFAULT_STRATEGY))
+ z_stream strm;
+ memset(&strm, 0, sizeof strm);
+ int ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
+ MAX_WBITS|16, // compress as gzip
+ 8, Z_DEFAULT_STRATEGY);
+ if (ret != Z_OK) {
+ log_warn("compression failure (initialization): %s", strm.msg);
return -1;
+ }
- z.next_in = const_cast<uint8_t*>(source);
- z.avail_in = slen;
- z.total_in = 0;
-
- /* write gzip header */
-
- dest[0] = 0x1f;
- dest[1] = 0x8b;
- dest[2] = Z_DEFLATED;
- dest[3] = 0; /* options */
- dest[4] = (mtime >> 0) & 0xff;
- dest[5] = (mtime >> 8) & 0xff;
- dest[6] = (mtime >> 16) & 0xff;
- dest[7] = (mtime >> 24) & 0xff;
- dest[8] = 0x00; /* extra flags */
- dest[9] = 0xFF; /* unknown */
-
- z.next_out = dest + 10;
- z.avail_out = dlen - 10 - 8;
- z.total_out = 0;
-
- if (deflate(&z, Z_FINISH) != Z_STREAM_END) {
- deflateEnd(&z);
+ gz_header gzh;
+ memset(&gzh, 0, sizeof gzh);
+ gzh.time = mtime;
+ gzh.os = 0xFF; // "unknown"
+ ret = deflateSetHeader(&strm, &gzh);
+ if (ret != Z_OK) {
+ log_warn("compression failure (initialization): %s", strm.msg);
return -1;
}
- crc = generate_crc32c(source, slen);
-
- dest = dest + 10 + z.total_out;
- dest[0] = (crc >> 0) & 0xff;
- dest[1] = (crc >> 8) & 0xff;
- dest[2] = (crc >> 16) & 0xff;
- dest[3] = (crc >> 24) & 0xff;
- dest[4] = (z.total_in >> 0) & 0xff;
- dest[5] = (z.total_in >> 8) & 0xff;
- dest[6] = (z.total_in >> 16) & 0xff;
- dest[7] = (z.total_in >> 24) & 0xff;
+ strm.next_in = const_cast<Bytef*>(source);
+ strm.avail_in = slen;
+ strm.next_out = dest;
+ strm.avail_out = dlen;
- if (deflateEnd(&z) != Z_OK)
+ ret = deflate(&strm, Z_FINISH);
+ if (ret != Z_STREAM_END) {
+ log_warn("compression failure: %s", strm.msg);
+ deflateEnd(&strm);
return -1;
- return 10 + z.total_out + 8;
+ }
+
+ deflateEnd(&strm);
+ return strm.total_out;
}
uint32_t
generate_crc32c(const uint8_t *string, size_t length)
{
- // zlib doesn't believe in size_t. When size_t is bigger than uInt,
- // we theoretically could break the operation up into uInt-sized
- // chunks to support the full range of size_t, but I doubt we will
- // ever need to crc32 more than 2^32 bytes, so I'm not bothering.
- // -- zw, 2012
log_assert(length <= std::numeric_limits<uInt>::max());
uLong crc = crc32(crc32(0, 0, 0), string, length);
1
0
commit f5a51ee02171da3ba825ff9ab8e1be1a30a96c22
Author: Zack Weinberg <zackw(a)cmu.edu>
Date: Mon Apr 30 16:32:46 2012 -0700
Don't use bzero.
---
src/steg/b64cookies.cc | 10 ++++------
src/steg/cookies.cc | 4 ++--
src/steg/http.cc | 6 +++---
src/steg/payloads.cc | 4 ++--
4 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/src/steg/b64cookies.cc b/src/steg/b64cookies.cc
index 2efa76a..4d85a8b 100644
--- a/src/steg/b64cookies.cc
+++ b/src/steg/b64cookies.cc
@@ -190,8 +190,8 @@ void desanitize_b64(char* input, int len) {
// srand(time(NULL));
-// bzero(data2, sizeof(data2));
-// bzero(outbuf, sizeof(outbuf));
+// memset(data2, 0, sizeof(data2));
+// memset(outbuf, 0, sizeof(outbuf));
// base64::encoder E;
// E.encode(data, strlen(data), data2);
@@ -208,7 +208,7 @@ void desanitize_b64(char* input, int len) {
// cookielen = gen_b64_cookie_field((char*) outbuf, (char*) data2, strlen(data2));
// printf("cookie=%s\n", outbuf);
-// bzero(data2, sizeof(data2));
+// memset(data2, 0, sizeof(data2));
// cookielen = unwrap_b64_cookie((char*) outbuf, (char*) data2, strlen(outbuf));
@@ -219,10 +219,8 @@ void desanitize_b64(char* input, int len) {
// data2[strlen(data2)] = '\n';
-// bzero(outbuf, 200);
+// memset(outbuf, 0, sizeof(outbuf));
-
-
// base64::decoder D;
// D.decode(data2, strlen(data2), outbuf);
// printf("%s\n", outbuf);
diff --git a/src/steg/cookies.cc b/src/steg/cookies.cc
index a945397..3a7abf5 100644
--- a/src/steg/cookies.cc
+++ b/src/steg/cookies.cc
@@ -216,10 +216,10 @@ int main () {
for (i=0; i < 1000000; i++) {
int cookielen = rand()%50 + 5;
- bzero(outbuf, sizeof(outbuf));
+ memset(outbuf, 0, sizeof(outbuf));
int len = gen_cookie_field(outbuf, cookielen, data, sizeof(data));
// printf("len = %d cookie = %s %d\n", len, outbuf, cookielen);
- bzero(data2, sizeof(data2));
+ memset(data2, 0, sizeof(data2));
int len2 = unwrap_cookie(outbuf, data2, cookielen);
// printf("unwrapped datalen = %d data = %s\n", len, data2);
diff --git a/src/steg/http.cc b/src/steg/http.cc
index c413cdc..cfeaf93 100644
--- a/src/steg/http.cc
+++ b/src/steg/http.cc
@@ -307,7 +307,7 @@ http_client_cookie_transmit (http_steg_t *s, struct evbuffer *source,
if (s->peer_dnsname[0] == '\0')
lookup_peer_name_from_ip(conn->peername, s->peer_dnsname);
- bzero(data2, sbuflen*4);
+ memset(data2, 0, sbuflen*4);
E.encode((char*) data, sbuflen, (char*) data2);
E.encode_end(data2+strlen((char*) data2));
@@ -668,12 +668,12 @@ http_server_receive(http_steg_t *s, conn_t *conn, struct evbuffer *dest, struct
log_abort(conn, "cookie too big: %lu (max %lu)",
(unsigned long)(pend - p), (unsigned long)MAX_COOKIE_SIZE);
- bzero(outbuf, sizeof(outbuf));
+ memset(outbuf, 0, sizeof(outbuf));
int cookielen = unwrap_b64_cookie((char*) p, (char*) outbuf, pend - p);
desanitize_b64(outbuf, cookielen);
outbuf[cookielen] = '\n';
- bzero(outbuf2, sizeof(outbuf2));
+ memset(outbuf2, 0, sizeof(outbuf2));
base64::decoder D;
sofar = D.decode(outbuf, cookielen+1, outbuf2);
diff --git a/src/steg/payloads.cc b/src/steg/payloads.cc
index 7116e36..3af80d4 100644
--- a/src/steg/payloads.cc
+++ b/src/steg/payloads.cc
@@ -199,7 +199,7 @@ void load_payloads(payloads& pl, const char* fname)
exit(1);
}
- bzero(pl.payload_hdrs, sizeof(pl.payload_hdrs));
+ memset(pl.payload_hdrs, 0, sizeof(pl.payload_hdrs));
pl.payload_count = 0;
while (pl.payload_count < MAX_PAYLOADS) {
@@ -1598,7 +1598,7 @@ void testCapacityJS () {
/*****
int main() {
char buf[HTTP_MSG_BUF_SIZE];
- bzero(buf, sizeof(buf));
+ memset(buf, 0, sizeof(buf));
// test for TYPE_HTTP_REQUEST
// load_payloads("../../traces/client.out");
// int len = find_client_payload(buf, 10000, TYPE_HTTP_REQUEST);
1
0
commit 2e75ae19337994837e61c741fa1c6866a58230bf
Author: Zack Weinberg <zackw(a)cmu.edu>
Date: Mon Apr 30 15:29:58 2012 -0700
Compression API compression.
* collapse def() and gzDeflate() together
* ditto inf() and gzInflate()
* new functions are named compress() and decompress()
* don't expose CRC generation
* don't set mtimes in deflate format
* zpack.{cc,h} renamed compression.{cc,h}
Mysteriously, this caused the 'crypt' unittest to start throwing bogus
warnings, so squelch those en passant.
---
Makefile.am | 8 +-
src/compression.cc | 102 ++++++++
src/compression.h | 35 +++
src/crypt.cc | 6 +-
src/steg/jsSteg.cc | 9 +-
src/steg/jsSteg.h | 1 -
src/steg/swfSteg.cc | 25 +--
src/test/unittest_compression.cc | 437 ++++++++++++++++++++++++++++++++
src/test/unittest_zlib.cc | 507 --------------------------------------
src/zpack.cc | 172 -------------
src/zpack.h | 21 --
11 files changed, 597 insertions(+), 726 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 3ded164..88939fd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -30,6 +30,7 @@ STEGANOGRAPHERS = \
libstegotorus_a_SOURCES = \
src/base64.cc \
+ src/compression.cc \
src/connections.cc \
src/crypt.cc \
src/network.cc \
@@ -38,7 +39,6 @@ libstegotorus_a_SOURCES = \
src/socks.cc \
src/steg.cc \
src/util.cc \
- src/zpack.cc \
$(PROTOCOLS) $(STEGANOGRAPHERS)
nodist_libstegotorus_a_SOURCES = protolist.cc steglist.cc
@@ -47,12 +47,12 @@ stegotorus_SOURCES = \
src/main.cc
UTGROUPS = \
+ src/test/unittest_compression.cc \
+ src/test/unittest_config.cc \
src/test/unittest_crypt.cc \
src/test/unittest_pdfsteg.cc \
src/test/unittest_socks.cc \
- src/test/unittest_config.cc \
- src/test/unittest_transfer.cc \
- src/test/unittest_zlib.cc
+ src/test/unittest_transfer.cc
unittests_SOURCES = \
src/test/tinytest.cc \
diff --git a/src/compression.cc b/src/compression.cc
new file mode 100644
index 0000000..2a0b2ef
--- /dev/null
+++ b/src/compression.cc
@@ -0,0 +1,102 @@
+/* Copyright 2011, 2012 SRI International
+ * See LICENSE for other credits and copying information
+ */
+#include "util.h"
+#include "compression.h"
+
+#include <zlib.h>
+#include <limits>
+
+// zlib doesn't believe in size_t. When size_t is bigger than uInt, we
+// theoretically could break operations up into uInt-sized chunks to
+// support the full range of size_t, but I doubt we will ever need to
+// compress, decompress, or crc32 more than 2^32 bytes in one
+// operation, so I'm not bothering. -- zw, 2012
+//
+// The indirection through ZLIB_UINT_MAX makes some versions of gcc
+// not produce a 'comparison is always (true/false)' warning.
+const size_t ZLIB_UINT_MAX = std::numeric_limits<uInt>::max();
+const size_t ZLIB_CEILING = (SIZE_T_CEILING > ZLIB_UINT_MAX
+ ? ZLIB_UINT_MAX : SIZE_T_CEILING);
+
+ssize_t
+compress(const uint8_t *source, size_t slen,
+ uint8_t *dest, size_t dlen,
+ compression_format fmt)
+{
+ log_assert(fmt == c_format_zlib || fmt == c_format_gzip);
+
+ if (slen > ZLIB_CEILING || dlen > ZLIB_CEILING)
+ return -1;
+
+ z_stream strm;
+ memset(&strm, 0, sizeof strm);
+
+ int wbits = MAX_WBITS;
+ if (fmt == c_format_gzip)
+ wbits |= 16; // magic number 16 = compress as gzip
+
+ int ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
+ wbits, 8, Z_DEFAULT_STRATEGY);
+ if (ret != Z_OK) {
+ log_warn("compression failure (initialization): %s", strm.msg);
+ return -1;
+ }
+
+ if (fmt == c_format_gzip) {
+ gz_header gzh;
+ memset(&gzh, 0, sizeof gzh);
+ gzh.os = 0xFF; // "unknown"
+ ret = deflateSetHeader(&strm, &gzh);
+ if (ret != Z_OK) {
+ log_warn("compression failure (initialization): %s", strm.msg);
+ return -1;
+ }
+ }
+
+ strm.next_in = const_cast<Bytef*>(source);
+ strm.avail_in = slen;
+ strm.next_out = dest;
+ strm.avail_out = dlen;
+
+ ret = deflate(&strm, Z_FINISH);
+ if (ret != Z_STREAM_END) {
+ log_warn("compression failure: %s", strm.msg);
+ deflateEnd(&strm);
+ return -1;
+ }
+
+ deflateEnd(&strm);
+ return strm.total_out;
+}
+
+ssize_t
+decompress(const uint8_t *source, size_t slen, uint8_t *dest, size_t dlen)
+{
+ if (slen > ZLIB_CEILING || dlen > ZLIB_CEILING)
+ return -1;
+
+ /* allocate inflate state */
+ z_stream strm;
+ memset(&strm, 0, sizeof strm);
+ int ret = inflateInit2(&strm, MAX_WBITS|32); /* autodetect gzip/zlib */
+ if (ret != Z_OK) {
+ log_warn("decompression failure (initialization): %s", strm.msg);
+ return -1;
+ }
+
+ strm.next_in = const_cast<Bytef*>(source);
+ strm.avail_in = slen;
+ strm.next_out = dest;
+ strm.avail_out = dlen;
+
+ ret = inflate(&strm, Z_FINISH);
+ if (ret != Z_STREAM_END) {
+ log_warn("decompression failure: %s", strm.msg);
+ inflateEnd(&strm);
+ return -1;
+ }
+
+ inflateEnd(&strm);
+ return strm.total_out;
+}
diff --git a/src/compression.h b/src/compression.h
new file mode 100644
index 0000000..ef1f75e
--- /dev/null
+++ b/src/compression.h
@@ -0,0 +1,35 @@
+/* Copyright 2011, 2012 SRI International
+ * See LICENSE for other credits and copying information
+ */
+#ifndef _COMPRESSION_H
+#define _COMPRESSION_H
+
+enum compression_format {
+ c_format_zlib = 0,
+ c_format_gzip = 1
+};
+
+/**
+ * Compress SLEN bytes of data from the buffer at SOURCE into the
+ * buffer at DEST. There are DLEN bytes of available space at the
+ * destination. FMT specifies the desired format of the compressed
+ * data: currently 'zlib' (RFC 1950) and 'gzip' (RFC 1952) formats are
+ * supported.
+ *
+ * Returns the amount of data actually written to DEST, or -1 on error.
+ */
+ssize_t compress(const uint8_t *source, size_t slen,
+ uint8_t *dest, size_t dlen,
+ compression_format fmt);
+
+/**
+ * Decompress SLEN bytes of data from the buffer at SOURCE into the
+ * buffer at DEST. There are DLEN bytes of available space at the
+ * destination. Automatically detects the compression format in use.
+ *
+ * Returns the amount of data actually written to DEST, or -1 on error.
+ */
+ssize_t decompress(const uint8_t *source, size_t slen,
+ uint8_t *dest, size_t dlen);
+
+#endif
diff --git a/src/crypt.cc b/src/crypt.cc
index e60cc41..053f7e6 100644
--- a/src/crypt.cc
+++ b/src/crypt.cc
@@ -384,8 +384,12 @@ gcm_decryptor_impl::decrypt(uint8_t *out, const uint8_t *in, size_t inlen,
if (!EVP_DecryptUpdate(&ctx, out, &olen, in, inlen) || size_t(olen) != inlen)
return log_crypto_warn("gcm_encryptor::decrypt");
- if (!EVP_DecryptFinal_ex(&ctx, out + inlen, &olen) || olen != 0)
+ if (!EVP_DecryptFinal_ex(&ctx, out + inlen, &olen) || olen != 0) {
+ /* don't warn for simple MAC failures */
+ if (!ERR_peek_error())
+ return -1;
return log_crypto_warn("gcm_decryptor::check tag");
+ }
return 0;
}
diff --git a/src/steg/jsSteg.cc b/src/steg/jsSteg.cc
index 8fee7cb..1d71918 100644
--- a/src/steg/jsSteg.cc
+++ b/src/steg/jsSteg.cc
@@ -5,6 +5,7 @@
#include "payloads.h"
#include "jsSteg.h"
#include "cookies.h"
+#include "compression.h"
void buf_dump(unsigned char* buf, int len, FILE *out);
@@ -828,8 +829,8 @@ http_server_JS_transmit (payloads& pl, struct evbuffer *source, conn_t *conn,
// sizeof outbuf2 = cLen + 10-byte for gzip header + 8-byte for crc
outbuf2 = (char *)xmalloc(cLen+18);
- outbuf2len = gzDeflate((const uint8_t *)outbuf, cLen,
- (uint8_t *)outbuf2, cLen+18, time(NULL));
+ outbuf2len = compress((const uint8_t *)outbuf, cLen,
+ (uint8_t *)outbuf2, cLen+18, c_format_gzip);
if (outbuf2len <= 0) {
log_warn("gzDeflate for outbuf fails");
@@ -992,8 +993,8 @@ http_handle_client_JS_receive(steg_t *, conn_t *conn, struct evbuffer *dest, str
gzipMode = isGzipContent(respMsg);
if (gzipMode) {
log_debug("gzip content encoding detected");
- buf2len = gzInflate((const uint8_t *)httpBody, httpBodyLen,
- (uint8_t *)buf2, HTTP_MSG_BUF_SIZE);
+ buf2len = decompress((const uint8_t *)httpBody, httpBodyLen,
+ (uint8_t *)buf2, HTTP_MSG_BUF_SIZE);
if (buf2len <= 0) {
log_warn("gzInflate for httpBody fails");
fprintf(stderr, "gzInflate for httpBody fails");
diff --git a/src/steg/jsSteg.h b/src/steg/jsSteg.h
index 576f91f..40ec611 100644
--- a/src/steg/jsSteg.h
+++ b/src/steg/jsSteg.h
@@ -13,7 +13,6 @@
#include "connections.h"
#include "steg.h"
#include <event2/buffer.h>
-#include "zpack.h"
// error codes
#define INVALID_BUF_SIZE -1
diff --git a/src/steg/swfSteg.cc b/src/steg/swfSteg.cc
index 77c425b..1510043 100644
--- a/src/steg/swfSteg.cc
+++ b/src/steg/swfSteg.cc
@@ -3,10 +3,9 @@
*/
#include "util.h"
#include "swfSteg.h"
+#include "compression.h"
#include "connections.h"
#include "payloads.h"
-#include "zlib.h"
-#include "zpack.h"
#include <event2/buffer.h>
@@ -62,18 +61,12 @@ swf_wrap(payloads& pl, char* inbuf, int in_len, char* outbuf, int out_sz) {
memcpy(tmp_buf, swf+8, SWF_SAVE_HEADER_LEN);
memcpy(tmp_buf+SWF_SAVE_HEADER_LEN, inbuf, in_len);
memcpy(tmp_buf+SWF_SAVE_HEADER_LEN+in_len, swf + in_swf_len - SWF_SAVE_FOOTER_LEN, SWF_SAVE_FOOTER_LEN);
- out_swf_len = def((const uint8_t *)tmp_buf,
- SWF_SAVE_HEADER_LEN + in_len + SWF_SAVE_FOOTER_LEN,
- (uint8_t *)tmp_buf2+8,
- in_len + SWF_SAVE_HEADER_LEN + SWF_SAVE_FOOTER_LEN + 512-8,
- Z_DEFAULT_COMPRESSION);
-
- // sprintf(hdr, "%s%d\r\n\r\n", http_response_1, out_swf_len + 8);
-
-
-
- // fprintf(stderr, "out_swf_len = %d\n", out_swf_len);
-
+ out_swf_len =
+ compress((const uint8_t *)tmp_buf,
+ SWF_SAVE_HEADER_LEN + in_len + SWF_SAVE_FOOTER_LEN,
+ (uint8_t *)tmp_buf2+8,
+ in_len + SWF_SAVE_HEADER_LEN + SWF_SAVE_FOOTER_LEN + 512-8,
+ c_format_zlib);
hdr_len = gen_response_header((char*) "application/x-shockwave-flash", 0, out_swf_len + 8, hdr, sizeof(hdr));
@@ -100,8 +93,8 @@ swf_unwrap(char* inbuf, int in_len, char* outbuf, int out_sz) {
tmp_buf = (char *)xmalloc(in_len * 8);
- inf_len = inf((const uint8_t *)inbuf + 8, in_len - 8,
- (uint8_t *)tmp_buf, in_len * 8);
+ inf_len = decompress((const uint8_t *)inbuf + 8, in_len - 8,
+ (uint8_t *)tmp_buf, in_len * 8);
// fprintf(stderr, "in_swf_len = %d\n", in_len -8 );
diff --git a/src/test/unittest_compression.cc b/src/test/unittest_compression.cc
new file mode 100644
index 0000000..e624d28
--- /dev/null
+++ b/src/test/unittest_compression.cc
@@ -0,0 +1,437 @@
+/* Copyright 2012 SRI International
+ * See LICENSE for other credits and copying information
+ */
+
+#include "util.h"
+#include "unittest.h"
+
+#include "compression.h"
+
+// Smoke tests for zlib.
+// Compressed strings generated with Python's 'zlib' and 'gzip'
+// modules, which wrap zlib, so they only constitute a round-trip
+// test, not a proper test. Z_DEFAULT_COMPRESSION (6) used in all
+// cases.
+//
+// If anyone knows a reliable source for "official" test vectors for
+// RFC 1950 through 1952, please let us know.
+
+struct zlib_testvec
+{
+ const uint8_t *text;
+ size_t tlen;
+ const uint8_t *zlibbed;
+ size_t zlen;
+ const uint8_t *gzipped;
+ size_t glen;
+};
+
+#define GZH(g) \
+ "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff" g
+
+#define T(t, z, g) \
+ { (const uint8_t *)t, sizeof t - 1, \
+ (const uint8_t *)z, sizeof z - 1, \
+ (const uint8_t *)GZH(g), sizeof GZH(g) - 1 }
+
+const zlib_testvec testvecs[] = {
+ // the empty string
+ T("",
+ "\x78\x9c\x03\x00\x00\x00\x00\x01",
+ "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
+
+ // 4-byte messages
+ T("\x00\x00\x00\x00",
+ "\x78\x9c\x63\x60\x60\x60\x00\x00\x00\x04\x00\x01",
+ "\x63\x60\x60\x60\x00\x00\x1c\xdf\x44\x21\x04\x00\x00\x00"),
+ T("\x11\x11\x11\x11",
+ "\x78\x9c\x13\x14\x14\x14\x04\x00\x00\xae\x00\x45",
+ "\x13\x14\x14\x14\x04\x00\x43\x25\x6c\xed\x04\x00\x00\x00"),
+ T("\x22\x22\x22\x22",
+ "\x78\x9c\x53\x52\x52\x52\x02\x00\x01\x58\x00\x89",
+ "\x53\x52\x52\x52\x02\x00\xe3\x2d\x64\x62\x04\x00\x00\x00"),
+ T("\x33\x33\x33\x33",
+ "\x78\x9c\x33\x36\x36\x36\x06\x00\x02\x02\x00\xcd",
+ "\x33\x36\x36\x36\x06\x00\xbc\xd7\x4c\xae\x04\x00\x00\x00"),
+ T("\x44\x44\x44\x44",
+ "\x78\x9c\x73\x71\x71\x71\x01\x00\x02\xac\x01\x11",
+ "\x73\x71\x71\x71\x01\x00\xe2\x3a\x05\xa7\x04\x00\x00\x00"),
+ T("\x55\x55\x55\x55",
+ "\x78\x9c\x0b\x0d\x0d\x0d\x05\x00\x03\x56\x01\x55",
+ "\x0b\x0d\x0d\x0d\x05\x00\xbd\xc0\x2d\x6b\x04\x00\x00\x00"),
+ T("\x66\x66\x66\x66",
+ "\x78\x9c\x4b\x4b\x4b\x4b\x03\x00\x04\x00\x01\x99",
+ "\x4b\x4b\x4b\x4b\x03\x00\x1d\xc8\x25\xe4\x04\x00\x00\x00"),
+ T("\x77\x77\x77\x77",
+ "\x78\x9c\x2b\x2f\x2f\x2f\x07\x00\x04\xaa\x01\xdd",
+ "\x2b\x2f\x2f\x2f\x07\x00\x42\x32\x0d\x28\x04\x00\x00\x00"),
+ T("\x88\x88\x88\x88",
+ "\x78\x9c\xeb\xe8\xe8\xe8\x00\x00\x05\x54\x02\x21",
+ "\xeb\xe8\xe8\xe8\x00\x00\xa1\x12\xb6\xf6\x04\x00\x00\x00"),
+ T("\x99\x99\x99\x99",
+ "\x78\x9c\x9b\x39\x73\xe6\x4c\x00\x05\xfe\x02\x65",
+ "\x9b\x39\x73\xe6\x4c\x00\xfe\xe8\x9e\x3a\x04\x00\x00\x00"),
+ T("\xaa\xaa\xaa\xaa",
+ "\x78\x9c\x5b\xb5\x6a\xd5\x2a\x00\x06\xa8\x02\xa9",
+ "\x5b\xb5\x6a\xd5\x2a\x00\x5e\xe0\x96\xb5\x04\x00\x00\x00"),
+ T("\xbb\xbb\xbb\xbb",
+ "\x78\x9c\xdb\xbd\x7b\xf7\x6e\x00\x07\x52\x02\xed",
+ "\xdb\xbd\x7b\xf7\x6e\x00\x01\x1a\xbe\x79\x04\x00\x00\x00"),
+ T("\xcc\xcc\xcc\xcc",
+ "\x78\x9c\x3b\x73\xe6\xcc\x19\x00\x07\xfc\x03\x31",
+ "\x3b\x73\xe6\xcc\x19\x00\x5f\xf7\xf7\x70\x04\x00\x00\x00"),
+ T("\xdd\xdd\xdd\xdd",
+ "\x78\x9c\xbb\x7b\xf7\xee\x5d\x00\x08\xa6\x03\x75",
+ "\xbb\x7b\xf7\xee\x5d\x00\x00\x0d\xdf\xbc\x04\x00\x00\x00"),
+ T("\xee\xee\xee\xee",
+ "\x78\x9c\x7b\xf7\xee\xdd\x3b\x00\x09\x50\x03\xb9",
+ "\x7b\xf7\xee\xdd\x3b\x00\xa0\x05\xd7\x33\x04\x00\x00\x00"),
+ T("\xff\xff\xff\xff",
+ "\x78\x9c\xfb\xff\xff\xff\x7f\x00\x09\xfa\x03\xfd",
+ "\xfb\xff\xff\xff\x7f\x00\xff\xff\xff\xff\x04\x00\x00\x00"),
+ T("\x40\x49\x0f\xdb", // pi (IEEE single)
+ "\x78\x9c\x73\xf0\xe4\xbf\x0d\x00\x02\xd8\x01\x74",
+ "\x73\xf0\xe4\xbf\x0d\x00\xfd\x26\x82\x53\x04\x00\x00\x00"),
+
+ // 8-byte messages
+ T("\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x78\x9c\x63\x60\x80\x00\x00\x00\x08\x00\x01",
+ "\x63\x60\x80\x00\x00\x69\xdf\x22\x65\x08\x00\x00\x00"),
+ T("\x00\x00\x00\x00\xff\xff\xff\xff",
+ "\x78\x9c\x63\x60\x60\x60\xf8\x0f\x04\x00\x09\xfe\x03\xfd",
+ "\x63\x60\x60\x60\xf8\x0f\x04\x00\x8a\xff\x99\xbb\x08\x00\x00\x00"),
+ T("\xff\xff\xff\xff\x00\x00\x00\x00",
+ "\x78\x9c\xfb\xff\xff\xff\x7f\x06\x20\x00\x00\x19\xee\x03\xfd",
+ "\xfb\xff\xff\xff\x7f\x06\x20\x00\x00\xff\xff\xff\xff\x08\x00\x00\x00"),
+ T("\xff\xff\xff\xff\xff\xff\xff\xff",
+ "\x78\x9c\xfb\xff\x1f\x02\x00\x23\xe4\x07\xf9",
+ "\xfb\xff\x1f\x02\x00\x1c\xdf\x44\x21\x08\x00\x00\x00"),
+ T("\x55\x55\x55\x55\x55\x55\x55\x55",
+ "\x78\x9c\x0b\x0d\x85\x00\x00\x0b\xfc\x02\xa9",
+ "\x0b\x0d\x85\x00\x00\x85\x22\xd0\xef\x08\x00\x00\x00"),
+ T("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ "\x78\x9c\x5b\xb5\x0a\x02\x00\x17\xf0\x05\x51",
+ "\x5b\xb5\x0a\x02\x00\xf0\x22\xb6\xab\x08\x00\x00\x00"),
+ T("\x40\x09\x21\xfb\x54\x44\x2d\x18", // pi (IEEE double)
+ "\x78\x9c\x73\xe0\x54\xfc\x1d\xe2\xa2\x2b\x01\x00\x0a\x82\x02\x43",
+ "\x73\xe0\x54\xfc\x1d\xe2\xa2\x2b\x01\x00\xd8\x90\x89\x2a\x08\x00\x00\x00"),
+
+ // 32-byte messages: all possible bytes occur once
+ T("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ "\x78\x9c\x63\x60\x64\x62\x66\x61\x65\x63\xe7\xe0\xe4\xe2\xe6\xe1"
+ "\xe5\xe3\x17\x10\x14\x12\x16\x11\x15\x13\x97\x90\x94\x92\x96\x91"
+ "\x95\x93\x07\x00\x15\x70\x01\xf1",
+ "\x63\x60\x64\x62\x66\x61\x65\x63\xe7\xe0\xe4\xe2\xe6\xe1\xe5\xe3"
+ "\x17\x10\x14\x12\x16\x11\x15\x13\x97\x90\x94\x92\x96\x91\x95\x93"
+ "\x07\x00\x8a\x7e\x26\x91\x20\x00\x00\x00"),
+ T("\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f",
+ "\x78\x9c\x53\x50\x54\x52\x56\x51\x55\x53\xd7\xd0\xd4\xd2\xd6\xd1"
+ "\xd5\xd3\x37\x30\x34\x32\x36\x31\x35\x33\xb7\xb0\xb4\xb2\xb6\xb1"
+ "\xb5\xb3\x07\x00\x57\x70\x05\xf1",
+ "\x53\x50\x54\x52\x56\x51\x55\x53\xd7\xd0\xd4\xd2\xd6\xd1\xd5\xd3"
+ "\x37\x30\x34\x32\x36\x31\x35\x33\xb7\xb0\xb4\xb2\xb6\xb1\xb5\xb3"
+ "\x07\x00\xe3\x06\xa6\xf6\x20\x00\x00\x00"),
+ T("\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f",
+ "\x78\x9c\x73\x70\x74\x72\x76\x71\x75\x73\xf7\xf0\xf4\xf2\xf6\xf1"
+ "\xf5\xf3\x0f\x08\x0c\x0a\x0e\x09\x0d\x0b\x8f\x88\x8c\x8a\x8e\x89"
+ "\x8d\x8b\x07\x00\x99\x70\x09\xf1",
+ "\x73\x70\x74\x72\x76\x71\x75\x73\xf7\xf0\xf4\xf2\xf6\xf1\xf5\xf3"
+ "\x0f\x08\x0c\x0a\x0e\x09\x0d\x0b\x8f\x88\x8c\x8a\x8e\x89\x8d\x8b"
+ "\x07\x00\x58\x8e\x26\x5e\x20\x00\x00\x00"),
+ T("\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f",
+ "\x78\x9c\x4b\x48\x4c\x4a\x4e\x49\x4d\x4b\xcf\xc8\xcc\xca\xce\xc9"
+ "\xcd\xcb\x2f\x28\x2c\x2a\x2e\x29\x2d\x2b\xaf\xa8\xac\xaa\xae\xa9"
+ "\xad\xab\x07\x00\xdb\x70\x0d\xf1",
+ "\x4b\x48\x4c\x4a\x4e\x49\x4d\x4b\xcf\xc8\xcc\xca\xce\xc9\xcd\xcb"
+ "\x2f\x28\x2c\x2a\x2e\x29\x2d\x2b\xaf\xa8\xac\xaa\xae\xa9\xad\xab"
+ "\x07\x00\x31\xf6\xa6\x39\x20\x00\x00\x00"),
+ T("\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f",
+ "\x78\x9c\x01\x20\x00\xdf\xff\x80\x81\x82\x83\x84\x85\x86\x87\x88"
+ "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98"
+ "\x99\x9a\x9b\x9c\x9d\x9e\x9f\x1d\x7f\x11\xf1",
+ "\x01\x20\x00\xdf\xff\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a"
+ "\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a"
+ "\x9b\x9c\x9d\x9e\x9f\x6f\x99\x56\xd4\x20\x00\x00\x00"),
+ T("\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf",
+ "\x78\x9c\x01\x20\x00\xdf\xff\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+ "\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
+ "\xb9\xba\xbb\xbc\xbd\xbe\xbf\x5f\x7f\x15\xf1",
+ "\x01\x20\x00\xdf\xff\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa"
+ "\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba"
+ "\xbb\xbc\xbd\xbe\xbf\x06\xe1\xd6\xb3\x20\x00\x00\x00"),
+ T("\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf",
+ "\x78\x9c\x01\x20\x00\xdf\xff\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8"
+ "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
+ "\xd9\xda\xdb\xdc\xdd\xde\xdf\xa1\x7f\x19\xf1",
+ "\x01\x20\x00\xdf\xff\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca"
+ "\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda"
+ "\xdb\xdc\xdd\xde\xdf\xbd\x69\x56\x1b\x20\x00\x00\x00"),
+ T("\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ "\x78\x9c\x01\x20\x00\xdf\xff\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
+ "\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8"
+ "\xf9\xfa\xfb\xfc\xfd\xfe\xff\xe3\x7f\x1d\xf1",
+ "\x01\x20\x00\xdf\xff\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea"
+ "\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa"
+ "\xfb\xfc\xfd\xfe\xff\xd4\x11\xd6\x7c\x20\x00\x00\x00"),
+
+ // 26- to 40-letter pangrams from Wikipedia, all nonletters removed,
+ // all lowercase
+ T("cwmfjordbankglyphsvextquiz",
+ "\x78\x9c\x4b\x2e\xcf\x4d\xcb\xca\x2f\x4a\x49\x4a\xcc\xcb\x4e\xcf"
+ "\xa9\x2c\xc8\x28\x2e\x4b\xad\x28\x29\x2c\xcd\xac\x02\x00\x93\xd9"
+ "\x0b\x20",
+ "\x4b\x2e\xcf\x4d\xcb\xca\x2f\x4a\x49\x4a\xcc\xcb\x4e\xcf\xa9\x2c"
+ "\xc8\x28\x2e\x4b\xad\x28\x29\x2c\xcd\xac\x02\x00\x10\x89\x30\x81"
+ "\x1a\x00\x00\x00"),
+ T("nymphsblitzquickvexdwarfjog",
+ "\x78\x9c\xcb\xab\xcc\x2d\xc8\x28\x4e\xca\xc9\x2c\xa9\x2a\x2c\xcd"
+ "\x4c\xce\x2e\x4b\xad\x48\x29\x4f\x2c\x4a\xcb\xca\x4f\x07\x00\xa2"
+ "\xd1\x0b\x89",
+ "\xcb\xab\xcc\x2d\xc8\x28\x4e\xca\xc9\x2c\xa9\x2a\x2c\xcd\x4c\xce"
+ "\x2e\x4b\xad\x48\x29\x4f\x2c\x4a\xcb\xca\x4f\x07\x00\xae\x01\xb2"
+ "\xc9\x1b\x00\x00\x00"),
+ T("brickquizwhangsjumpyveldtfox",
+ "\x78\x9c\x4b\x2a\xca\x4c\xce\x2e\x2c\xcd\xac\x2a\xcf\x48\xcc\x4b"
+ "\x2f\xce\x2a\xcd\x2d\xa8\x2c\x4b\xcd\x49\x29\x49\xcb\xaf\x00\x00"
+ "\xac\xcf\x0b\xfe",
+ "\x4b\x2a\xca\x4c\xce\x2e\x2c\xcd\xac\x2a\xcf\x48\xcc\x4b\x2f\xce"
+ "\x2a\xcd\x2d\xa8\x2c\x4b\xcd\x49\x29\x49\xcb\xaf\x00\x00\xeb\x36"
+ "\x78\xc1\x1c\x00\x00\x00"),
+ T("vexednymphsgoforquickwaltzjob",
+ "\x78\x9c\x2b\x4b\xad\x48\x4d\xc9\xab\xcc\x2d\xc8\x28\x4e\xcf\x4f"
+ "\xcb\x2f\x2a\x2c\xcd\x4c\xce\x2e\x4f\xcc\x29\xa9\xca\xca\x4f\x02"
+ "\x00\xba\x43\x0c\x63",
+ "\x2b\x4b\xad\x48\x4d\xc9\xab\xcc\x2d\xc8\x28\x4e\xcf\x4f\xcb\x2f"
+ "\x2a\x2c\xcd\x4c\xce\x2e\x4f\xcc\x29\xa9\xca\xca\x4f\x02\x00\x60"
+ "\x23\x8c\xea\x1d\x00\x00\x00"),
+ T("bothfickledwarvesjinxmypigquiz",
+ "\x78\x9c\x4b\xca\x2f\xc9\x48\xcb\x4c\xce\xce\x49\x4d\x29\x4f\x2c"
+ "\x2a\x4b\x2d\xce\xca\xcc\xab\xc8\xad\x2c\xc8\x4c\x2f\x2c\xcd\xac"
+ "\x02\x00\xc2\xd3\x0c\xc0",
+ "\x4b\xca\x2f\xc9\x48\xcb\x4c\xce\xce\x49\x4d\x29\x4f\x2c\x2a\x4b"
+ "\x2d\xce\xca\xcc\xab\xc8\xad\x2c\xc8\x4c\x2f\x2c\xcd\xac\x02\x00"
+ "\x5f\x5f\x7c\x3c\x1e\x00\x00\x00"),
+ T("ficklejinxbogdwarvesspymathquiz",
+ "\x78\x9c\x4b\xcb\x4c\xce\xce\x49\xcd\xca\xcc\xab\x48\xca\x4f\x4f"
+ "\x29\x4f\x2c\x2a\x4b\x2d\x2e\x2e\xa8\xcc\x4d\x2c\xc9\x28\x2c\xcd"
+ "\xac\x02\x00\xcf\x8d\x0d\x2b",
+ "\x4b\xcb\x4c\xce\xce\x49\xcd\xca\xcc\xab\x48\xca\x4f\x4f\x29\x4f"
+ "\x2c\x2a\x4b\x2d\x2e\x2e\xa8\xcc\x4d\x2c\xc9\x28\x2c\xcd\xac\x02"
+ "\x00\x07\x28\x86\x75\x1f\x00\x00\x00"),
+ T("averybadquackmightjinxzippyfowls",
+ "\x78\x9c\x4b\x2c\x4b\x2d\xaa\x4c\x4a\x4c\x29\x2c\x4d\x4c\xce\xce"
+ "\xcd\x4c\xcf\x28\xc9\xca\xcc\xab\xa8\xca\x2c\x28\xa8\x4c\xcb\x2f"
+ "\xcf\x29\x06\x00\xdd\xb8\x0d\x9d",
+ "\x4b\x2c\x4b\x2d\xaa\x4c\x4a\x4c\x29\x2c\x4d\x4c\xce\xce\xcd\x4c"
+ "\xcf\x28\xc9\xca\xcc\xab\xa8\xca\x2c\x28\xa8\x4c\xcb\x2f\xcf\x29"
+ "\x06\x00\xaa\x73\x33\x56\x20\x00\x00\x00"),
+ T("aquickbrownfoxjumpsoverthelazydog",
+ "\x78\x9c\x4b\x2c\x2c\xcd\x4c\xce\x4e\x2a\xca\x2f\xcf\x4b\xcb\xaf"
+ "\xc8\x2a\xcd\x2d\x28\xce\x2f\x4b\x2d\x2a\xc9\x48\xcd\x49\xac\xaa"
+ "\x4c\xc9\x4f\x07\x00\xef\x3d\x0e\x1a",
+ "\x4b\x2c\x2c\xcd\x4c\xce\x4e\x2a\xca\x2f\xcf\x4b\xcb\xaf\xc8\x2a"
+ "\xcd\x2d\x28\xce\x2f\x4b\x2d\x2a\xc9\x48\xcd\x49\xac\xaa\x4c\xc9"
+ "\x4f\x07\x00\x00\x66\xdf\x56\x21\x00\x00\x00"),
+ T("quizzicaltwinsprovedmyhijackbugfix",
+ "\x78\x9c\x2b\x2c\xcd\xac\xaa\xca\x4c\x4e\xcc\x29\x29\xcf\xcc\x2b"
+ "\x2e\x28\xca\x2f\x4b\x4d\xc9\xad\xcc\xc8\xcc\x4a\x4c\xce\x4e\x2a"
+ "\x4d\x4f\xcb\xac\x00\x00\xff\xe8\x0e\x77",
+ "\x2b\x2c\xcd\xac\xaa\xca\x4c\x4e\xcc\x29\x29\xcf\xcc\x2b\x2e\x28"
+ "\xca\x2f\x4b\x4d\xc9\xad\xcc\xc8\xcc\x4a\x4c\xce\x4e\x2a\x4d\x4f"
+ "\xcb\xac\x00\x00\x01\x07\x14\xb7\x22\x00\x00\x00"),
+ T("whenzombiesarrivequicklyfaxjudgepat",
+ "\x78\x9c\x2b\xcf\x48\xcd\xab\xca\xcf\x4d\xca\x4c\x2d\x4e\x2c\x2a"
+ "\xca\x2c\x4b\x2d\x2c\xcd\x4c\xce\xce\xa9\x4c\x4b\xac\xc8\x2a\x4d"
+ "\x49\x4f\x2d\x48\x2c\x01\x00\x0b\x5d\x0e\xca",
+ "\x2b\xcf\x48\xcd\xab\xca\xcf\x4d\xca\x4c\x2d\x4e\x2c\x2a\xca\x2c"
+ "\x4b\x2d\x2c\xcd\x4c\xce\xce\xa9\x4c\x4b\xac\xc8\x2a\x4d\x49\x4f"
+ "\x2d\x48\x2c\x01\x00\xae\xef\x98\xc3\x23\x00\x00\x00"),
+ T("heavyboxesperformquickwaltzesandjigs",
+ "\x78\x9c\xcb\x48\x4d\x2c\xab\x4c\xca\xaf\x48\x2d\x2e\x48\x2d\x4a"
+ "\xcb\x2f\xca\x2d\x2c\xcd\x4c\xce\x2e\x4f\xcc\x29\xa9\x4a\x2d\x4e"
+ "\xcc\x4b\xc9\xca\x4c\x2f\x06\x00\x1a\xc0\x0f\x41",
+ "\xcb\x48\x4d\x2c\xab\x4c\xca\xaf\x48\x2d\x2e\x48\x2d\x4a\xcb\x2f"
+ "\xca\x2d\x2c\xcd\x4c\xce\x2e\x4f\xcc\x29\xa9\x4a\x2d\x4e\xcc\x4b"
+ "\xc9\xca\x4c\x2f\x06\x00\x71\xc5\x60\xbb\x24\x00\x00\x00"),
+ T("fakebugsputinwaxjonquilsdrivehimcrazy",
+ "\x78\x9c\x4b\x4b\xcc\x4e\x4d\x2a\x4d\x2f\x2e\x28\x2d\xc9\xcc\x2b"
+ "\x4f\xac\xc8\xca\xcf\x2b\x2c\xcd\xcc\x29\x4e\x29\xca\x2c\x4b\xcd"
+ "\xc8\xcc\x4d\x2e\x4a\xac\xaa\x04\x00\x29\x9e\x0f\xbf",
+ "\x4b\x4b\xcc\x4e\x4d\x2a\x4d\x2f\x2e\x28\x2d\xc9\xcc\x2b\x4f\xac"
+ "\xc8\xca\xcf\x2b\x2c\xcd\xcc\x29\x4e\x29\xca\x2c\x4b\xcd\xc8\xcc"
+ "\x4d\x2e\x4a\xac\xaa\x04\x00\xf0\x24\xc5\xa1\x25\x00\x00\x00"),
+ T("wovensilkpyjamasexchangedforbluequartz",
+ "\x78\x9c\x2b\xcf\x2f\x4b\xcd\x2b\xce\xcc\xc9\x2e\xa8\xcc\x4a\xcc"
+ "\x4d\x2c\x4e\xad\x48\xce\x48\xcc\x4b\x4f\x4d\x49\xcb\x2f\x4a\xca"
+ "\x29\x4d\x2d\x2c\x4d\x2c\x2a\xa9\x02\x00\x39\xef\x10\x15",
+ "\x2b\xcf\x2f\x4b\xcd\x2b\xce\xcc\xc9\x2e\xa8\xcc\x4a\xcc\x4d\x2c"
+ "\x4e\xad\x48\xce\x48\xcc\x4b\x4f\x4d\x49\xcb\x2f\x4a\xca\x29\x4d"
+ "\x2d\x2c\x4d\x2c\x2a\xa9\x02\x00\x4e\x06\x7f\x9a\x26\x00\x00\x00"),
+ T("thequickonyxgoblinjumpsoverthelazydwarf",
+ "\x78\x9c\x2b\xc9\x48\x2d\x2c\xcd\x4c\xce\xce\xcf\xab\xac\x48\xcf"
+ "\x4f\xca\xc9\xcc\xcb\x2a\xcd\x2d\x28\xce\x2f\x4b\x2d\x2a\xc9\x48"
+ "\xcd\x49\xac\xaa\x4c\x29\x4f\x2c\x4a\x03\x00\x4d\x76\x10\xa8",
+ "\x2b\xc9\x48\x2d\x2c\xcd\x4c\xce\xce\xcf\xab\xac\x48\xcf\x4f\xca"
+ "\xc9\xcc\xcb\x2a\xcd\x2d\x28\xce\x2f\x4b\x2d\x2a\xc9\x48\xcd\x49"
+ "\xac\xaa\x4c\x29\x4f\x2c\x4a\x03\x00\x12\x87\x47\x3b\x27\x00\x00\x00"),
+ T("amazinglyfewdiscothequesprovidejukeboxes",
+ "\x78\x9c\x4b\xcc\x4d\xac\xca\xcc\x4b\xcf\xa9\x4c\x4b\x2d\x4f\xc9"
+ "\x2c\x4e\xce\x2f\xc9\x48\x2d\x2c\x4d\x2d\x2e\x28\xca\x2f\xcb\x4c"
+ "\x49\xcd\x2a\xcd\x4e\x4d\xca\xaf\x48\x2d\x06\x00\x59\xbe\x10\xe9",
+ "\x4b\xcc\x4d\xac\xca\xcc\x4b\xcf\xa9\x4c\x4b\x2d\x4f\xc9\x2c\x4e"
+ "\xce\x2f\xc9\x48\x2d\x2c\x4d\x2d\x2e\x28\xca\x2f\xcb\x4c\x49\xcd"
+ "\x2a\xcd\x4e\x4d\xca\xaf\x48\x2d\x06\x00\xa3\xe4\xdd\x7d\x28\x00\x00\x00"),
+
+ // self-describing pangram by Lee Sallows (SciAm, 1984)
+ T("This Pangram contains four as, one b, two cs, one d, thirty es, "
+ "six fs, five gs, seven hs, eleven is, one j, one k, two ls, two ms, "
+ "eighteen ns, fifteen os, two ps, one q, five rs, twenty-seven ss, "
+ "eighteen ts, two us, seven vs, eight ws, two xs, three ys, & one z.",
+ "\x78\x9c\x4d\x4e\xcd\x1a\xc2\x20\x0c\x7b\x95\x9c\x3c\x4d\x9f\xc5"
+ "\x83\x2f\x80\xb3\x8c\xea\x56\x14\xd8\x0f\x3e\xbd\x0c\xaa\x9f\xa7"
+ "\xa4\x69\x92\xf6\xe2\x38\xe2\x6c\x64\x08\x66\x42\xef\x25\x19\x96"
+ "\x08\xeb\xe7\x00\x13\x3b\x78\x21\x5c\x3b\xa4\xd5\xa3\xd7\xf1\x56"
+ "\x46\xc7\x21\x65\x50\x51\x22\x6f\xb0\x05\x2d\x2f\x84\x61\x17\x68"
+ "\x21\x81\x2b\x8c\xc6\x4a\x59\x73\xf7\x06\x8f\xd6\x36\xc6\x86\xd3"
+ "\x6e\xe4\xc1\x25\x2a\x56\xa9\x45\xb6\x72\xaf\x86\xa7\xc6\x5f\x7a"
+ "\x23\x54\x9d\x24\xe5\x63\x3b\x15\xff\x1b\x92\xa6\xe6\xdf\x27\xcb"
+ "\x77\x8d\x55\x77\xdb\x8e\x2e\x10\x21\x17\x76\xa8\xed\xef\xd3\x07"
+ "\xaa\x0c\x59\x5f",
+ "\x4d\x4e\xcd\x1a\xc2\x20\x0c\x7b\x95\x9c\x3c\x4d\x9f\xc5\x83\x2f"
+ "\x80\xb3\x8c\xea\x56\x14\xd8\x0f\x3e\xbd\x0c\xaa\x9f\xa7\xa4\x69"
+ "\x92\xf6\xe2\x38\xe2\x6c\x64\x08\x66\x42\xef\x25\x19\x96\x08\xeb"
+ "\xe7\x00\x13\x3b\x78\x21\x5c\x3b\xa4\xd5\xa3\xd7\xf1\x56\x46\xc7"
+ "\x21\x65\x50\x51\x22\x6f\xb0\x05\x2d\x2f\x84\x61\x17\x68\x21\x81"
+ "\x2b\x8c\xc6\x4a\x59\x73\xf7\x06\x8f\xd6\x36\xc6\x86\xd3\x6e\xe4"
+ "\xc1\x25\x2a\x56\xa9\x45\xb6\x72\xaf\x86\xa7\xc6\x5f\x7a\x23\x54"
+ "\x9d\x24\xe5\x63\x3b\x15\xff\x1b\x92\xa6\xe6\xdf\x27\xcb\x77\x8d"
+ "\x55\x77\xdb\x8e\x2e\x10\x21\x17\x76\xa8\xed\xef\xd3\x07\x11\xb4"
+ "\xb5\x3a\x09\x01\x00\x00"),
+
+ // "Lion-Eating Poet in the Stone Den" by Chao Yuen Ren,
+ // Simplified Chinese text in UTF-8
+ T("\xe3\x80\x8a\xe6\x96\xbd\xe6\xb0\x8f\xe9\xa3\x9f\xe7\x8b\xae\xe5\x8f"
+ "\xb2\xe3\x80\x8b \xe7\x9f\xb3\xe5\xae\xa4\xe8\xaf\x97\xe5\xa3\xab\xe6"
+ "\x96\xbd\xe6\xb0\x8f\xef\xbc\x8c\xe5\x97\x9c\xe7\x8b\xae\xef\xbc\x8c"
+ "\xe8\xaa\x93\xe9\xa3\x9f\xe5\x8d\x81\xe7\x8b\xae\xe3\x80\x82 \xe6\xb0"
+ "\x8f\xe6\x97\xb6\xe6\x97\xb6\xe9\x80\x82\xe5\xb8\x82\xe8\xa7\x86\xe7"
+ "\x8b\xae\xe3\x80\x82 \xe5\x8d\x81\xe6\x97\xb6\xef\xbc\x8c\xe9\x80\x82"
+ "\xe5\x8d\x81\xe7\x8b\xae\xe9\x80\x82\xe5\xb8\x82\xe3\x80\x82 \xe6\x98"
+ "\xaf\xe6\x97\xb6\xef\xbc\x8c\xe9\x80\x82\xe6\x96\xbd\xe6\xb0\x8f\xe9"
+ "\x80\x82\xe5\xb8\x82\xe3\x80\x82 \xe6\xb0\x8f\xe8\xa7\x86\xe6\x98\xaf"
+ "\xe5\x8d\x81\xe7\x8b\xae\xef\xbc\x8c\xe6\x81\x83\xe7\x9f\xa2\xe5\x8a"
+ "\xbf\xef\xbc\x8c\xe4\xbd\xbf\xe6\x98\xaf\xe5\x8d\x81\xe7\x8b\xae\xe9"
+ "\x80\x9d\xe4\xb8\x96\xe3\x80\x82 \xe6\xb0\x8f\xe6\x8b\xbe\xe6\x98\xaf"
+ "\xe5\x8d\x81\xe7\x8b\xae\xe5\xb0\xb8\xef\xbc\x8c\xe9\x80\x82\xe7\x9f"
+ "\xb3\xe5\xae\xa4\xe3\x80\x82 \xe7\x9f\xb3\xe5\xae\xa4\xe6\xb9\xbf\xef"
+ "\xbc\x8c\xe6\xb0\x8f\xe4\xbd\xbf\xe4\xbe\x8d\xe6\x8b\xad\xe7\x9f\xb3"
+ "\xe5\xae\xa4\xe3\x80\x82 \xe7\x9f\xb3\xe5\xae\xa4\xe6\x8b\xad\xef\xbc"
+ "\x8c\xe6\xb0\x8f\xe5\xa7\x8b\xe8\xaf\x95\xe9\xa3\x9f\xe6\x98\xaf\xe5"
+ "\x8d\x81\xe7\x8b\xae\xe3\x80\x82 \xe9\xa3\x9f\xe6\x97\xb6\xef\xbc\x8c"
+ "\xe5\xa7\x8b\xe8\xaf\x86\xe6\x98\xaf\xe5\x8d\x81\xe7\x8b\xae\xe5\xb0"
+ "\xb8\xef\xbc\x8c\xe5\xae\x9e\xe5\x8d\x81\xe7\x9f\xb3\xe7\x8b\xae\xe5"
+ "\xb0\xb8\xe3\x80\x82 \xe8\xaf\x95\xe9\x87\x8a\xe6\x98\xaf\xe4\xba\x8b"
+ "\xe3\x80\x82",
+ "\x78\x9c\x65\x8f\xdd\x0a\x82\x40\x10\x46\x5f\xc5\x47\x5d\x0d\x0c"
+ "\xdc\xc4\x8b\x48\xbb\xa8\x84\x0c\x84\xc2\x1f\x12\xc2\x22\xf5\x61"
+ "\x74\x56\xbd\xea\x15\xfa\x76\xd7\x0c\x0a\xf6\x62\x66\xcf\x99\x6f"
+ "\x67\x5b\xe6\x08\xbf\x12\xb9\x37\x46\x61\xcf\x53\xf2\xae\x2d\xe3"
+ "\x46\x1f\x16\x94\x9e\x86\x2c\xa0\xe8\xa2\xf1\xeb\xb9\xa2\x60\x07"
+ "\x03\xc5\x70\x5e\xc3\x26\xd7\x44\xdb\x32\xcb\x00\x16\xc1\x0d\x67"
+ "\x64\x16\x95\xd6\x10\xdb\x13\x80\x82\x5b\x4c\x48\xa0\x74\x6d\xa8"
+ "\xa1\x6d\x36\xb3\x69\x83\x2f\xcb\x3d\x84\xc0\xd0\x43\x90\x84\xb9"
+ "\xe8\xc3\x23\x39\x0d\xea\xae\x6a\x66\x34\xb2\x7d\x57\xfa\x9f\x25"
+ "\x78\x3d\x03\xca\x4b\x9d\xad\xbf\x22\x0d\x5d\x89\xbb\xcc\x80\x8d"
+ "\x98\xae\x76\x05\x4f\xfe\x0c\x9e\x68\x83\x62\x3e\x64\x1b\x7c\x75"
+ "\x4e\x95\x92\xec\xd5\xe2\x0a\xdb\x3f\x2f\x52\x7a\x90\x6d\x58\xe8"
+ "\x1b\x39\x20\x33\x96\x0e\xbc\xee\xc1\xd1\xbf\x01\xae\x11\xff\x53",
+ "\x65\x8f\xdd\x0a\x82\x40\x10\x46\x5f\xc5\x47\x5d\x0d\x0c\xdc\xc4"
+ "\x8b\x48\xbb\xa8\x84\x0c\x84\xc2\x1f\x12\xc2\x22\xf5\x61\x74\x56"
+ "\xbd\xea\x15\xfa\x76\xd7\x0c\x0a\xf6\x62\x66\xcf\x99\x6f\x67\x5b"
+ "\xe6\x08\xbf\x12\xb9\x37\x46\x61\xcf\x53\xf2\xae\x2d\xe3\x46\x1f"
+ "\x16\x94\x9e\x86\x2c\xa0\xe8\xa2\xf1\xeb\xb9\xa2\x60\x07\x03\xc5"
+ "\x70\x5e\xc3\x26\xd7\x44\xdb\x32\xcb\x00\x16\xc1\x0d\x67\x64\x16"
+ "\x95\xd6\x10\xdb\x13\x80\x82\x5b\x4c\x48\xa0\x74\x6d\xa8\xa1\x6d"
+ "\x36\xb3\x69\x83\x2f\xcb\x3d\x84\xc0\xd0\x43\x90\x84\xb9\xe8\xc3"
+ "\x23\x39\x0d\xea\xae\x6a\x66\x34\xb2\x7d\x57\xfa\x9f\x25\x78\x3d"
+ "\x03\xca\x4b\x9d\xad\xbf\x22\x0d\x5d\x89\xbb\xcc\x80\x8d\x98\xae"
+ "\x76\x05\x4f\xfe\x0c\x9e\x68\x83\x62\x3e\x64\x1b\x7c\x75\x4e\x95"
+ "\x92\xec\xd5\xe2\x0a\xdb\x3f\x2f\x52\x7a\x90\x6d\x58\xe8\x1b\x39"
+ "\x20\x33\x96\x0e\xbc\xee\xc1\xd1\xbf\x01\xe5\x06\xa6\x1f\x72\x01"
+ "\x00\x00"),
+
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+#undef T
+#undef GZH
+
+static void
+test_compress_zlib(void *)
+{
+ uint8_t obuf[1024];
+ for (const zlib_testvec *t = testvecs; t->text; t++) {
+ ssize_t n = compress(t->text, t->tlen, obuf, sizeof obuf, c_format_zlib);
+ tt_uint_op(n, ==, t->zlen);
+ tt_mem_op(obuf, ==, t->zlibbed, t->zlen);
+ }
+
+ end:;
+}
+
+static void
+test_decompress_zlib(void *)
+{
+ uint8_t obuf[1024];
+ for (const zlib_testvec *t = testvecs; t->text; t++) {
+ ssize_t n = decompress(t->zlibbed, t->zlen, obuf, sizeof obuf);
+ tt_uint_op(n, ==, t->tlen);
+ tt_mem_op(obuf, ==, t->text, t->tlen);
+ }
+
+ end:;
+}
+
+static void
+test_compress_gzip(void *)
+{
+ uint8_t obuf[1024];
+ for (const zlib_testvec *t = testvecs; t->text; t++) {
+ ssize_t n = compress(t->text, t->tlen, obuf, sizeof obuf, c_format_gzip);
+ tt_uint_op(n, ==, t->glen);
+ tt_mem_op(obuf, ==, t->gzipped, t->glen);
+ }
+
+ end:;
+}
+static void
+test_decompress_gzip(void *)
+{
+ uint8_t obuf[1024];
+ for (const zlib_testvec *t = testvecs; t->text; t++) {
+ ssize_t n = decompress(t->gzipped, t->glen, obuf, sizeof obuf);
+ tt_uint_op(n, ==, t->tlen);
+ tt_mem_op(obuf, ==, t->text, t->tlen);
+ }
+
+ end:;
+}
+
+#define T(name) \
+ { #name, test_##name, 0, 0, 0 }
+
+struct testcase_t zlib_tests[] = {
+ T(compress_zlib),
+ T(decompress_zlib),
+ T(compress_gzip),
+ T(decompress_gzip),
+ END_OF_TESTCASES
+};
diff --git a/src/test/unittest_zlib.cc b/src/test/unittest_zlib.cc
deleted file mode 100644
index 2d655b2..0000000
--- a/src/test/unittest_zlib.cc
+++ /dev/null
@@ -1,507 +0,0 @@
-/* Copyright 2012 SRI International
- * See LICENSE for other credits and copying information
- */
-
-#include "util.h"
-#include "unittest.h"
-
-#include "zlib.h"
-#include "zpack.h"
-
-// Smoke tests for zlib.
-//
-// CRC values generated using a standalone crc32 implementation of
-// unknown provenance, and then validated with the implementation
-// built into zlib.
-//
-// Compressed strings generated with Python's 'zlib' and 'gzip'
-// modules, which wrap zlib, so they only constitute a round-trip
-// test, not a proper test. Z_DEFAULT_COMPRESSION (6) used in all cases.
-//
-// If anyone knows a reliable source for "official" test vectors for
-// CRC polynomial 04C11DB7 and/or RFC 1950 through 1952, please let us
-// know.
-
-struct zlib_testvec
-{
- const uint8_t *text;
- size_t tlen;
- const uint8_t *zlibbed;
- size_t zlen;
- const uint8_t *gzipped;
- size_t glen;
- uint32_t crc32;
-};
-
-#define GZH(g) \
- "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff" g
-
-#define T(t, z, g, c) \
- { (const uint8_t *)t, sizeof t - 1, \
- (const uint8_t *)z, sizeof z - 1, \
- (const uint8_t *)GZH(g), sizeof GZH(g) - 1, \
- 0x##c }
-
-const zlib_testvec testvecs[] = {
- // the empty string
- T("",
- "\x78\x9c\x03\x00\x00\x00\x00\x01",
- "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00",
- 00000000),
-
- // 4-byte messages
- T("\x00\x00\x00\x00",
- "\x78\x9c\x63\x60\x60\x60\x00\x00\x00\x04\x00\x01",
- "\x63\x60\x60\x60\x00\x00\x1c\xdf\x44\x21\x04\x00\x00\x00",
- 2144df1c),
- T("\x11\x11\x11\x11",
- "\x78\x9c\x13\x14\x14\x14\x04\x00\x00\xae\x00\x45",
- "\x13\x14\x14\x14\x04\x00\x43\x25\x6c\xed\x04\x00\x00\x00",
- ed6c2543),
- T("\x22\x22\x22\x22",
- "\x78\x9c\x53\x52\x52\x52\x02\x00\x01\x58\x00\x89",
- "\x53\x52\x52\x52\x02\x00\xe3\x2d\x64\x62\x04\x00\x00\x00",
- 62642de3),
- T("\x33\x33\x33\x33",
- "\x78\x9c\x33\x36\x36\x36\x06\x00\x02\x02\x00\xcd",
- "\x33\x36\x36\x36\x06\x00\xbc\xd7\x4c\xae\x04\x00\x00\x00",
- ae4cd7bc),
- T("\x44\x44\x44\x44",
- "\x78\x9c\x73\x71\x71\x71\x01\x00\x02\xac\x01\x11",
- "\x73\x71\x71\x71\x01\x00\xe2\x3a\x05\xa7\x04\x00\x00\x00",
- a7053ae2),
- T("\x55\x55\x55\x55",
- "\x78\x9c\x0b\x0d\x0d\x0d\x05\x00\x03\x56\x01\x55",
- "\x0b\x0d\x0d\x0d\x05\x00\xbd\xc0\x2d\x6b\x04\x00\x00\x00",
- 6b2dc0bd),
- T("\x66\x66\x66\x66",
- "\x78\x9c\x4b\x4b\x4b\x4b\x03\x00\x04\x00\x01\x99",
- "\x4b\x4b\x4b\x4b\x03\x00\x1d\xc8\x25\xe4\x04\x00\x00\x00",
- e425c81d),
- T("\x77\x77\x77\x77",
- "\x78\x9c\x2b\x2f\x2f\x2f\x07\x00\x04\xaa\x01\xdd",
- "\x2b\x2f\x2f\x2f\x07\x00\x42\x32\x0d\x28\x04\x00\x00\x00",
- 280d3242),
- T("\x88\x88\x88\x88",
- "\x78\x9c\xeb\xe8\xe8\xe8\x00\x00\x05\x54\x02\x21",
- "\xeb\xe8\xe8\xe8\x00\x00\xa1\x12\xb6\xf6\x04\x00\x00\x00",
- f6b612a1),
- T("\x99\x99\x99\x99",
- "\x78\x9c\x9b\x39\x73\xe6\x4c\x00\x05\xfe\x02\x65",
- "\x9b\x39\x73\xe6\x4c\x00\xfe\xe8\x9e\x3a\x04\x00\x00\x00",
- 3a9ee8fe),
- T("\xaa\xaa\xaa\xaa",
- "\x78\x9c\x5b\xb5\x6a\xd5\x2a\x00\x06\xa8\x02\xa9",
- "\x5b\xb5\x6a\xd5\x2a\x00\x5e\xe0\x96\xb5\x04\x00\x00\x00",
- b596e05e),
- T("\xbb\xbb\xbb\xbb",
- "\x78\x9c\xdb\xbd\x7b\xf7\x6e\x00\x07\x52\x02\xed",
- "\xdb\xbd\x7b\xf7\x6e\x00\x01\x1a\xbe\x79\x04\x00\x00\x00",
- 79be1a01),
- T("\xcc\xcc\xcc\xcc",
- "\x78\x9c\x3b\x73\xe6\xcc\x19\x00\x07\xfc\x03\x31",
- "\x3b\x73\xe6\xcc\x19\x00\x5f\xf7\xf7\x70\x04\x00\x00\x00",
- 70f7f75f),
- T("\xdd\xdd\xdd\xdd",
- "\x78\x9c\xbb\x7b\xf7\xee\x5d\x00\x08\xa6\x03\x75",
- "\xbb\x7b\xf7\xee\x5d\x00\x00\x0d\xdf\xbc\x04\x00\x00\x00",
- bcdf0d00),
- T("\xee\xee\xee\xee",
- "\x78\x9c\x7b\xf7\xee\xdd\x3b\x00\x09\x50\x03\xb9",
- "\x7b\xf7\xee\xdd\x3b\x00\xa0\x05\xd7\x33\x04\x00\x00\x00",
- 33d705a0),
- T("\xff\xff\xff\xff",
- "\x78\x9c\xfb\xff\xff\xff\x7f\x00\x09\xfa\x03\xfd",
- "\xfb\xff\xff\xff\x7f\x00\xff\xff\xff\xff\x04\x00\x00\x00",
- ffffffff),
- T("\x40\x49\x0f\xdb",
- "\x78\x9c\x73\xf0\xe4\xbf\x0d\x00\x02\xd8\x01\x74",
- "\x73\xf0\xe4\xbf\x0d\x00\xfd\x26\x82\x53\x04\x00\x00\x00",
- 538226fd), // pi (IEEE single)
-
- // 8-byte messages
- T("\x00\x00\x00\x00\x00\x00\x00\x00",
- "\x78\x9c\x63\x60\x80\x00\x00\x00\x08\x00\x01",
- "\x63\x60\x80\x00\x00\x69\xdf\x22\x65\x08\x00\x00\x00",
- 6522df69),
- T("\x00\x00\x00\x00\xff\xff\xff\xff",
- "\x78\x9c\x63\x60\x60\x60\xf8\x0f\x04\x00\x09\xfe\x03\xfd",
- "\x63\x60\x60\x60\xf8\x0f\x04\x00\x8a\xff\x99\xbb\x08\x00\x00\x00",
- bb99ff8a),
- T("\xff\xff\xff\xff\x00\x00\x00\x00",
- "\x78\x9c\xfb\xff\xff\xff\x7f\x06\x20\x00\x00\x19\xee\x03\xfd",
- "\xfb\xff\xff\xff\x7f\x06\x20\x00\x00\xff\xff\xff\xff\x08\x00\x00\x00",
- ffffffff),
- T("\xff\xff\xff\xff\xff\xff\xff\xff",
- "\x78\x9c\xfb\xff\x1f\x02\x00\x23\xe4\x07\xf9",
- "\xfb\xff\x1f\x02\x00\x1c\xdf\x44\x21\x08\x00\x00\x00",
- 2144df1c),
- T("\x55\x55\x55\x55\x55\x55\x55\x55",
- "\x78\x9c\x0b\x0d\x85\x00\x00\x0b\xfc\x02\xa9",
- "\x0b\x0d\x85\x00\x00\x85\x22\xd0\xef\x08\x00\x00\x00",
- efd02285),
- T("\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
- "\x78\x9c\x5b\xb5\x0a\x02\x00\x17\xf0\x05\x51",
- "\x5b\xb5\x0a\x02\x00\xf0\x22\xb6\xab\x08\x00\x00\x00",
- abb622f0),
- T("\x40\x09\x21\xfb\x54\x44\x2d\x18",
- "\x78\x9c\x73\xe0\x54\xfc\x1d\xe2\xa2\x2b\x01\x00\x0a\x82\x02\x43",
- "\x73\xe0\x54\xfc\x1d\xe2\xa2\x2b\x01\x00\xd8\x90\x89\x2a\x08\x00\x00\x00",
- 2a8990d8), // pi (IEEE double)
-
- // 32-byte messages: all possible bytes occur once
- T("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
- "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
- "\x78\x9c\x63\x60\x64\x62\x66\x61\x65\x63\xe7\xe0\xe4\xe2\xe6\xe1"
- "\xe5\xe3\x17\x10\x14\x12\x16\x11\x15\x13\x97\x90\x94\x92\x96\x91"
- "\x95\x93\x07\x00\x15\x70\x01\xf1",
- "\x63\x60\x64\x62\x66\x61\x65\x63\xe7\xe0\xe4\xe2\xe6\xe1\xe5\xe3"
- "\x17\x10\x14\x12\x16\x11\x15\x13\x97\x90\x94\x92\x96\x91\x95\x93"
- "\x07\x00\x8a\x7e\x26\x91\x20\x00\x00\x00",
- 91267e8a),
- T("\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
- "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f",
- "\x78\x9c\x53\x50\x54\x52\x56\x51\x55\x53\xd7\xd0\xd4\xd2\xd6\xd1"
- "\xd5\xd3\x37\x30\x34\x32\x36\x31\x35\x33\xb7\xb0\xb4\xb2\xb6\xb1"
- "\xb5\xb3\x07\x00\x57\x70\x05\xf1",
- "\x53\x50\x54\x52\x56\x51\x55\x53\xd7\xd0\xd4\xd2\xd6\xd1\xd5\xd3"
- "\x37\x30\x34\x32\x36\x31\x35\x33\xb7\xb0\xb4\xb2\xb6\xb1\xb5\xb3"
- "\x07\x00\xe3\x06\xa6\xf6\x20\x00\x00\x00",
- f6a606e3),
- T("\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
- "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f",
- "\x78\x9c\x73\x70\x74\x72\x76\x71\x75\x73\xf7\xf0\xf4\xf2\xf6\xf1"
- "\xf5\xf3\x0f\x08\x0c\x0a\x0e\x09\x0d\x0b\x8f\x88\x8c\x8a\x8e\x89"
- "\x8d\x8b\x07\x00\x99\x70\x09\xf1",
- "\x73\x70\x74\x72\x76\x71\x75\x73\xf7\xf0\xf4\xf2\xf6\xf1\xf5\xf3"
- "\x0f\x08\x0c\x0a\x0e\x09\x0d\x0b\x8f\x88\x8c\x8a\x8e\x89\x8d\x8b"
- "\x07\x00\x58\x8e\x26\x5e\x20\x00\x00\x00",
- 5e268e58),
- T("\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
- "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f",
- "\x78\x9c\x4b\x48\x4c\x4a\x4e\x49\x4d\x4b\xcf\xc8\xcc\xca\xce\xc9"
- "\xcd\xcb\x2f\x28\x2c\x2a\x2e\x29\x2d\x2b\xaf\xa8\xac\xaa\xae\xa9"
- "\xad\xab\x07\x00\xdb\x70\x0d\xf1",
- "\x4b\x48\x4c\x4a\x4e\x49\x4d\x4b\xcf\xc8\xcc\xca\xce\xc9\xcd\xcb"
- "\x2f\x28\x2c\x2a\x2e\x29\x2d\x2b\xaf\xa8\xac\xaa\xae\xa9\xad\xab"
- "\x07\x00\x31\xf6\xa6\x39\x20\x00\x00\x00",
- 39a6f631),
- T("\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
- "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f",
- "\x78\x9c\x01\x20\x00\xdf\xff\x80\x81\x82\x83\x84\x85\x86\x87\x88"
- "\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98"
- "\x99\x9a\x9b\x9c\x9d\x9e\x9f\x1d\x7f\x11\xf1",
- "\x01\x20\x00\xdf\xff\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a"
- "\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a"
- "\x9b\x9c\x9d\x9e\x9f\x6f\x99\x56\xd4\x20\x00\x00\x00",
- d456996f),
- T("\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
- "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf",
- "\x78\x9c\x01\x20\x00\xdf\xff\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
- "\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
- "\xb9\xba\xbb\xbc\xbd\xbe\xbf\x5f\x7f\x15\xf1",
- "\x01\x20\x00\xdf\xff\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa"
- "\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba"
- "\xbb\xbc\xbd\xbe\xbf\x06\xe1\xd6\xb3\x20\x00\x00\x00",
- b3d6e106),
- T("\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
- "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf",
- "\x78\x9c\x01\x20\x00\xdf\xff\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8"
- "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"
- "\xd9\xda\xdb\xdc\xdd\xde\xdf\xa1\x7f\x19\xf1",
- "\x01\x20\x00\xdf\xff\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca"
- "\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda"
- "\xdb\xdc\xdd\xde\xdf\xbd\x69\x56\x1b\x20\x00\x00\x00",
- 1b5669bd),
- T("\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
- "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
- "\x78\x9c\x01\x20\x00\xdf\xff\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"
- "\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8"
- "\xf9\xfa\xfb\xfc\xfd\xfe\xff\xe3\x7f\x1d\xf1",
- "\x01\x20\x00\xdf\xff\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea"
- "\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa"
- "\xfb\xfc\xfd\xfe\xff\xd4\x11\xd6\x7c\x20\x00\x00\x00",
- 7cd611d4),
-
- // 26- to 40-letter pangrams from Wikipedia, all nonletters removed,
- // all lowercase
- T("cwmfjordbankglyphsvextquiz",
- "\x78\x9c\x4b\x2e\xcf\x4d\xcb\xca\x2f\x4a\x49\x4a\xcc\xcb\x4e\xcf"
- "\xa9\x2c\xc8\x28\x2e\x4b\xad\x28\x29\x2c\xcd\xac\x02\x00\x93\xd9"
- "\x0b\x20",
- "\x4b\x2e\xcf\x4d\xcb\xca\x2f\x4a\x49\x4a\xcc\xcb\x4e\xcf\xa9\x2c"
- "\xc8\x28\x2e\x4b\xad\x28\x29\x2c\xcd\xac\x02\x00\x10\x89\x30\x81"
- "\x1a\x00\x00\x00",
- 81308910),
- T("nymphsblitzquickvexdwarfjog",
- "\x78\x9c\xcb\xab\xcc\x2d\xc8\x28\x4e\xca\xc9\x2c\xa9\x2a\x2c\xcd"
- "\x4c\xce\x2e\x4b\xad\x48\x29\x4f\x2c\x4a\xcb\xca\x4f\x07\x00\xa2"
- "\xd1\x0b\x89",
- "\xcb\xab\xcc\x2d\xc8\x28\x4e\xca\xc9\x2c\xa9\x2a\x2c\xcd\x4c\xce"
- "\x2e\x4b\xad\x48\x29\x4f\x2c\x4a\xcb\xca\x4f\x07\x00\xae\x01\xb2"
- "\xc9\x1b\x00\x00\x00",
- c9b201ae),
- T("brickquizwhangsjumpyveldtfox",
- "\x78\x9c\x4b\x2a\xca\x4c\xce\x2e\x2c\xcd\xac\x2a\xcf\x48\xcc\x4b"
- "\x2f\xce\x2a\xcd\x2d\xa8\x2c\x4b\xcd\x49\x29\x49\xcb\xaf\x00\x00"
- "\xac\xcf\x0b\xfe",
- "\x4b\x2a\xca\x4c\xce\x2e\x2c\xcd\xac\x2a\xcf\x48\xcc\x4b\x2f\xce"
- "\x2a\xcd\x2d\xa8\x2c\x4b\xcd\x49\x29\x49\xcb\xaf\x00\x00\xeb\x36"
- "\x78\xc1\x1c\x00\x00\x00",
- c17836eb),
- T("vexednymphsgoforquickwaltzjob",
- "\x78\x9c\x2b\x4b\xad\x48\x4d\xc9\xab\xcc\x2d\xc8\x28\x4e\xcf\x4f"
- "\xcb\x2f\x2a\x2c\xcd\x4c\xce\x2e\x4f\xcc\x29\xa9\xca\xca\x4f\x02"
- "\x00\xba\x43\x0c\x63",
- "\x2b\x4b\xad\x48\x4d\xc9\xab\xcc\x2d\xc8\x28\x4e\xcf\x4f\xcb\x2f"
- "\x2a\x2c\xcd\x4c\xce\x2e\x4f\xcc\x29\xa9\xca\xca\x4f\x02\x00\x60"
- "\x23\x8c\xea\x1d\x00\x00\x00",
- ea8c2360),
- T("bothfickledwarvesjinxmypigquiz",
- "\x78\x9c\x4b\xca\x2f\xc9\x48\xcb\x4c\xce\xce\x49\x4d\x29\x4f\x2c"
- "\x2a\x4b\x2d\xce\xca\xcc\xab\xc8\xad\x2c\xc8\x4c\x2f\x2c\xcd\xac"
- "\x02\x00\xc2\xd3\x0c\xc0",
- "\x4b\xca\x2f\xc9\x48\xcb\x4c\xce\xce\x49\x4d\x29\x4f\x2c\x2a\x4b"
- "\x2d\xce\xca\xcc\xab\xc8\xad\x2c\xc8\x4c\x2f\x2c\xcd\xac\x02\x00"
- "\x5f\x5f\x7c\x3c\x1e\x00\x00\x00",
- 3c7c5f5f),
- T("ficklejinxbogdwarvesspymathquiz",
- "\x78\x9c\x4b\xcb\x4c\xce\xce\x49\xcd\xca\xcc\xab\x48\xca\x4f\x4f"
- "\x29\x4f\x2c\x2a\x4b\x2d\x2e\x2e\xa8\xcc\x4d\x2c\xc9\x28\x2c\xcd"
- "\xac\x02\x00\xcf\x8d\x0d\x2b",
- "\x4b\xcb\x4c\xce\xce\x49\xcd\xca\xcc\xab\x48\xca\x4f\x4f\x29\x4f"
- "\x2c\x2a\x4b\x2d\x2e\x2e\xa8\xcc\x4d\x2c\xc9\x28\x2c\xcd\xac\x02"
- "\x00\x07\x28\x86\x75\x1f\x00\x00\x00",
- 75862807),
- T("averybadquackmightjinxzippyfowls",
- "\x78\x9c\x4b\x2c\x4b\x2d\xaa\x4c\x4a\x4c\x29\x2c\x4d\x4c\xce\xce"
- "\xcd\x4c\xcf\x28\xc9\xca\xcc\xab\xa8\xca\x2c\x28\xa8\x4c\xcb\x2f"
- "\xcf\x29\x06\x00\xdd\xb8\x0d\x9d",
- "\x4b\x2c\x4b\x2d\xaa\x4c\x4a\x4c\x29\x2c\x4d\x4c\xce\xce\xcd\x4c"
- "\xcf\x28\xc9\xca\xcc\xab\xa8\xca\x2c\x28\xa8\x4c\xcb\x2f\xcf\x29"
- "\x06\x00\xaa\x73\x33\x56\x20\x00\x00\x00",
- 563373aa),
- T("aquickbrownfoxjumpsoverthelazydog",
- "\x78\x9c\x4b\x2c\x2c\xcd\x4c\xce\x4e\x2a\xca\x2f\xcf\x4b\xcb\xaf"
- "\xc8\x2a\xcd\x2d\x28\xce\x2f\x4b\x2d\x2a\xc9\x48\xcd\x49\xac\xaa"
- "\x4c\xc9\x4f\x07\x00\xef\x3d\x0e\x1a",
- "\x4b\x2c\x2c\xcd\x4c\xce\x4e\x2a\xca\x2f\xcf\x4b\xcb\xaf\xc8\x2a"
- "\xcd\x2d\x28\xce\x2f\x4b\x2d\x2a\xc9\x48\xcd\x49\xac\xaa\x4c\xc9"
- "\x4f\x07\x00\x00\x66\xdf\x56\x21\x00\x00\x00",
- 56df6600),
- T("quizzicaltwinsprovedmyhijackbugfix",
- "\x78\x9c\x2b\x2c\xcd\xac\xaa\xca\x4c\x4e\xcc\x29\x29\xcf\xcc\x2b"
- "\x2e\x28\xca\x2f\x4b\x4d\xc9\xad\xcc\xc8\xcc\x4a\x4c\xce\x4e\x2a"
- "\x4d\x4f\xcb\xac\x00\x00\xff\xe8\x0e\x77",
- "\x2b\x2c\xcd\xac\xaa\xca\x4c\x4e\xcc\x29\x29\xcf\xcc\x2b\x2e\x28"
- "\xca\x2f\x4b\x4d\xc9\xad\xcc\xc8\xcc\x4a\x4c\xce\x4e\x2a\x4d\x4f"
- "\xcb\xac\x00\x00\x01\x07\x14\xb7\x22\x00\x00\x00",
- b7140701),
- T("whenzombiesarrivequicklyfaxjudgepat",
- "\x78\x9c\x2b\xcf\x48\xcd\xab\xca\xcf\x4d\xca\x4c\x2d\x4e\x2c\x2a"
- "\xca\x2c\x4b\x2d\x2c\xcd\x4c\xce\xce\xa9\x4c\x4b\xac\xc8\x2a\x4d"
- "\x49\x4f\x2d\x48\x2c\x01\x00\x0b\x5d\x0e\xca",
- "\x2b\xcf\x48\xcd\xab\xca\xcf\x4d\xca\x4c\x2d\x4e\x2c\x2a\xca\x2c"
- "\x4b\x2d\x2c\xcd\x4c\xce\xce\xa9\x4c\x4b\xac\xc8\x2a\x4d\x49\x4f"
- "\x2d\x48\x2c\x01\x00\xae\xef\x98\xc3\x23\x00\x00\x00",
- c398efae),
- T("heavyboxesperformquickwaltzesandjigs",
- "\x78\x9c\xcb\x48\x4d\x2c\xab\x4c\xca\xaf\x48\x2d\x2e\x48\x2d\x4a"
- "\xcb\x2f\xca\x2d\x2c\xcd\x4c\xce\x2e\x4f\xcc\x29\xa9\x4a\x2d\x4e"
- "\xcc\x4b\xc9\xca\x4c\x2f\x06\x00\x1a\xc0\x0f\x41",
- "\xcb\x48\x4d\x2c\xab\x4c\xca\xaf\x48\x2d\x2e\x48\x2d\x4a\xcb\x2f"
- "\xca\x2d\x2c\xcd\x4c\xce\x2e\x4f\xcc\x29\xa9\x4a\x2d\x4e\xcc\x4b"
- "\xc9\xca\x4c\x2f\x06\x00\x71\xc5\x60\xbb\x24\x00\x00\x00",
- bb60c571),
- T("fakebugsputinwaxjonquilsdrivehimcrazy",
- "\x78\x9c\x4b\x4b\xcc\x4e\x4d\x2a\x4d\x2f\x2e\x28\x2d\xc9\xcc\x2b"
- "\x4f\xac\xc8\xca\xcf\x2b\x2c\xcd\xcc\x29\x4e\x29\xca\x2c\x4b\xcd"
- "\xc8\xcc\x4d\x2e\x4a\xac\xaa\x04\x00\x29\x9e\x0f\xbf",
- "\x4b\x4b\xcc\x4e\x4d\x2a\x4d\x2f\x2e\x28\x2d\xc9\xcc\x2b\x4f\xac"
- "\xc8\xca\xcf\x2b\x2c\xcd\xcc\x29\x4e\x29\xca\x2c\x4b\xcd\xc8\xcc"
- "\x4d\x2e\x4a\xac\xaa\x04\x00\xf0\x24\xc5\xa1\x25\x00\x00\x00",
- a1c524f0),
- T("wovensilkpyjamasexchangedforbluequartz",
- "\x78\x9c\x2b\xcf\x2f\x4b\xcd\x2b\xce\xcc\xc9\x2e\xa8\xcc\x4a\xcc"
- "\x4d\x2c\x4e\xad\x48\xce\x48\xcc\x4b\x4f\x4d\x49\xcb\x2f\x4a\xca"
- "\x29\x4d\x2d\x2c\x4d\x2c\x2a\xa9\x02\x00\x39\xef\x10\x15",
- "\x2b\xcf\x2f\x4b\xcd\x2b\xce\xcc\xc9\x2e\xa8\xcc\x4a\xcc\x4d\x2c"
- "\x4e\xad\x48\xce\x48\xcc\x4b\x4f\x4d\x49\xcb\x2f\x4a\xca\x29\x4d"
- "\x2d\x2c\x4d\x2c\x2a\xa9\x02\x00\x4e\x06\x7f\x9a\x26\x00\x00\x00",
- 9a7f064e),
- T("thequickonyxgoblinjumpsoverthelazydwarf",
- "\x78\x9c\x2b\xc9\x48\x2d\x2c\xcd\x4c\xce\xce\xcf\xab\xac\x48\xcf"
- "\x4f\xca\xc9\xcc\xcb\x2a\xcd\x2d\x28\xce\x2f\x4b\x2d\x2a\xc9\x48"
- "\xcd\x49\xac\xaa\x4c\x29\x4f\x2c\x4a\x03\x00\x4d\x76\x10\xa8",
- "\x2b\xc9\x48\x2d\x2c\xcd\x4c\xce\xce\xcf\xab\xac\x48\xcf\x4f\xca"
- "\xc9\xcc\xcb\x2a\xcd\x2d\x28\xce\x2f\x4b\x2d\x2a\xc9\x48\xcd\x49"
- "\xac\xaa\x4c\x29\x4f\x2c\x4a\x03\x00\x12\x87\x47\x3b\x27\x00\x00\x00",
- 3b478712),
- T("amazinglyfewdiscothequesprovidejukeboxes",
- "\x78\x9c\x4b\xcc\x4d\xac\xca\xcc\x4b\xcf\xa9\x4c\x4b\x2d\x4f\xc9"
- "\x2c\x4e\xce\x2f\xc9\x48\x2d\x2c\x4d\x2d\x2e\x28\xca\x2f\xcb\x4c"
- "\x49\xcd\x2a\xcd\x4e\x4d\xca\xaf\x48\x2d\x06\x00\x59\xbe\x10\xe9",
- "\x4b\xcc\x4d\xac\xca\xcc\x4b\xcf\xa9\x4c\x4b\x2d\x4f\xc9\x2c\x4e"
- "\xce\x2f\xc9\x48\x2d\x2c\x4d\x2d\x2e\x28\xca\x2f\xcb\x4c\x49\xcd"
- "\x2a\xcd\x4e\x4d\xca\xaf\x48\x2d\x06\x00\xa3\xe4\xdd\x7d\x28\x00\x00\x00",
- 7ddde4a3),
-
- // self-describing pangram by Lee Sallows (SciAm, 1984)
- T("This Pangram contains four as, one b, two cs, one d, thirty es, "
- "six fs, five gs, seven hs, eleven is, one j, one k, two ls, two ms, "
- "eighteen ns, fifteen os, two ps, one q, five rs, twenty-seven ss, "
- "eighteen ts, two us, seven vs, eight ws, two xs, three ys, & one z.",
- "\x78\x9c\x4d\x4e\xcd\x1a\xc2\x20\x0c\x7b\x95\x9c\x3c\x4d\x9f\xc5"
- "\x83\x2f\x80\xb3\x8c\xea\x56\x14\xd8\x0f\x3e\xbd\x0c\xaa\x9f\xa7"
- "\xa4\x69\x92\xf6\xe2\x38\xe2\x6c\x64\x08\x66\x42\xef\x25\x19\x96"
- "\x08\xeb\xe7\x00\x13\x3b\x78\x21\x5c\x3b\xa4\xd5\xa3\xd7\xf1\x56"
- "\x46\xc7\x21\x65\x50\x51\x22\x6f\xb0\x05\x2d\x2f\x84\x61\x17\x68"
- "\x21\x81\x2b\x8c\xc6\x4a\x59\x73\xf7\x06\x8f\xd6\x36\xc6\x86\xd3"
- "\x6e\xe4\xc1\x25\x2a\x56\xa9\x45\xb6\x72\xaf\x86\xa7\xc6\x5f\x7a"
- "\x23\x54\x9d\x24\xe5\x63\x3b\x15\xff\x1b\x92\xa6\xe6\xdf\x27\xcb"
- "\x77\x8d\x55\x77\xdb\x8e\x2e\x10\x21\x17\x76\xa8\xed\xef\xd3\x07"
- "\xaa\x0c\x59\x5f",
- "\x4d\x4e\xcd\x1a\xc2\x20\x0c\x7b\x95\x9c\x3c\x4d\x9f\xc5\x83\x2f"
- "\x80\xb3\x8c\xea\x56\x14\xd8\x0f\x3e\xbd\x0c\xaa\x9f\xa7\xa4\x69"
- "\x92\xf6\xe2\x38\xe2\x6c\x64\x08\x66\x42\xef\x25\x19\x96\x08\xeb"
- "\xe7\x00\x13\x3b\x78\x21\x5c\x3b\xa4\xd5\xa3\xd7\xf1\x56\x46\xc7"
- "\x21\x65\x50\x51\x22\x6f\xb0\x05\x2d\x2f\x84\x61\x17\x68\x21\x81"
- "\x2b\x8c\xc6\x4a\x59\x73\xf7\x06\x8f\xd6\x36\xc6\x86\xd3\x6e\xe4"
- "\xc1\x25\x2a\x56\xa9\x45\xb6\x72\xaf\x86\xa7\xc6\x5f\x7a\x23\x54"
- "\x9d\x24\xe5\x63\x3b\x15\xff\x1b\x92\xa6\xe6\xdf\x27\xcb\x77\x8d"
- "\x55\x77\xdb\x8e\x2e\x10\x21\x17\x76\xa8\xed\xef\xd3\x07\x11\xb4"
- "\xb5\x3a\x09\x01\x00\x00",
- 3ab5b411),
-
- // "Lion-Eating Poet in the Stone Den" by Chao Yuen Ren,
- // Simplified Chinese text in UTF-8
- T("\xe3\x80\x8a\xe6\x96\xbd\xe6\xb0\x8f\xe9\xa3\x9f\xe7\x8b\xae\xe5\x8f"
- "\xb2\xe3\x80\x8b \xe7\x9f\xb3\xe5\xae\xa4\xe8\xaf\x97\xe5\xa3\xab\xe6"
- "\x96\xbd\xe6\xb0\x8f\xef\xbc\x8c\xe5\x97\x9c\xe7\x8b\xae\xef\xbc\x8c"
- "\xe8\xaa\x93\xe9\xa3\x9f\xe5\x8d\x81\xe7\x8b\xae\xe3\x80\x82 \xe6\xb0"
- "\x8f\xe6\x97\xb6\xe6\x97\xb6\xe9\x80\x82\xe5\xb8\x82\xe8\xa7\x86\xe7"
- "\x8b\xae\xe3\x80\x82 \xe5\x8d\x81\xe6\x97\xb6\xef\xbc\x8c\xe9\x80\x82"
- "\xe5\x8d\x81\xe7\x8b\xae\xe9\x80\x82\xe5\xb8\x82\xe3\x80\x82 \xe6\x98"
- "\xaf\xe6\x97\xb6\xef\xbc\x8c\xe9\x80\x82\xe6\x96\xbd\xe6\xb0\x8f\xe9"
- "\x80\x82\xe5\xb8\x82\xe3\x80\x82 \xe6\xb0\x8f\xe8\xa7\x86\xe6\x98\xaf"
- "\xe5\x8d\x81\xe7\x8b\xae\xef\xbc\x8c\xe6\x81\x83\xe7\x9f\xa2\xe5\x8a"
- "\xbf\xef\xbc\x8c\xe4\xbd\xbf\xe6\x98\xaf\xe5\x8d\x81\xe7\x8b\xae\xe9"
- "\x80\x9d\xe4\xb8\x96\xe3\x80\x82 \xe6\xb0\x8f\xe6\x8b\xbe\xe6\x98\xaf"
- "\xe5\x8d\x81\xe7\x8b\xae\xe5\xb0\xb8\xef\xbc\x8c\xe9\x80\x82\xe7\x9f"
- "\xb3\xe5\xae\xa4\xe3\x80\x82 \xe7\x9f\xb3\xe5\xae\xa4\xe6\xb9\xbf\xef"
- "\xbc\x8c\xe6\xb0\x8f\xe4\xbd\xbf\xe4\xbe\x8d\xe6\x8b\xad\xe7\x9f\xb3"
- "\xe5\xae\xa4\xe3\x80\x82 \xe7\x9f\xb3\xe5\xae\xa4\xe6\x8b\xad\xef\xbc"
- "\x8c\xe6\xb0\x8f\xe5\xa7\x8b\xe8\xaf\x95\xe9\xa3\x9f\xe6\x98\xaf\xe5"
- "\x8d\x81\xe7\x8b\xae\xe3\x80\x82 \xe9\xa3\x9f\xe6\x97\xb6\xef\xbc\x8c"
- "\xe5\xa7\x8b\xe8\xaf\x86\xe6\x98\xaf\xe5\x8d\x81\xe7\x8b\xae\xe5\xb0"
- "\xb8\xef\xbc\x8c\xe5\xae\x9e\xe5\x8d\x81\xe7\x9f\xb3\xe7\x8b\xae\xe5"
- "\xb0\xb8\xe3\x80\x82 \xe8\xaf\x95\xe9\x87\x8a\xe6\x98\xaf\xe4\xba\x8b"
- "\xe3\x80\x82",
- "\x78\x9c\x65\x8f\xdd\x0a\x82\x40\x10\x46\x5f\xc5\x47\x5d\x0d\x0c"
- "\xdc\xc4\x8b\x48\xbb\xa8\x84\x0c\x84\xc2\x1f\x12\xc2\x22\xf5\x61"
- "\x74\x56\xbd\xea\x15\xfa\x76\xd7\x0c\x0a\xf6\x62\x66\xcf\x99\x6f"
- "\x67\x5b\xe6\x08\xbf\x12\xb9\x37\x46\x61\xcf\x53\xf2\xae\x2d\xe3"
- "\x46\x1f\x16\x94\x9e\x86\x2c\xa0\xe8\xa2\xf1\xeb\xb9\xa2\x60\x07"
- "\x03\xc5\x70\x5e\xc3\x26\xd7\x44\xdb\x32\xcb\x00\x16\xc1\x0d\x67"
- "\x64\x16\x95\xd6\x10\xdb\x13\x80\x82\x5b\x4c\x48\xa0\x74\x6d\xa8"
- "\xa1\x6d\x36\xb3\x69\x83\x2f\xcb\x3d\x84\xc0\xd0\x43\x90\x84\xb9"
- "\xe8\xc3\x23\x39\x0d\xea\xae\x6a\x66\x34\xb2\x7d\x57\xfa\x9f\x25"
- "\x78\x3d\x03\xca\x4b\x9d\xad\xbf\x22\x0d\x5d\x89\xbb\xcc\x80\x8d"
- "\x98\xae\x76\x05\x4f\xfe\x0c\x9e\x68\x83\x62\x3e\x64\x1b\x7c\x75"
- "\x4e\x95\x92\xec\xd5\xe2\x0a\xdb\x3f\x2f\x52\x7a\x90\x6d\x58\xe8"
- "\x1b\x39\x20\x33\x96\x0e\xbc\xee\xc1\xd1\xbf\x01\xae\x11\xff\x53",
- "\x65\x8f\xdd\x0a\x82\x40\x10\x46\x5f\xc5\x47\x5d\x0d\x0c\xdc\xc4"
- "\x8b\x48\xbb\xa8\x84\x0c\x84\xc2\x1f\x12\xc2\x22\xf5\x61\x74\x56"
- "\xbd\xea\x15\xfa\x76\xd7\x0c\x0a\xf6\x62\x66\xcf\x99\x6f\x67\x5b"
- "\xe6\x08\xbf\x12\xb9\x37\x46\x61\xcf\x53\xf2\xae\x2d\xe3\x46\x1f"
- "\x16\x94\x9e\x86\x2c\xa0\xe8\xa2\xf1\xeb\xb9\xa2\x60\x07\x03\xc5"
- "\x70\x5e\xc3\x26\xd7\x44\xdb\x32\xcb\x00\x16\xc1\x0d\x67\x64\x16"
- "\x95\xd6\x10\xdb\x13\x80\x82\x5b\x4c\x48\xa0\x74\x6d\xa8\xa1\x6d"
- "\x36\xb3\x69\x83\x2f\xcb\x3d\x84\xc0\xd0\x43\x90\x84\xb9\xe8\xc3"
- "\x23\x39\x0d\xea\xae\x6a\x66\x34\xb2\x7d\x57\xfa\x9f\x25\x78\x3d"
- "\x03\xca\x4b\x9d\xad\xbf\x22\x0d\x5d\x89\xbb\xcc\x80\x8d\x98\xae"
- "\x76\x05\x4f\xfe\x0c\x9e\x68\x83\x62\x3e\x64\x1b\x7c\x75\x4e\x95"
- "\x92\xec\xd5\xe2\x0a\xdb\x3f\x2f\x52\x7a\x90\x6d\x58\xe8\x1b\x39"
- "\x20\x33\x96\x0e\xbc\xee\xc1\xd1\xbf\x01\xe5\x06\xa6\x1f\x72\x01"
- "\x00\x00",
- 1fa606e5),
-
- { 0, 0, 0, 0, 0, 0, 0 }
-};
-
-#undef T
-#undef GZH
-
-static void
-test_zlib_crc32(void *)
-{
- for (const zlib_testvec *t = testvecs; t->text; t++) {
- uint32_t h = generate_crc32c(t->text, t->tlen);
- tt_assert_op_type(h, ==, t->crc32, unsigned int, "%08x");
- }
-
- end:;
-}
-
-static void
-test_zlib_compress_zlib(void *)
-{
- uint8_t obuf[1024];
- for (const zlib_testvec *t = testvecs; t->text; t++) {
- ssize_t n = def(t->text, t->tlen, obuf, sizeof obuf, 6);
- tt_uint_op(n, ==, t->zlen);
- tt_mem_op(obuf, ==, t->zlibbed, t->zlen);
- }
-
- end:;
-}
-
-static void
-test_zlib_decompress_zlib(void *)
-{
- uint8_t obuf[1024];
- for (const zlib_testvec *t = testvecs; t->text; t++) {
- ssize_t n = inf(t->zlibbed, t->zlen, obuf, sizeof obuf);
- tt_uint_op(n, ==, t->tlen);
- tt_mem_op(obuf, ==, t->text, t->tlen);
- }
-
- end:;
-}
-
-static void
-test_zlib_compress_gzip(void *)
-{
- uint8_t obuf[1024];
- for (const zlib_testvec *t = testvecs; t->text; t++) {
- ssize_t n = gzDeflate(t->text, t->tlen, obuf, sizeof obuf, 0);
- tt_uint_op(n, ==, t->glen);
- tt_mem_op(obuf, ==, t->gzipped, t->glen);
- }
-
- end:;
-}
-static void
-test_zlib_decompress_gzip(void *)
-{
- uint8_t obuf[1024];
- for (const zlib_testvec *t = testvecs; t->text; t++) {
- ssize_t n = gzInflate(t->gzipped, t->glen, obuf, sizeof obuf);
- tt_uint_op(n, ==, t->tlen);
- tt_mem_op(obuf, ==, t->text, t->tlen);
- }
-
- end:;
-}
-
-#define T(name) \
- { #name, test_zlib_##name, 0, 0, 0 }
-
-struct testcase_t zlib_tests[] = {
- T(crc32),
- T(compress_zlib),
- T(decompress_zlib),
- T(compress_gzip),
- T(decompress_gzip),
- END_OF_TESTCASES
-};
diff --git a/src/zpack.cc b/src/zpack.cc
deleted file mode 100644
index 3ffd065..0000000
--- a/src/zpack.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-/* Copyright 2011, 2012 SRI International
- * See LICENSE for other credits and copying information
- */
-#include "util.h"
-#include "zpack.h"
-#include "zlib.h"
-
-#include <limits>
-
-// zlib doesn't believe in size_t. When size_t is bigger than uInt, we
-// theoretically could break operations up into uInt-sized chunks to
-// support the full range of size_t, but I doubt we will ever need to
-// compress, decompress, or crc32 more than 2^32 bytes in one
-// operation, so I'm not bothering. -- zw, 2012
-//
-// The indirection through ZLIB_UINT_MAX makes some versions of gcc
-// not produce a 'comparison is always (true/false)' warning.
-const size_t ZLIB_UINT_MAX = std::numeric_limits<uInt>::max();
-const size_t ZLIB_CEILING = (SIZE_T_CEILING > ZLIB_UINT_MAX
- ? ZLIB_UINT_MAX : SIZE_T_CEILING);
-
-// Compress from 'source' to 'dest', producing 'zlib' (RFC 1950) format,
-// with compression level 'level'.
-ssize_t
-def(const uint8_t *source, size_t slen, uint8_t *dest, size_t dlen, int level)
-{
- if (slen > ZLIB_CEILING || dlen > ZLIB_CEILING)
- return -1;
-
- z_stream strm;
- memset(&strm, 0, sizeof strm);
- int ret = deflateInit(&strm, level);
- if (ret != Z_OK) {
- log_warn("compression failure (initialization): %s", strm.msg);
- return -1;
- }
-
- strm.next_in = const_cast<Bytef*>(source);
- strm.avail_in = slen;
- strm.next_out = dest;
- strm.avail_out = dlen;
-
- ret = deflate(&strm, Z_FINISH);
- if (ret != Z_STREAM_END) {
- log_warn("compression failure: %s", strm.msg);
- deflateEnd(&strm);
- return -1;
- }
-
- deflateEnd(&strm);
- return strm.total_out;
-}
-
-// Decompress 'zlib'-format data from 'source' to 'dest'.
-ssize_t
-inf(const uint8_t *source, size_t slen, uint8_t *dest, size_t dlen)
-{
- if (slen > ZLIB_CEILING || dlen > ZLIB_CEILING)
- return -1;
-
- /* allocate inflate state */
- z_stream strm;
- memset(&strm, 0, sizeof strm);
- int ret = inflateInit(&strm);
- if (ret != Z_OK) {
- log_warn("decompression failure (initialization): %s", strm.msg);
- return -1;
- }
-
- strm.next_in = const_cast<Bytef*>(source);
- strm.avail_in = slen;
- strm.next_out = dest;
- strm.avail_out = dlen;
-
- ret = inflate(&strm, Z_FINISH);
- if (ret != Z_STREAM_END) {
- log_warn("decompression failure: %s", strm.msg);
- inflateEnd(&strm);
- return -1;
- }
-
- inflateEnd(&strm);
- return strm.total_out;
-}
-
-ssize_t
-gzInflate(const uint8_t *source, size_t slen, uint8_t *dest, size_t dlen)
-{
- if (slen > ZLIB_CEILING || dlen > ZLIB_CEILING)
- return -1;
-
- z_stream strm;
- memset(&strm, 0, sizeof strm);
- int ret = inflateInit2(&strm, MAX_WBITS|16); // 16 = decode gzip (only)
-
- if (ret != Z_OK) {
- log_warn("decompression failure (initialization): %s", strm.msg);
- return -1;
- }
-
- strm.next_in = const_cast<Bytef*>(source);
- strm.avail_in = slen;
- strm.next_out = dest;
- strm.avail_out = dlen;
-
- ret = inflate(&strm, Z_FINISH);
- if (ret != Z_STREAM_END) {
- log_warn("decompression failure: %s", strm.msg);
- inflateEnd(&strm);
- return -1;
- }
-
- inflateEnd(&strm);
- return strm.total_out;
-}
-
-ssize_t
-gzDeflate(const uint8_t *source, size_t slen, uint8_t *dest, size_t dlen,
- time_t mtime)
-{
- if (slen > ZLIB_CEILING || dlen > ZLIB_CEILING)
- return -1;
-
- z_stream strm;
- memset(&strm, 0, sizeof strm);
- int ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
- MAX_WBITS|16, // compress as gzip
- 8, Z_DEFAULT_STRATEGY);
- if (ret != Z_OK) {
- log_warn("compression failure (initialization): %s", strm.msg);
- return -1;
- }
-
- gz_header gzh;
- memset(&gzh, 0, sizeof gzh);
- gzh.time = mtime;
- gzh.os = 0xFF; // "unknown"
- ret = deflateSetHeader(&strm, &gzh);
- if (ret != Z_OK) {
- log_warn("compression failure (initialization): %s", strm.msg);
- return -1;
- }
-
- strm.next_in = const_cast<Bytef*>(source);
- strm.avail_in = slen;
- strm.next_out = dest;
- strm.avail_out = dlen;
-
- ret = deflate(&strm, Z_FINISH);
- if (ret != Z_STREAM_END) {
- log_warn("compression failure: %s", strm.msg);
- deflateEnd(&strm);
- return -1;
- }
-
- deflateEnd(&strm);
- return strm.total_out;
-}
-
-uint32_t
-generate_crc32c(const uint8_t *string, size_t length)
-{
- log_assert(length <= std::numeric_limits<uInt>::max());
-
- uLong crc = crc32(crc32(0, 0, 0), string, length);
-
- // zlib also doesn't believe 'long' can be more than 32 bits wide.
- // This shouldn't ever fire unless there is a bug in zlib.
- log_assert(crc <= std::numeric_limits<uint32_t>::max());
-
- return crc;
-}
diff --git a/src/zpack.h b/src/zpack.h
deleted file mode 100644
index 438c9dc..0000000
--- a/src/zpack.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Copyright 2011, 2012 SRI International
- * See LICENSE for other credits and copying information
- */
-#ifndef _ZPACK_H
-#define _ZPACK_H
-
-ssize_t def(const uint8_t *source, size_t slen,
- uint8_t *dest, size_t dlen,
- int level);
-ssize_t inf(const uint8_t *source, size_t slen,
- uint8_t *dest, size_t dlen);
-
-ssize_t gzInflate(const uint8_t *source, size_t slen,
- uint8_t *dest, size_t dlen);
-ssize_t gzDeflate(const uint8_t *source, size_t slen,
- uint8_t *dest, size_t dlen,
- time_t mtime);
-
-uint32_t generate_crc32c(const uint8_t *string, size_t length);
-
-#endif
1
0
[stegotorus/master] Update audit-globals.sh for last batch of changes.
by zwol@torproject.org 20 Jul '12
by zwol@torproject.org 20 Jul '12
20 Jul '12
commit c98348b44db7c82f3d2c389ecf98148228dc6947
Author: Zack Weinberg <zackw(a)cmu.edu>
Date: Mon Apr 30 15:38:27 2012 -0700
Update audit-globals.sh for last batch of changes.
---
src/audit-globals.sh | 14 ++------------
1 files changed, 2 insertions(+), 12 deletions(-)
diff --git a/src/audit-globals.sh b/src/audit-globals.sh
index 21d6633..2a94462 100644
--- a/src/audit-globals.sh
+++ b/src/audit-globals.sh
@@ -28,6 +28,8 @@ sed '
# .o or .obj extension.
# These are genuinely OK.
+ /^compression ZLIB_CEILING$/d
+ /^compression ZLIB_UINT_MAX$/d
/^connections circuits$/d
/^connections connections$/d
/^connections closing_all_connections$/d
@@ -46,18 +48,6 @@ sed '
/^util the_evdns_base$/d
/^crypt log_crypto()::initialized$/d
/^crypt init_crypto()::initialized$/d
-
- # These are grandfathered; they need to be removed.
- /^steg\/payloads payload_count$/d
- /^steg\/payloads payload_hdrs$/d
- /^steg\/payloads payloads$/d
- /^steg\/payloads initTypePayload$/d
- /^steg\/payloads max_HTML_capacity$/d
- /^steg\/payloads max_JS_capacity$/d
- /^steg\/payloads max_PDF_capacity$/d
- /^steg\/payloads typePayload$/d
- /^steg\/payloads typePayloadCap$/d
- /^steg\/payloads typePayloadCount$/d
')
if [ -n "$symbols" ]; then
1
0
commit 4ca01f911b4f003f81b0b1cd201761ef2efc31eb
Author: Zack Weinberg <zackw(a)cmu.edu>
Date: Mon Apr 30 16:21:57 2012 -0700
Header file hygiene in steg/.
---
src/steg/b64cookies.cc | 7 +-
src/steg/cookies.cc | 5 +-
src/steg/cookies.h | 18 ++--
src/steg/http.cc | 17 ++--
src/steg/jsSteg.cc | 265 +++++++++++++++++++++++++-----------------------
src/steg/jsSteg.h | 68 +++++--------
src/steg/payloads.cc | 3 +
src/steg/payloads.h | 48 +++------
src/steg/swfSteg.h | 3 +-
9 files changed, 205 insertions(+), 229 deletions(-)
diff --git a/src/steg/b64cookies.cc b/src/steg/b64cookies.cc
index b75bedc..2efa76a 100644
--- a/src/steg/b64cookies.cc
+++ b/src/steg/b64cookies.cc
@@ -2,12 +2,9 @@
* See LICENSE for other credits and copying information
*/
+#include "util.h"
#include "b64cookies.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
int unwrap_b64_cookie(char* inbuf, char* outbuf, int buflen) {
int i,j;
j = 0;
@@ -71,7 +68,7 @@ int gen_b64_cookie_field(char* outbuf, char* data, int datalen) {
int cnt = gen_one_b64cookie(outbuf, onecookielen, data + consumed, datalen - consumed);
if (cnt < 0) {
- fprintf(stderr, "error: couldn't create cookie %d\n", cnt);
+ log_warn("couldn't create cookie: %d\n", cnt);
return cnt;
}
diff --git a/src/steg/cookies.cc b/src/steg/cookies.cc
index 885c8cb..a945397 100644
--- a/src/steg/cookies.cc
+++ b/src/steg/cookies.cc
@@ -2,6 +2,7 @@
* See LICENSE for other credits and copying information
*/
+#include "util.h"
#include "cookies.h"
int unwrap_cookie(unsigned char* inbuf, unsigned char* outbuf, int buflen) {
@@ -118,7 +119,7 @@ int gen_cookie_field(unsigned char* outbuf, int total_cookie_len, unsigned char*
if (total_cookie_len < 4) {
- fprintf(stderr, "error: cookie length too small\n");
+ log_warn("cookie length too small (have %d, need 4)", total_cookie_len);
return -1;
}
@@ -128,7 +129,7 @@ int gen_cookie_field(unsigned char* outbuf, int total_cookie_len, unsigned char*
int cnt = gen_one_cookie(outbuf, cookielen, data + consumed, datalen - consumed);
if (cnt < 0) {
- fprintf(stderr, "error: couldn't create cookie %d\n", cnt);
+ log_warn("couldn't create cookie: %d", cnt);
return cnt;
}
diff --git a/src/steg/cookies.h b/src/steg/cookies.h
index a7ed856..3955a54 100644
--- a/src/steg/cookies.h
+++ b/src/steg/cookies.h
@@ -5,16 +5,14 @@
#ifndef _COOKIES_H
#define _COOKIES_H
-#include <stdio.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <string.h>
-
int unwrap_cookie(unsigned char* inbuf, unsigned char* outbuf, int buflen);
-int gen_cookie_field(unsigned char* outbuf, int total_cookie_len, unsigned char* data, int datalen);
-int gen_one_cookie(unsigned char* outbuf, int cookielen, unsigned char* data, int datalen);
-int gen_one_cookie2(unsigned char* outbuf, int cookielen, unsigned char* data, int datalen);
-int gen_cookie_field2(unsigned char* outbuf, int total_cookie_len, unsigned char* data, int datalen);
-
+int gen_cookie_field(unsigned char* outbuf, int total_cookie_len,
+ unsigned char* data, int datalen);
+int gen_one_cookie(unsigned char* outbuf, int cookielen,
+ unsigned char* data, int datalen);
+int gen_one_cookie2(unsigned char* outbuf, int cookielen,
+ unsigned char* data, int datalen);
+int gen_cookie_field2(unsigned char* outbuf, int total_cookie_len,
+ unsigned char* data, int datalen);
#endif
diff --git a/src/steg/http.cc b/src/steg/http.cc
index 7267e6f..c413cdc 100644
--- a/src/steg/http.cc
+++ b/src/steg/http.cc
@@ -17,7 +17,6 @@
#include "b64cookies.h"
#include <event2/buffer.h>
-#include <stdio.h>
#define MIN_COOKIE_SIZE 24
#define MAX_COOKIE_SIZE 1024
@@ -219,6 +218,7 @@ lookup_peer_name_from_ip(const char* p_ip, char* p_name) {
struct addrinfo* ailist;
struct addrinfo* aip;
struct addrinfo hint;
+ int res;
char buf[128];
hint.ai_flags = AI_CANONNAME;
@@ -234,15 +234,16 @@ lookup_peer_name_from_ip(const char* p_ip, char* p_name) {
buf[strchr(buf, ':') - buf] = 0;
- if (getaddrinfo(buf, NULL, &hint, &ailist)) {
- fprintf(stderr, "error: getaddrinfo() %s\n", p_ip);
- exit(1);
+ if ((res = getaddrinfo(buf, NULL, &hint, &ailist))) {
+ log_warn("getaddrinfo(%s) failed: %s", p_ip, gai_strerror(res));
+ return 0;
}
for (aip = ailist; aip != NULL; aip = aip->ai_next) {
char buf[512];
- if (getnameinfo(aip->ai_addr, sizeof(struct sockaddr), buf, 512, NULL, 0, 0) == 0) {
- sprintf(p_name, "%s", buf);
+ if (getnameinfo(aip->ai_addr, sizeof(struct sockaddr),
+ buf, 512, NULL, 0, 0) == 0) {
+ strcpy(p_name, buf);
return 1;
}
}
@@ -437,7 +438,7 @@ int gen_uri_field(char* uri, unsigned int uri_sz, char* data, int datalen) {
if (so_far > uri_sz - 6) {
- fprintf(stderr, "too small\n");
+ log_warn("too small\n");
return 0;
}
}
@@ -529,8 +530,6 @@ http_client_uri_transmit (http_steg_t *s,
}
- // fprintf(stderr, "outbuf = %s\n", outbuf);
-
if (evbuffer_add(dest, outbuf, datalen) || // add uri field
evbuffer_add(dest, "HTTP/1.1\r\nHost: ", 19) ||
evbuffer_add(dest, s->peer_dnsname, strlen(s->peer_dnsname)) ||
diff --git a/src/steg/jsSteg.cc b/src/steg/jsSteg.cc
index 1d71918..6ff0b89 100644
--- a/src/steg/jsSteg.cc
+++ b/src/steg/jsSteg.cc
@@ -2,10 +2,23 @@
* See LICENSE for other credits and copying information
*/
+#include "util.h"
#include "payloads.h"
#include "jsSteg.h"
#include "cookies.h"
#include "compression.h"
+#include "connections.h"
+
+#include <ctype.h>
+
+#include <event2/buffer.h>
+
+// error codes
+#define INVALID_BUF_SIZE -1
+#define INVALID_DATA_CHAR -2
+
+// controlling content gzipping for jsSteg
+#define JS_GZIP_RESP 1
void buf_dump(unsigned char* buf, int len, FILE *out);
@@ -43,7 +56,7 @@ int isxString(char *str) {
* this function returns 1; otherwise, it returns 0
*
* Assumptions:
- * msg is null terminated
+ * msg is null terminated
*
*/
int isGzipContent (char *msg) {
@@ -63,7 +76,7 @@ int isGzipContent (char *msg) {
gzipFlag = 1;
break;
}
-
+
if (!strncmp(end, "\r\n\r\n", 4)){
break;
}
@@ -86,7 +99,7 @@ int isGzipContent (char *msg) {
* otherwise: return 0
*
* Assumptions:
- * msg is null terminated
+ * msg is null terminated
*
*/
int findContentType (char *msg) {
@@ -102,16 +115,16 @@ int findContentType (char *msg) {
}
if (!strncmp(ptr, "Content-Type:", 13)) {
-
- if (!strncmp(ptr+14, "text/javascript", 15) ||
- !strncmp(ptr+14, "application/javascript", 22) ||
+
+ if (!strncmp(ptr+14, "text/javascript", 15) ||
+ !strncmp(ptr+14, "application/javascript", 22) ||
!strncmp(ptr+14, "application/x-javascript", 24)) {
return HTTP_CONTENT_JAVASCRIPT;
}
if (!strncmp(ptr+14, "text/html", 9)) {
return HTTP_CONTENT_HTML;
}
- if (!strncmp(ptr+14, "application/pdf", 15) ||
+ if (!strncmp(ptr+14, "application/pdf", 15) ||
!strncmp(ptr+14, "application/x-pdf", 17)) {
return HTTP_CONTENT_PDF;
}
@@ -119,7 +132,7 @@ int findContentType (char *msg) {
return HTTP_CONTENT_SWF;
}
}
-
+
if (!strncmp(end, "\r\n\r\n", 4)){
break;
}
@@ -141,7 +154,7 @@ int findContentType (char *msg) {
* function returns the number of characters in data successfully
* embedded in jData, or returns one of the error codes
*
- * approach:
+ * approach:
* replaces characters in jTemplate that are hexadecimal (i.e., {0-9,a-f,A-F})
* with those in data, and leave the non-hex char in place
*
@@ -170,14 +183,14 @@ int findContentType (char *msg) {
*
*/
int encode(char *data, char *jTemplate, char *jData,
- unsigned int dlen, unsigned int jtlen, unsigned int jdlen )
+ unsigned int dlen, unsigned int jtlen, unsigned int jdlen )
{
unsigned int encCnt = 0; /* num of data encoded in jData */
char *dp, *jtp, *jdp; /* current pointers for data, jTemplate, and jData */
-
+
unsigned int j;
- /*
+ /*
* insanity checks
*/
if (jdlen < jtlen) { return INVALID_BUF_SIZE; }
@@ -196,9 +209,9 @@ int encode(char *data, char *jTemplate, char *jData,
*jdp = *dp;
dp++;
encCnt++;
- if (encCnt == dlen) {
- jtp++; jdp++;
- break;
+ if (encCnt == dlen) {
+ jtp++; jdp++;
+ break;
}
} else {
*jdp = *jtp;
@@ -229,12 +242,12 @@ int encode(char *data, char *jTemplate, char *jData,
* the JS to JS_DELIMITER_REPLACEMENT, before all the data is encoded.
*
* Output:
- * fin - signal the caller whether all data has been encoded and
+ * fin - signal the caller whether all data has been encoded and
* a JS_DELIMITER has been added
*/
int encode2(char *data, char *jTemplate, char *jData,
- unsigned int dlen, unsigned int jtlen,
- unsigned int jdlen, int *fin)
+ unsigned int dlen, unsigned int jtlen,
+ unsigned int jdlen, int *fin)
{
unsigned int encCnt = 0; /* num of data encoded in jData */
char *dp, *jtp, *jdp; /* current pointers for data, jTemplate, and jData */
@@ -329,8 +342,8 @@ int encode2(char *data, char *jTemplate, char *jData,
int encodeHTTPBody(char *data, char *jTemplate, char *jData,
- unsigned int dlen, unsigned int jtlen,
- unsigned int jdlen, int mode)
+ unsigned int dlen, unsigned int jtlen,
+ unsigned int jdlen, int mode)
{
char *dp, *jtp, *jdp; // current pointers for data, jTemplate, and jData
unsigned int encCnt = 0; // num of data encoded in jData
@@ -340,8 +353,8 @@ int encodeHTTPBody(char *data, char *jTemplate, char *jData,
int scriptLen;
int fin;
unsigned int dlen2 = dlen;
- dp = data;
- jtp = jTemplate;
+ dp = data;
+ jtp = jTemplate;
jdp = jData;
@@ -357,16 +370,16 @@ int encodeHTTPBody(char *data, char *jTemplate, char *jData,
#endif
return encCnt;
- }
+ }
else if (mode == CONTENT_HTML_JAVASCRIPT) {
while (encCnt < dlen2) {
jsStart = strstr(jtp, startScriptTypeJS);
- if (jsStart == NULL) {
+ if (jsStart == NULL) {
#ifdef DEBUG
- printf("lack of usable JS; can't find startScriptType\n");
+ printf("lack of usable JS; can't find startScriptType\n");
#endif
- return encCnt;
+ return encCnt;
}
skip = strlen(startScriptTypeJS)+jsStart-jtp;
#ifdef DEBUG2
@@ -375,11 +388,11 @@ int encodeHTTPBody(char *data, char *jTemplate, char *jData,
memcpy(jdp, jtp, skip);
jtp = jtp+skip; jdp = jdp+skip;
jsEnd = strstr(jtp, endScriptTypeJS);
- if (jsEnd == NULL) {
+ if (jsEnd == NULL) {
#ifdef DEBUG
- printf("lack of usable JS; can't find endScriptType\n");
+ printf("lack of usable JS; can't find endScriptType\n");
#endif
- return encCnt;
+ return encCnt;
}
// the JS for encoding data is between jsStart and jsEnd
@@ -388,7 +401,7 @@ int encodeHTTPBody(char *data, char *jTemplate, char *jData,
n = encode2(dp, jtp, jdp, dlen, scriptLen, jdlen, &fin);
// update encCnt, dp, and dlen based on n
if (n > 0) {
- encCnt = encCnt+n; dp = dp+n; dlen = dlen-n;
+ encCnt = encCnt+n; dp = dp+n; dlen = dlen-n;
}
// update jtp, jdp, jdlen
skip = jsEnd-jtp;
@@ -405,9 +418,9 @@ int encodeHTTPBody(char *data, char *jTemplate, char *jData,
// added by encode()
if (fin == 0 && dlen == 0) {
if (skip > 0) {
- *jtp = JS_DELIMITER;
- jtp = jtp+1; jdp = jdp+1;
- skip--;
+ *jtp = JS_DELIMITER;
+ jtp = jtp+1; jdp = jdp+1;
+ skip--;
}
}
memcpy(jdp, jtp, skip);
@@ -450,13 +463,13 @@ int encodeHTTPBody(char *data, char *jTemplate, char *jData,
* jData = "01p_or2=M3th.r4n5om()*6789ABCDEF0000000; dfp_tile = 1;"
* jdlen = 54
* dlen = 16
- * dataBufSize = 1000
+ * dataBufSize = 1000
* decode() returns 16
* dataBuf= "0123456789ABCDEF"
*
*/
int decode (char *jData, char *dataBuf, unsigned int jdlen,
- unsigned int dlen, unsigned int dataBufSize )
+ unsigned int dlen, unsigned int dataBufSize )
{
unsigned int decCnt = 0; /* num of data decoded */
char *dp, *jdp; /* current pointers for dataBuf and jData */
@@ -468,10 +481,10 @@ int decode (char *jData, char *dataBuf, unsigned int jdlen,
for (j=0; j<jdlen; j++) {
if ( isxdigit(*jdp) ) {
if (decCnt < dlen) {
- decCnt++;
- *dp++ = *jdp++;
+ decCnt++;
+ *dp++ = *jdp++;
} else {
- break;
+ break;
}
} else {
jdp++;
@@ -487,16 +500,16 @@ int decode (char *jData, char *dataBuf, unsigned int jdlen,
* stops when JS_DELIMITER is encountered.
*/
int decode2 (char *jData, char *dataBuf, unsigned int jdlen,
- unsigned int dataBufSize, int *fin )
+ unsigned int dataBufSize, int *fin )
{
unsigned int decCnt = 0; /* num of data decoded */
char *dp, *jdp; /* current pointers for dataBuf and jData */
int i,j;
int cjdlen = jdlen;
-
+
*fin = 0;
dp = dataBuf; jdp = jData;
-
+
i = offset2Hex(jdp, cjdlen, 0);
while (i != -1) {
// return if JS_DELIMITER exists between jdp and jdp+i
@@ -515,9 +528,9 @@ int decode2 (char *jData, char *dataBuf, unsigned int jdlen,
jdp = jdp+1; cjdlen--;
dp = dp+1; dataBufSize--;
decCnt++;
-
+
// find the next hex char
- i = offset2Hex(jdp, cjdlen, 1);
+ i = offset2Hex(jdp, cjdlen, 1);
}
// look for JS_DELIMITER between jdp to jData+jdlen
@@ -526,7 +539,7 @@ int decode2 (char *jData, char *dataBuf, unsigned int jdlen,
*fin = 1;
break;
}
- jdp = jdp+1;
+ jdp = jdp+1;
}
return decCnt;
@@ -534,7 +547,7 @@ int decode2 (char *jData, char *dataBuf, unsigned int jdlen,
int decodeHTTPBody (char *jData, char *dataBuf, unsigned int jdlen,
- unsigned int dataBufSize, int *fin, int mode )
+ unsigned int dataBufSize, int *fin, int mode )
{
char *jsStart, *jsEnd;
char *dp, *jdp; // current pointers for data and jData
@@ -542,31 +555,31 @@ int decodeHTTPBody (char *jData, char *dataBuf, unsigned int jdlen,
int decCnt = 0;
int n;
int dlen = dataBufSize;
- dp = dataBuf; jdp = jData;
+ dp = dataBuf; jdp = jData;
if (mode == CONTENT_JAVASCRIPT) {
decCnt = decode2(jData, dataBuf, jdlen, dataBufSize, fin);
if (*fin == 0) {
log_warn("Unable to find JS_DELIMITER");
}
- }
+ }
else if (mode == CONTENT_HTML_JAVASCRIPT) {
*fin = 0;
while (*fin == 0) {
jsStart = strstr(jdp, startScriptTypeJS);
if (jsStart == NULL) {
#ifdef DEBUG
- printf("Can't find startScriptType for decoding data inside script type JS\n");
+ printf("Can't find startScriptType for decoding data inside script type JS\n");
#endif
- return decCnt;
+ return decCnt;
}
jdp = jsStart+strlen(startScriptTypeJS);
jsEnd = strstr(jdp, endScriptTypeJS);
- if (jsEnd == NULL) {
+ if (jsEnd == NULL) {
#ifdef DEBUG
- printf("Can't find endScriptType for decoding data inside script type JS\n");
+ printf("Can't find endScriptType for decoding data inside script type JS\n");
#endif
- return decCnt;
+ return decCnt;
}
// the JS for decoding data is between jsStart and jsEnd
@@ -592,18 +605,18 @@ int decodeHTTPBody (char *jData, char *dataBuf, unsigned int jdlen,
void printerr(int errno) {
if (errno == INVALID_BUF_SIZE) {
printf ("Error: Output buffer too small\n");
- }
+ }
else if (errno == INVALID_DATA_CHAR) {
printf ("Error: Non-hex char in data\n");
- }
+ }
else {
printf ("Unknown error: %i\n", errno);
}
}
-int testEncode(char *data, char *js, char *outBuf, unsigned int dlen, unsigned int jslen,
- unsigned int outBufLen, int testNum) {
+int testEncode(char *data, char *js, char *outBuf, unsigned int dlen, unsigned int jslen,
+ unsigned int outBufLen, int testNum) {
int r;
printf ("***** Start of testEncode (%i) *****\n", testNum);
@@ -625,8 +638,8 @@ int testEncode(char *data, char *js, char *outBuf, unsigned int dlen, unsigned i
return r;
}
-int testDecode(char *inBuf, char *outBuf, unsigned int inBufSize, unsigned int dlen,
- unsigned int outBufSize, int testNum) {
+int testDecode(char *inBuf, char *outBuf, unsigned int inBufSize, unsigned int dlen,
+ unsigned int outBufSize, int testNum) {
int r;
@@ -650,9 +663,9 @@ int testDecode(char *inBuf, char *outBuf, unsigned int inBufSize, unsigned int d
}
-int testEncode2(char *data, char *js, char *outBuf,
- unsigned int dlen, unsigned int jslen, unsigned int outBufLen,
- int mode, int testNum) {
+int testEncode2(char *data, char *js, char *outBuf,
+ unsigned int dlen, unsigned int jslen, unsigned int outBufLen,
+ int mode, int testNum) {
int r;
// int fin;
@@ -667,14 +680,14 @@ int testEncode2(char *data, char *js, char *outBuf,
if (r < 0) {
printerr(r);
- }
+ }
else {
printf ("\nOutput:\n");
printf ("%i char of data embedded in outBuf\n", r);
// printf ("fin = %d\n", fin);
outBuf[jslen] = '\0';
printf ("outBuf = %s\n", outBuf);
-
+
if ((unsigned int) r < dlen) {
printf ("Incomplete data encoding\n");
}
@@ -686,9 +699,9 @@ int testEncode2(char *data, char *js, char *outBuf,
-int testDecode2(char *inBuf, char *outBuf,
- unsigned int inBufSize, unsigned int outBufSize,
- int mode, int testNum) {
+int testDecode2(char *inBuf, char *outBuf,
+ unsigned int inBufSize, unsigned int outBufSize,
+ int mode, int testNum) {
int r;
int fin;
@@ -764,7 +777,7 @@ http_server_JS_transmit (payloads& pl, struct evbuffer *source, conn_t *conn,
(int) sbuflen, (int) mjs);
return -1;
}
-
+
// Convert data in 'source' to hexadecimal and write it to data
cnt = 0;
for (i = 0; i < nv; i++) {
@@ -826,8 +839,8 @@ http_server_JS_transmit (payloads& pl, struct evbuffer *source, conn_t *conn,
// work in progress
if (gzipMode == 1) {
// conservative estimate:
- // sizeof outbuf2 = cLen + 10-byte for gzip header + 8-byte for crc
- outbuf2 = (char *)xmalloc(cLen+18);
+ // sizeof outbuf2 = cLen + 10-byte for gzip header + 8-byte for crc
+ outbuf2 = (char *)xmalloc(cLen+18);
outbuf2len = compress((const uint8_t *)outbuf, cLen,
(uint8_t *)outbuf2, cLen+18, c_format_gzip);
@@ -844,7 +857,7 @@ http_server_JS_transmit (payloads& pl, struct evbuffer *source, conn_t *conn,
outbuf2len = cLen;
}
- // outbuf2 points to the HTTP payload (of length outbuf2len) to be sent
+ // outbuf2 points to the HTTP payload (of length outbuf2len) to be sent
if (mode == CONTENT_JAVASCRIPT) { // JavaScript in HTTP body
newHdrLen = gen_response_header((char*) "application/x-javascript", gzipMode,
@@ -863,7 +876,7 @@ http_server_JS_transmit (payloads& pl, struct evbuffer *source, conn_t *conn,
return -1;
}
- // newHdr points to the HTTP header (of length newHdrLen) to be sent
+ // newHdr points to the HTTP header (of length newHdrLen) to be sent
if (evbuffer_add(dest, newHdr, newHdrLen)) {
log_warn("SERVER ERROR: evbuffer_add() fails for newHdr");
@@ -903,39 +916,39 @@ http_handle_client_JS_receive(steg_t *, conn_t *conn, struct evbuffer *dest, str
unsigned char *field, *fieldStart, *fieldEnd, *fieldValStart;
char *httpBody;
-
+
int decCnt, fin, i, j, k, gzipMode=0, httpBodyLen, buf2len, contentType = 0;
ev_ssize_t r;
struct evbuffer * scratch;
char c;
-
-
+
+
s2 = evbuffer_search(source, "\r\n\r\n", sizeof ("\r\n\r\n") -1 , NULL);
if (s2.pos == -1) {
log_debug("CLIENT Did not find end of HTTP header %d", (int) evbuffer_get_length(source));
// evbuffer_dump(source, stderr);
return RECV_INCOMPLETE;
}
-
+
log_debug("CLIENT received response header with len %d", (int)s2.pos);
-
+
response_len = 0;
- hdrLen = s2.pos + strlen("\r\n\r\n");
+ hdrLen = s2.pos + strlen("\r\n\r\n");
response_len += hdrLen;
-
+
// get content length, e.g., Content-Length: 22417
field = evbuffer_pullup(source, s2.pos);
if (field == NULL) {
log_debug("CLIENT unable to pullup the complete HTTP header");
return RECV_BAD;
}
-
+
fieldStart = (unsigned char*) strstr((char*) field, "Content-Length: ");
if (fieldStart == NULL) {
log_debug("CLIENT unable to find Content-Length in the header");
return RECV_BAD;
}
-
+
fieldEnd = (unsigned char*) strstr((char *)fieldStart, "\r\n");
if (fieldEnd == NULL) {
log_debug("CLIENT unable to find end of line for Content-Length");
@@ -949,15 +962,15 @@ http_handle_client_JS_receive(steg_t *, conn_t *conn, struct evbuffer *dest, str
}
memcpy(buf, fieldValStart, fieldEnd-fieldValStart);
buf[fieldEnd-fieldValStart] = 0;
-
+
content_len = atoi(buf);
log_debug("CLIENT received Content-Length = %d\n", content_len);
-
+
response_len += content_len;
if (response_len > (int) evbuffer_get_length(source))
return RECV_INCOMPLETE;
-
+
// read the entire HTTP resp
if (response_len < HTTP_MSG_BUF_SIZE) {
r = evbuffer_copyout(source, respMsg, response_len);
@@ -975,12 +988,12 @@ http_handle_client_JS_receive(steg_t *, conn_t *conn, struct evbuffer *dest, str
log_debug("CLIENT: HTTP response too large to handle");
return RECV_BAD;
}
-
+
log_debug("CLIENT received HTTP response with length %d\n", response_len);
// buf_dump((unsigned char*)respMsg, response_len, stderr);
// log_debug("HTTP response header:");
// buf_dump((unsigned char*)respMsg, hdrLen+80, stderr);
-
+
contentType = findContentType (respMsg);
if (contentType != HTTP_CONTENT_JAVASCRIPT && contentType != HTTP_CONTENT_HTML) {
log_warn("ERROR: Invalid content type (%d)", contentType);
@@ -997,16 +1010,14 @@ http_handle_client_JS_receive(steg_t *, conn_t *conn, struct evbuffer *dest, str
(uint8_t *)buf2, HTTP_MSG_BUF_SIZE);
if (buf2len <= 0) {
log_warn("gzInflate for httpBody fails");
- fprintf(stderr, "gzInflate for httpBody fails");
- exit(-1);
return RECV_BAD;
}
buf2[buf2len] = 0;
httpBody = buf2;
httpBodyLen = buf2len;
}
-
- if (contentType == HTTP_CONTENT_JAVASCRIPT) {
+
+ if (contentType == HTTP_CONTENT_JAVASCRIPT) {
decCnt = decodeHTTPBody(httpBody, data, httpBodyLen, HTTP_MSG_BUF_SIZE,
&fin, CONTENT_JAVASCRIPT);
} else {
@@ -1014,59 +1025,56 @@ http_handle_client_JS_receive(steg_t *, conn_t *conn, struct evbuffer *dest, str
&fin, CONTENT_HTML_JAVASCRIPT);
}
data[decCnt] = 0;
-
+
log_debug("After decodeHTTPBody; decCnt: %d\n", decCnt);
// decCnt is an odd number or data is not a hex string
if (decCnt % 2) {
- fprintf(stderr, "CLIENT ERROR: An odd number of hex characters received\n");
- // buf_dump((unsigned char*)data, decCnt, stderr);
+ log_debug("CLIENT ERROR: An odd number of hex characters received\n");
return RECV_BAD;
}
-
+
if (! isxString(data)) {
- log_warn("CLIENT ERROR: Data received not hex");
- // buf_dump((unsigned char*)data, decCnt, stderr);
+ log_debug("CLIENT ERROR: Data received not hex");
return RECV_BAD;
}
-
+
// log_debug("Hex data received:");
// buf_dump ((unsigned char*)data, decCnt, stderr);
-
+
// get a scratch buffer
scratch = evbuffer_new();
if (!scratch) return RECV_BAD;
-
+
if (evbuffer_expand(scratch, decCnt/2)) {
log_warn("CLIENT ERROR: Evbuffer expand failed \n");
evbuffer_free(scratch);
return RECV_BAD;
}
-
+
// convert hex data back to binary
for (i=0, j=0; i< decCnt; i=i+2, ++j) {
sscanf(&data[i], "%2x", (unsigned int*) &k);
c = (char)k;
evbuffer_add(scratch, &c, 1);
}
-
+
// log_debug("CLIENT Done converting hex data to binary:\n");
// evbuffer_dump(scratch, stderr);
-
-
- // fprintf(stderr, "CLIENT RECEIVED payload of size %d\n", (int) evbuffer_get_length(scratch));
+
+
// add the scratch buffer (which contains the data) to dest
-
+
if (evbuffer_add_buffer(dest, scratch)) {
evbuffer_free(scratch);
log_warn("CLIENT ERROR: Failed to transfer buffer");
return RECV_BAD;
}
log_debug("Added scratch (buffer) to dest\n");
-
+
evbuffer_free(scratch);
-
-
+
+
if (response_len <= (int) evbuffer_get_length(source)) {
if (evbuffer_drain(source, response_len) == -1) {
log_warn("CLIENT ERROR: Failed to drain source");
@@ -1077,10 +1085,10 @@ http_handle_client_JS_receive(steg_t *, conn_t *conn, struct evbuffer *dest, str
log_warn("response_len > buffer size... can't drain");
exit(-1);
}
-
-
+
+
log_debug("Drained source for %d char\n", response_len);
-
+
// downcast_steg(s)->have_received = 1;
conn->expect_close();
return RECV_GOOD;
@@ -1090,25 +1098,25 @@ http_handle_client_JS_receive(steg_t *, conn_t *conn, struct evbuffer *dest, str
/*****
int
main() {
- int jDataSize = 1000;
+ int jDataSize = 1000;
char jData[jDataSize];
- int outDataBufSize = 1000;
+ int outDataBufSize = 1000;
char outDataBuf[outDataBufSize];
int r;
// test case 1: data embedded in javascript
r = testEncode2(data1, js1, jData, strlen(data1), strlen(js1), jDataSize,
- CONTENT_JAVASCRIPT, 1);
+ CONTENT_JAVASCRIPT, 1);
if (r > 0) { testDecode2(jData, outDataBuf, strlen(js1), outDataBufSize, CONTENT_JAVASCRIPT, 1); }
-
+
// test case 4: data embedded in one script type javascript
r = testEncode2(data1, js4, jData, strlen(data1), strlen(js4), jDataSize,
- CONTENT_HTML_JAVASCRIPT, 4);
+ CONTENT_HTML_JAVASCRIPT, 4);
if (r > 0) { testDecode2(jData, outDataBuf, strlen(js4), outDataBufSize, CONTENT_HTML_JAVASCRIPT, 4); }
// test case 5: data embedded in one script type javascript
r = testEncode2(data1, js5, jData, strlen(data1), strlen(js5), jDataSize,
- CONTENT_HTML_JAVASCRIPT, 5);
+ CONTENT_HTML_JAVASCRIPT, 5);
if (r > 0) { testDecode2(jData, outDataBuf, strlen(js5), outDataBufSize, CONTENT_HTML_JAVASCRIPT, 5); }
@@ -1119,43 +1127,42 @@ http_handle_client_JS_receive(steg_t *, conn_t *conn, struct evbuffer *dest, str
/*****
int
main() {
- int jDataSize = 1000;
+ int jDataSize = 1000;
char jData[jDataSize];
- int jDataSmallSize = 5;
+ int jDataSmallSize = 5;
char jDataSmall[jDataSmallSize];
- int outDataBufSize = 1000;
+ int outDataBufSize = 1000;
char outDataBuf[outDataBufSize];
- int outDataSmallSize = 5;
+ int outDataSmallSize = 5;
char outDataSmall[outDataSmallSize];
int r;
// test case 1: data embedded in javascript
- r = testEncode(data1, js1, jData, strlen(data1), strlen(js1), jDataSize, 1);
+ r = testEncode(data1, js1, jData, strlen(data1), strlen(js1), jDataSize, 1);
if (r > 0) { testDecode(jData, outDataBuf, strlen(js1), r, outDataBufSize, 1); }
// test case 2: data embedded in javascript
- r = testEncode(data1, js2, jData, strlen(data1), strlen(js2), jDataSize, 2);
+ r = testEncode(data1, js2, jData, strlen(data1), strlen(js2), jDataSize, 2);
if (r > 0) { testDecode(jData, outDataBuf, strlen(js2), r, outDataBufSize, 2); }
// test case 3: data partially embedded in javascript; num of hex char in js < data len
- r = testEncode(data1, js3, jData, strlen(data1), strlen(js3), jDataSize, 3);
+ r = testEncode(data1, js3, jData, strlen(data1), strlen(js3), jDataSize, 3);
if (r > 0) { testDecode(jData, outDataBuf, strlen(js3), r, outDataBufSize, 3); }
// test case 4: data embedded in javascript; larger data
- r = testEncode(data2, js1, jData, strlen(data2), strlen(js1), jDataSize, 4);
+ r = testEncode(data2, js1, jData, strlen(data2), strlen(js1), jDataSize, 4);
if (r > 0) { testDecode(jData, outDataBuf, strlen(js1), r, outDataBufSize, 4); }
// test case 5 (for encode): err for non-hex data
- testEncode(nonhexstr, js1, jData, strlen(nonhexstr), strlen(js1), jDataSize, 5);
-
+ testEncode(nonhexstr, js1, jData, strlen(nonhexstr), strlen(js1), jDataSize, 5);
+
// test case 6 (for encode): err for small output buf
- testEncode(data1, js1, jDataSmall, strlen(data1), strlen(js1), jDataSmallSize, 6);
+ testEncode(data1, js1, jDataSmall, strlen(data1), strlen(js1), jDataSmallSize, 6);
// test case 7 (for decode): err for small output buf
- r = testEncode(data1, js1, jData, strlen(data1), strlen(js1), jDataSize, 7);
+ r = testEncode(data1, js1, jData, strlen(data1), strlen(js1), jDataSize, 7);
if (r > 0) { testDecode(jData, outDataSmall, strlen(js1), r, outDataSmallSize, 7); }
}
*****/
-
diff --git a/src/steg/jsSteg.h b/src/steg/jsSteg.h
index 40ec611..e8232d5 100644
--- a/src/steg/jsSteg.h
+++ b/src/steg/jsSteg.h
@@ -5,74 +5,58 @@
#ifndef _JSSTEG_H
#define _JSSTEG_H
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include "util.h"
-#include "connections.h"
-#include "steg.h"
-#include <event2/buffer.h>
-
-// error codes
-#define INVALID_BUF_SIZE -1
-#define INVALID_DATA_CHAR -2
-
-// controlling content gzipping for jsSteg
-#define JS_GZIP_RESP 1
-
struct payloads;
-int encodeHTTPBody(char *data, char *jTemplate, char *jData,unsigned int dlen,
- unsigned int jtlen, unsigned int jdlen, int mode);
+int encodeHTTPBody(char *data, char *jTemplate, char *jData, unsigned int dlen,
+ unsigned int jtlen, unsigned int jdlen, int mode);
int isxString(char *str);
-int isGzipContent (char *msg);
+int isGzipContent (char *msg);
int findContentType (char *msg);
int decodeHTTPBody (char *jData, char *dataBuf, unsigned int jdlen,
- unsigned int dataBufSize, int *fin, int mode);
+ unsigned int dataBufSize, int *fin, int mode);
int encode(char *data, char *jTemplate, char *jData,
- unsigned int dlen, unsigned int jtlen, unsigned int jdlen );
+ unsigned int dlen, unsigned int jtlen, unsigned int jdlen );
int encode2(char *data, char *jTemplate, char *jData,
- unsigned int dlen, unsigned int jtlen,
- unsigned int jdlen, int *fin);
+ unsigned int dlen, unsigned int jtlen,
+ unsigned int jdlen, int *fin);
int decode (char *jData, char *dataBuf, unsigned int jdlen,
- unsigned int dlen, unsigned int dataBufSize );
+ unsigned int dlen, unsigned int dataBufSize );
int decode2 (char *jData, char *dataBuf, unsigned int jdlen,
- unsigned int dataBufSize, int *fin );
+ unsigned int dataBufSize, int *fin );
void printerr(int errno);
-int testEncode(char *data, char *js, char *outBuf, unsigned int dlen, unsigned int jslen,
- unsigned int outBufLen, int testNum);
-
-int testDecode(char *inBuf, char *outBuf, unsigned int inBufSize, unsigned int dlen,
- unsigned int outBufSize, int testNum);
+int testEncode(char *data, char *js, char *outBuf,
+ unsigned int dlen, unsigned int jslen,
+ unsigned int outBufLen, int testNum);
-int testEncode2(char *data, char *js, char *outBuf,
- unsigned int dlen, unsigned int jslen, unsigned int outBufLen,
- int mode, int testNum);
+int testDecode(char *inBuf, char *outBuf, unsigned int inBufSize,
+ unsigned int dlen,
+ unsigned int outBufSize, int testNum);
-int testDecode2(char *inBuf, char *outBuf,
- unsigned int inBufSize, unsigned int outBufSize,
- int mode, int testNum);
+int testEncode2(char *data, char *js, char *outBuf,
+ unsigned int dlen, unsigned int jslen, unsigned int outBufLen,
+ int mode, int testNum);
+int testDecode2(char *inBuf, char *outBuf,
+ unsigned int inBufSize, unsigned int outBufSize,
+ int mode, int testNum);
-int
-http_server_JS_transmit (payloads& pl, struct evbuffer *source, conn_t *conn, unsigned int content_type);
int
-http_handle_client_JS_receive(steg_t *s, conn_t *conn, struct evbuffer *dest, struct evbuffer* source);
-
+http_server_JS_transmit (payloads& pl, struct evbuffer *source,
+ conn_t *conn, unsigned int content_type);
+int
+http_handle_client_JS_receive(steg_t *s, conn_t *conn,
+ struct evbuffer *dest, struct evbuffer* source);
#endif
-
-
diff --git a/src/steg/payloads.cc b/src/steg/payloads.cc
index d24711f..7116e36 100644
--- a/src/steg/payloads.cc
+++ b/src/steg/payloads.cc
@@ -6,6 +6,9 @@
#include "payloads.h"
#include "swfSteg.h"
+#include <ctype.h>
+#include <time.h>
+
/*
* fixContentLen corrects the Content-Length for an HTTP msg that
* has been ungzipped, and removes the "Content-Encoding: gzip"
diff --git a/src/steg/payloads.h b/src/steg/payloads.h
index cb809ba..b19c5be 100644
--- a/src/steg/payloads.h
+++ b/src/steg/payloads.h
@@ -5,15 +5,6 @@
#ifndef _PAYLOADS_H
#define _PAYLOADS_H
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <string.h>
-#include <sys/types.h>
-#include <arpa/inet.h>
-#include <ctype.h>
-
-
/* three files:
server_data, client data, protocol data
*/
@@ -22,8 +13,6 @@
#define RECV_INCOMPLETE 0
#define RECV_BAD -1
-
-
#define CONN_DATA_REQUEST 1 /* payload packet sent by client */
#define CONN_DATA_REPLY 2 /* payload packet sent by server */
@@ -33,7 +22,7 @@
#define MAX_RESP_HDR_SIZE 512
// max number of payloads that have enough capacity from which
-// we choose the best fit
+// we choose the best fit
#define MAX_CANDIDATE_PAYLOADS 10
// jsSteg-specific defines
@@ -52,6 +41,8 @@
#define HTML_MIN_AVAIL_SIZE 1026
+#define HTTP_MSG_BUF_SIZE 100000
+
#define PDF_DELIMITER_SIZE 2
#define PDF_MIN_AVAIL_SIZE 10240
// PDF_MIN_AVAIL_SIZE should reflect the min number of data bytes
@@ -73,7 +64,6 @@
#define CONTENT_JAVASCRIPT 1
#define CONTENT_HTML_JAVASCRIPT 2
-
// payloads for specific content type
//
// MAX_CONTENT_TYPE specifies the maximum number of supported content types
@@ -92,8 +82,6 @@
#define MAX_CONTENT_TYPE 11
-
-
typedef int SID;
typedef short PacketType;
typedef short StateFlag;
@@ -106,23 +94,20 @@ typedef short StateFlag;
/* struct for reading in the payload_gen dump file */
-typedef struct {
+struct pentry_header {
PacketType ptype;
int length;
ushort port; /* network format */
-}pentry_header;
-
-
-
+};
-typedef struct service_state {
+struct service_state {
SID id;
PacketType data_type;
SID next_state;
// double* probabilities;
StateFlag flg;
int dir;
-}state;
+};
struct payloads {
int initTypePayload[MAX_CONTENT_TYPE];
@@ -139,12 +124,10 @@ struct payloads {
int payload_count;
};
-
-#define HTTP_MSG_BUF_SIZE 100000
-
void load_payloads(payloads& pl, const char* fname);
unsigned int find_client_payload(payloads& pl, char* buf, int len, int type);
-unsigned int find_server_payload(payloads& pl, char** buf, int len, int type, int contentType);
+unsigned int find_server_payload(payloads& pl, char** buf, int len, int type,
+ int contentType);
int init_JS_payload_pool(payloads& pl, int len, int type, int minCapacity);
int init_SWF_payload_pool(payloads& pl, int len, int type, int minCapacity);
@@ -152,8 +135,10 @@ int init_PDF_payload_pool(payloads& pl, int len, int type,int minCapacity);
int init_HTML_payload_pool(payloads& pl, int len, int type, int minCapacity);
-int get_next_payload (payloads& pl, int contentType, char** buf, int* size, int* cap);
-int get_payload (payloads& pl, int contentType, int cap, char** buf, int* size);
+int get_next_payload (payloads& pl, int contentType, char** buf, int* size,
+ int* cap);
+int get_payload (payloads& pl, int contentType, int cap, char** buf,
+ int* size);
int has_eligible_HTTP_content (char* buf, int len, int type);
int fixContentLen (char* payload, int payloadLen, char *buf, int bufLen);
@@ -168,14 +153,15 @@ unsigned int capacityJS3 (char* buf, int len, int mode);
unsigned int get_max_JS_capacity(void);
unsigned int get_max_HTML_capacity(void);
-char * strInBinary (const char *pattern, unsigned int patternLen, const char *blob, unsigned int blobLen);
-
+char * strInBinary (const char *pattern, unsigned int patternLen,
+ const char *blob, unsigned int blobLen);
unsigned int capacityPDF (char* buf, int len);
unsigned int get_max_PDF_capacity(void);
int find_content_length (char *hdr, int hlen);
int find_uri_type(char* buf, int size);
-int gen_response_header(char* content_type, int gzip, int length, char* buf, int buflen);
+int gen_response_header(char* content_type, int gzip, int length,
+ char* buf, int buflen);
#endif
diff --git a/src/steg/swfSteg.h b/src/steg/swfSteg.h
index 938b05a..e1f3ff7 100644
--- a/src/steg/swfSteg.h
+++ b/src/steg/swfSteg.h
@@ -20,6 +20,7 @@ int
http_server_SWF_transmit(payloads& pl, struct evbuffer *source, conn_t *conn);
int
-http_handle_client_SWF_receive(steg_t *s, conn_t *conn, struct evbuffer *dest, struct evbuffer* source);
+http_handle_client_SWF_receive(steg_t *s, conn_t *conn, struct evbuffer *dest,
+ struct evbuffer* source);
#endif
1
0
commit f269b6e1b4ab7abfc1c3478aef3ab45de2c22a55
Author: Vinod Yegneswaran <vinod(a)csl.sri.com>
Date: Tue Nov 1 19:23:05 2011 +0000
fixed a typo...
git-svn-id: svn+ssh://spartan.csl.sri.com/svn/private/DEFIANCE@113 a58ff0ac-194c-e011-a152-003048836090
---
src/steg/zpack.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/steg/zpack.c b/src/steg/zpack.c
index 57cd2b2..63aa412 100644
--- a/src/steg/zpack.c
+++ b/src/steg/zpack.c
@@ -52,7 +52,7 @@ int def(char *source, int slen, char *dest, int dlen, int level)
memcpy (in, source, strm.avail_in);
slen = slen - strm.avail_in;
- source - source + strm.avail_in;
+ source = source + strm.avail_in;
flush = (slen == 0) ? Z_FINISH : Z_NO_FLUSH;
strm.next_in = in;
1
0
[stegotorus/master] disabled x_http.c by adding return 0 to x_http_detect.
by zwol@torproject.org 20 Jul '12
by zwol@torproject.org 20 Jul '12
20 Jul '12
commit 27c3f3c2dc33ca82ba5f558cf808e65c3747b3ba
Author: Vinod Yegneswaran <vinod(a)csl.sri.com>
Date: Tue Nov 1 06:08:24 2011 +0000
disabled x_http.c by adding return 0 to x_http_detect.
svn version should now be working...
git-svn-id: svn+ssh://spartan.csl.sri.com/svn/private/DEFIANCE@110 a58ff0ac-194c-e011-a152-003048836090
---
src/steg/x_http.c | 1 +
start-client.csh | 4 ++--
start-server.csh | 4 ++--
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/steg/x_http.c b/src/steg/x_http.c
index df0b94b..c26fe1f 100644
--- a/src/steg/x_http.c
+++ b/src/steg/x_http.c
@@ -71,6 +71,7 @@ x_http_detect(conn_t *conn)
{
struct evbuffer *buf = conn_get_inbound(conn);
unsigned char *data;
+ return 0;
/* Look for the text of http_response_1. */
if (evbuffer_get_length(buf) >= sizeof http_response_1 - 1) {
diff --git a/start-client.csh b/start-client.csh
index 65f4465..a09302e 100644
--- a/start-client.csh
+++ b/start-client.csh
@@ -2,7 +2,7 @@
# ./obfsproxy --log-min-severity=debug x_dsteg socks 127.0.0.1:1080 x_http
setenv EVENT_NOKQUEUE yes
-#./obfsproxy --log-min-severity=debug chop socks 127.0.0.1:1080 127.0.0.1:8080 x_http2 127.0.0.1:8081 x_http2
+./obfsproxy --log-min-severity=debug chop socks 127.0.0.1:1080 127.0.0.1:8080 x_http2 127.0.0.1:8081 x_http2
# ./obfsproxy --log-min-severity=warn chop socks 127.0.0.1:1080 127.0.0.1:8080 x_http2 127.0.0.1:8081 x_http2
-./obfsproxy --log-min-severity=error chop socks 127.0.0.1:1080 127.0.0.1:8080 x_http2 127.0.0.1:8081 x_http2
+#./obfsproxy --log-min-severity=error chop socks 127.0.0.1:1080 127.0.0.1:8080 x_http2 127.0.0.1:8081 x_http2
diff --git a/start-server.csh b/start-server.csh
index 50b781a..935e8bb 100644
--- a/start-server.csh
+++ b/start-server.csh
@@ -1,6 +1,6 @@
#!/bin/csh
setenv EVENT_NOKQUEUE yes
-#./obfsproxy --log-min-severity=debug chop server 87.73.82.145:8080 127.0.0.1:8080 127.0.0.1:8081
+./obfsproxy --log-min-severity=debug chop server 87.73.82.145:8080 127.0.0.1:8080 127.0.0.1:8081
# ./obfsproxy --log-min-severity=warn chop server 87.73.82.145:8080 127.0.0.1:8080 127.0.0.1:8081
-./obfsproxy --log-min-severity=error chop server 87.73.82.145:8080 127.0.0.1:8080 127.0.0.1:8081
+#./obfsproxy --log-min-severity=error chop server 87.73.82.145:8080 127.0.0.1:8080 127.0.0.1:8081
1
0
commit 47fb64a72ab5c8503c2a35d970921c215238cdb5
Author: Vinod Yegneswaran <vinod(a)csl.sri.com>
Date: Tue Nov 1 06:17:28 2011 +0000
enabled jskeyword skip
git-svn-id: svn+ssh://spartan.csl.sri.com/svn/private/DEFIANCE@112 a58ff0ac-194c-e011-a152-003048836090
---
src/steg/payloads.c | 58 ++++++++++++++++++++++++--------------------------
1 files changed, 28 insertions(+), 30 deletions(-)
diff --git a/src/steg/payloads.c b/src/steg/payloads.c
index 2782aa6..8d0b8fe 100644
--- a/src/steg/payloads.c
+++ b/src/steg/payloads.c
@@ -454,11 +454,9 @@ unsigned int find_client_payload(char* buf, int len, int type) {
pentry_header* p = &payload_hdrs[r];
if (p->ptype == type) {
inbuf = payloads[r];
- if (find_uri_type(inbuf) != HTTP_CONTENT_SWF &&
+ if (find_uri_type(inbuf) != HTTP_CONTENT_SWF &&
find_uri_type(inbuf) != HTTP_CONTENT_JAVASCRIPT)
-
goto next;
-
if (p->length > len) {
fprintf(stderr, "BUFFER TOO SMALL... \n");
goto next;
@@ -497,7 +495,7 @@ unsigned int find_client_payload(char* buf, int len, int type) {
int skipJSPattern (char *cp, int len) {
// log_debug("Turning off skipJSPattern for debugging");
- return 0;
+ // return 0;
if (len < 1) return 0;
@@ -575,6 +573,8 @@ int offset2Alnum_ (char *p, int range) {
}
}
+
+
/*
* offset2Hex returns the offset to the next usable hex char.
* usable here refer to char that our steg module can use to encode
@@ -608,15 +608,13 @@ int offset2Hex (char *p, int range, int isLastCharHex) {
if (isLastCharHex) {
if (isxdigit(*cp)) return 0; // base case
else {
- cp++;
- i = offset2Alnum_(cp, p+range-cp);
- while (i == 0) {
- if (isxdigit(*cp)) return (cp-p);
+ while (cp < (p+range) && isalnum_(*cp)) {
cp++;
- i = offset2Alnum_(cp, p+range-cp);
+ if (isxdigit(*cp)) return (cp-p);
}
- if (i == -1) return -1;
- // if (i > 0), fallthru and handle case 2
+ if (cp >= (p+range)) return -1;
+ // non-alnum_ found
+ // fallthru and handle case 2
}
}
@@ -626,29 +624,29 @@ int offset2Hex (char *p, int range, int isLastCharHex) {
i = offset2Alnum_(cp, p+range-cp);
if (i == -1) return -1;
- // isFirstWordChar = 1;
while (cp < (p+range) && i != -1) {
-
- if (i == 0) {
- j = skipJSPattern(cp, p+range-cp);
- if (j > 0) {
- // cp points a word that should not be used (e.g., JS keyword)
- cp = cp+j; isFirstWordChar = 1;
- } else { // j == 0
- if (isFirstWordChar) {
+
+ if (i == 0) {
+ if (isFirstWordChar) {
+ j = skipJSPattern(cp, p+range-cp);
+ if (j > 0) {
+ cp = cp+j;
+ } else {
cp++; isFirstWordChar = 0; // skip the 1st char of a word
- }
- else { // we are in the middle of a word; no need to invoke skipJSPattern
- if (isxdigit(*cp)) return (cp-p);
- else cp++;
}
- }
- } else { // i > 0
- cp += i; isFirstWordChar = 1;
- }
- i = offset2Alnum_(cp, p+range-cp);
-
+ } else { // we are in the middle of a word; no need to invoke skipJSPattern
+ if (isxdigit(*cp)) return (cp-p);
+ if (! isalnum_(*cp)) {
+ isFirstWordChar = 1;
+ }
+ cp++;
+ }
+ } else {
+ cp += i; isFirstWordChar = 1;
+ }
+ i = offset2Alnum_(cp, p+range-cp);
+
} // while
// cannot find next usable hex char
1
0