deflate-ruby 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +95 -92
  3. data/LICENSE.txt +6 -6
  4. data/README.md +87 -65
  5. data/Rakefile +23 -0
  6. data/ext/deflate_ruby/{libdeflate/lib/x86/adler32_impl.h → adler32_impl.h} +8 -7
  7. data/ext/deflate_ruby/common_defs.h +748 -0
  8. data/ext/deflate_ruby/{libdeflate/lib/x86/cpu_features.c → cpu_features.c} +46 -16
  9. data/ext/deflate_ruby/{libdeflate/lib/x86/cpu_features.h → cpu_features.h} +2 -1
  10. data/ext/deflate_ruby/{libdeflate/lib/x86/crc32_impl.h → crc32_impl.h} +22 -23
  11. data/ext/deflate_ruby/{libdeflate/lib/crc32_multipliers.h → crc32_multipliers.h} +2 -4
  12. data/ext/deflate_ruby/{libdeflate/lib/x86/crc32_pclmul_template.h → crc32_pclmul_template.h} +23 -94
  13. data/ext/deflate_ruby/{libdeflate/lib/crc32_tables.h → crc32_tables.h} +1 -1
  14. data/ext/deflate_ruby/{libdeflate/lib/deflate_compress.c → deflate_compress.c} +59 -60
  15. data/ext/deflate_ruby/deflate_ruby.c +392 -218
  16. data/ext/deflate_ruby/deflate_ruby.h +6 -0
  17. data/ext/deflate_ruby/extconf.rb +35 -25
  18. data/ext/deflate_ruby/libdeflate/adler32.c +162 -0
  19. data/ext/deflate_ruby/libdeflate/{lib/arm → arm}/adler32_impl.h +14 -7
  20. data/ext/deflate_ruby/libdeflate/{lib/arm → arm}/crc32_impl.h +25 -31
  21. data/ext/deflate_ruby/libdeflate/arm/crc32_pmull_helpers.h +156 -0
  22. data/ext/deflate_ruby/libdeflate/arm/crc32_pmull_wide.h +226 -0
  23. data/ext/deflate_ruby/libdeflate/bt_matchfinder.h +342 -0
  24. data/ext/deflate_ruby/libdeflate/common_defs.h +2 -1
  25. data/ext/deflate_ruby/libdeflate/cpu_features_common.h +93 -0
  26. data/ext/deflate_ruby/libdeflate/crc32.c +262 -0
  27. data/ext/deflate_ruby/libdeflate/crc32_multipliers.h +375 -0
  28. data/ext/deflate_ruby/libdeflate/crc32_tables.h +587 -0
  29. data/ext/deflate_ruby/libdeflate/decompress_template.h +777 -0
  30. data/ext/deflate_ruby/libdeflate/deflate_compress.c +4128 -0
  31. data/ext/deflate_ruby/libdeflate/deflate_compress.h +15 -0
  32. data/ext/deflate_ruby/libdeflate/deflate_constants.h +56 -0
  33. data/ext/deflate_ruby/libdeflate/deflate_decompress.c +1208 -0
  34. data/ext/deflate_ruby/libdeflate/gzip_compress.c +90 -0
  35. data/ext/deflate_ruby/libdeflate/gzip_constants.h +45 -0
  36. data/ext/deflate_ruby/libdeflate/gzip_decompress.c +144 -0
  37. data/ext/deflate_ruby/libdeflate/hc_matchfinder.h +401 -0
  38. data/ext/deflate_ruby/libdeflate/ht_matchfinder.h +234 -0
  39. data/ext/deflate_ruby/libdeflate/lib_common.h +106 -0
  40. data/ext/deflate_ruby/libdeflate/libdeflate.h +2 -2
  41. data/ext/deflate_ruby/libdeflate/{lib/matchfinder_common.h → matchfinder_common.h} +3 -3
  42. data/ext/deflate_ruby/libdeflate/x86/adler32_impl.h +135 -0
  43. data/ext/deflate_ruby/libdeflate/x86/adler32_template.h +518 -0
  44. data/ext/deflate_ruby/libdeflate/x86/cpu_features.c +213 -0
  45. data/ext/deflate_ruby/libdeflate/x86/cpu_features.h +170 -0
  46. data/ext/deflate_ruby/libdeflate/x86/crc32_impl.h +159 -0
  47. data/ext/deflate_ruby/libdeflate/x86/crc32_pclmul_template.h +424 -0
  48. data/ext/deflate_ruby/libdeflate/x86/decompress_impl.h +57 -0
  49. data/ext/deflate_ruby/libdeflate.h +411 -0
  50. data/ext/deflate_ruby/matchfinder_common.h +224 -0
  51. data/ext/deflate_ruby/matchfinder_impl.h +122 -0
  52. data/ext/deflate_ruby/utils.c +141 -0
  53. data/ext/deflate_ruby/zlib_compress.c +82 -0
  54. data/ext/deflate_ruby/zlib_constants.h +21 -0
  55. data/ext/deflate_ruby/zlib_decompress.c +104 -0
  56. data/lib/deflate_ruby/version.rb +1 -1
  57. data/lib/deflate_ruby.rb +1 -63
  58. data/sig/deflate_ruby.rbs +4 -0
  59. data/test/test_deflate_ruby.rb +220 -0
  60. data/test/test_helper.rb +6 -0
  61. metadata +89 -144
  62. data/ext/deflate_ruby/libdeflate/CMakeLists.txt +0 -270
  63. data/ext/deflate_ruby/libdeflate/NEWS.md +0 -494
  64. data/ext/deflate_ruby/libdeflate/README.md +0 -228
  65. data/ext/deflate_ruby/libdeflate/libdeflate-config.cmake.in +0 -3
  66. data/ext/deflate_ruby/libdeflate/libdeflate.pc.in +0 -18
  67. data/ext/deflate_ruby/libdeflate/programs/CMakeLists.txt +0 -105
  68. data/ext/deflate_ruby/libdeflate/programs/benchmark.c +0 -696
  69. data/ext/deflate_ruby/libdeflate/programs/checksum.c +0 -218
  70. data/ext/deflate_ruby/libdeflate/programs/config.h.in +0 -19
  71. data/ext/deflate_ruby/libdeflate/programs/gzip.c +0 -688
  72. data/ext/deflate_ruby/libdeflate/programs/prog_util.c +0 -521
  73. data/ext/deflate_ruby/libdeflate/programs/prog_util.h +0 -225
  74. data/ext/deflate_ruby/libdeflate/programs/test_checksums.c +0 -200
  75. data/ext/deflate_ruby/libdeflate/programs/test_custom_malloc.c +0 -155
  76. data/ext/deflate_ruby/libdeflate/programs/test_incomplete_codes.c +0 -385
  77. data/ext/deflate_ruby/libdeflate/programs/test_invalid_streams.c +0 -130
  78. data/ext/deflate_ruby/libdeflate/programs/test_litrunlen_overflow.c +0 -72
  79. data/ext/deflate_ruby/libdeflate/programs/test_overread.c +0 -95
  80. data/ext/deflate_ruby/libdeflate/programs/test_slow_decompression.c +0 -472
  81. data/ext/deflate_ruby/libdeflate/programs/test_trailing_bytes.c +0 -151
  82. data/ext/deflate_ruby/libdeflate/programs/test_util.c +0 -237
  83. data/ext/deflate_ruby/libdeflate/programs/test_util.h +0 -61
  84. data/ext/deflate_ruby/libdeflate/programs/tgetopt.c +0 -118
  85. data/ext/deflate_ruby/libdeflate/scripts/android_build.sh +0 -118
  86. data/ext/deflate_ruby/libdeflate/scripts/android_tests.sh +0 -69
  87. data/ext/deflate_ruby/libdeflate/scripts/benchmark.sh +0 -10
  88. data/ext/deflate_ruby/libdeflate/scripts/checksum.sh +0 -10
  89. data/ext/deflate_ruby/libdeflate/scripts/checksum_benchmarks.sh +0 -253
  90. data/ext/deflate_ruby/libdeflate/scripts/cmake-helper.sh +0 -17
  91. data/ext/deflate_ruby/libdeflate/scripts/deflate_benchmarks.sh +0 -119
  92. data/ext/deflate_ruby/libdeflate/scripts/exec_tests.sh +0 -38
  93. data/ext/deflate_ruby/libdeflate/scripts/gen-release-archives.sh +0 -37
  94. data/ext/deflate_ruby/libdeflate/scripts/gen_bitreverse_tab.py +0 -19
  95. data/ext/deflate_ruby/libdeflate/scripts/gen_crc32_multipliers.c +0 -199
  96. data/ext/deflate_ruby/libdeflate/scripts/gen_crc32_tables.c +0 -105
  97. data/ext/deflate_ruby/libdeflate/scripts/gen_default_litlen_costs.py +0 -44
  98. data/ext/deflate_ruby/libdeflate/scripts/gen_offset_slot_map.py +0 -29
  99. data/ext/deflate_ruby/libdeflate/scripts/gzip_tests.sh +0 -523
  100. data/ext/deflate_ruby/libdeflate/scripts/libFuzzer/deflate_compress/corpus/0 +0 -0
  101. data/ext/deflate_ruby/libdeflate/scripts/libFuzzer/deflate_compress/fuzz.c +0 -95
  102. data/ext/deflate_ruby/libdeflate/scripts/libFuzzer/deflate_decompress/corpus/0 +0 -3
  103. data/ext/deflate_ruby/libdeflate/scripts/libFuzzer/deflate_decompress/fuzz.c +0 -62
  104. data/ext/deflate_ruby/libdeflate/scripts/libFuzzer/fuzz.sh +0 -108
  105. data/ext/deflate_ruby/libdeflate/scripts/libFuzzer/gzip_decompress/corpus/0 +0 -0
  106. data/ext/deflate_ruby/libdeflate/scripts/libFuzzer/gzip_decompress/fuzz.c +0 -19
  107. data/ext/deflate_ruby/libdeflate/scripts/libFuzzer/zlib_decompress/corpus/0 +0 -3
  108. data/ext/deflate_ruby/libdeflate/scripts/libFuzzer/zlib_decompress/fuzz.c +0 -19
  109. data/ext/deflate_ruby/libdeflate/scripts/run_tests.sh +0 -416
  110. data/ext/deflate_ruby/libdeflate/scripts/toolchain-i686-w64-mingw32.cmake +0 -8
  111. data/ext/deflate_ruby/libdeflate/scripts/toolchain-x86_64-w64-mingw32.cmake +0 -8
  112. /data/ext/deflate_ruby/{libdeflate/lib/adler32.c → adler32.c} +0 -0
  113. /data/ext/deflate_ruby/{libdeflate/lib/x86/adler32_template.h → adler32_template.h} +0 -0
  114. /data/ext/deflate_ruby/{libdeflate/lib/bt_matchfinder.h → bt_matchfinder.h} +0 -0
  115. /data/ext/deflate_ruby/{libdeflate/lib/cpu_features_common.h → cpu_features_common.h} +0 -0
  116. /data/ext/deflate_ruby/{libdeflate/lib/crc32.c → crc32.c} +0 -0
  117. /data/ext/deflate_ruby/{libdeflate/lib/arm/crc32_pmull_helpers.h → crc32_pmull_helpers.h} +0 -0
  118. /data/ext/deflate_ruby/{libdeflate/lib/arm/crc32_pmull_wide.h → crc32_pmull_wide.h} +0 -0
  119. /data/ext/deflate_ruby/{libdeflate/lib/x86/decompress_impl.h → decompress_impl.h} +0 -0
  120. /data/ext/deflate_ruby/{libdeflate/lib/decompress_template.h → decompress_template.h} +0 -0
  121. /data/ext/deflate_ruby/{libdeflate/lib/deflate_compress.h → deflate_compress.h} +0 -0
  122. /data/ext/deflate_ruby/{libdeflate/lib/deflate_constants.h → deflate_constants.h} +0 -0
  123. /data/ext/deflate_ruby/{libdeflate/lib/deflate_decompress.c → deflate_decompress.c} +0 -0
  124. /data/ext/deflate_ruby/{libdeflate/lib/gzip_compress.c → gzip_compress.c} +0 -0
  125. /data/ext/deflate_ruby/{libdeflate/lib/gzip_constants.h → gzip_constants.h} +0 -0
  126. /data/ext/deflate_ruby/{libdeflate/lib/gzip_decompress.c → gzip_decompress.c} +0 -0
  127. /data/ext/deflate_ruby/{libdeflate/lib/hc_matchfinder.h → hc_matchfinder.h} +0 -0
  128. /data/ext/deflate_ruby/{libdeflate/lib/ht_matchfinder.h → ht_matchfinder.h} +0 -0
  129. /data/ext/deflate_ruby/{libdeflate/lib/lib_common.h → lib_common.h} +0 -0
  130. /data/ext/deflate_ruby/libdeflate/{lib/arm → arm}/cpu_features.c +0 -0
  131. /data/ext/deflate_ruby/libdeflate/{lib/arm → arm}/cpu_features.h +0 -0
  132. /data/ext/deflate_ruby/libdeflate/{lib/arm → arm}/matchfinder_impl.h +0 -0
  133. /data/ext/deflate_ruby/libdeflate/{lib/riscv → riscv}/matchfinder_impl.h +0 -0
  134. /data/ext/deflate_ruby/libdeflate/{lib/utils.c → utils.c} +0 -0
  135. /data/ext/deflate_ruby/libdeflate/{lib/x86 → x86}/matchfinder_impl.h +0 -0
  136. /data/ext/deflate_ruby/libdeflate/{lib/zlib_compress.c → zlib_compress.c} +0 -0
  137. /data/ext/deflate_ruby/libdeflate/{lib/zlib_constants.h → zlib_constants.h} +0 -0
  138. /data/ext/deflate_ruby/libdeflate/{lib/zlib_decompress.c → zlib_decompress.c} +0 -0
@@ -1,385 +0,0 @@
1
- /*
2
- * test_incomplete_codes.c
3
- *
4
- * Test that the decompressor accepts incomplete Huffman codes in certain
5
- * specific cases.
6
- */
7
-
8
- #include "test_util.h"
9
-
10
- static void
11
- verify_decompression_libdeflate(const u8 *in, size_t in_nbytes,
12
- u8 *out, size_t out_nbytes_avail,
13
- const u8 *expected_out,
14
- size_t expected_out_nbytes)
15
- {
16
- struct libdeflate_decompressor *d;
17
- enum libdeflate_result res;
18
- size_t actual_out_nbytes;
19
-
20
- d = libdeflate_alloc_decompressor();
21
- ASSERT(d != NULL);
22
-
23
- res = libdeflate_deflate_decompress(d, in, in_nbytes,
24
- out, out_nbytes_avail,
25
- &actual_out_nbytes);
26
- ASSERT(res == LIBDEFLATE_SUCCESS);
27
- ASSERT(actual_out_nbytes == expected_out_nbytes);
28
- ASSERT(memcmp(out, expected_out, actual_out_nbytes) == 0);
29
-
30
- libdeflate_free_decompressor(d);
31
- }
32
-
33
- static void
34
- verify_decompression_zlib(const u8 *in, size_t in_nbytes,
35
- u8 *out, size_t out_nbytes_avail,
36
- const u8 *expected_out, size_t expected_out_nbytes)
37
- {
38
- z_stream z;
39
- int res;
40
- size_t actual_out_nbytes;
41
-
42
- memset(&z, 0, sizeof(z));
43
- res = inflateInit2(&z, -15);
44
- ASSERT(res == Z_OK);
45
-
46
- z.next_in = (void *)in;
47
- z.avail_in = in_nbytes;
48
- z.next_out = (void *)out;
49
- z.avail_out = out_nbytes_avail;
50
- res = inflate(&z, Z_FINISH);
51
- ASSERT(res == Z_STREAM_END);
52
- actual_out_nbytes = out_nbytes_avail - z.avail_out;
53
- ASSERT(actual_out_nbytes == expected_out_nbytes);
54
- ASSERT(memcmp(out, expected_out, actual_out_nbytes) == 0);
55
-
56
- inflateEnd(&z);
57
- }
58
-
59
- static void
60
- verify_decompression(const u8 *in, size_t in_nbytes,
61
- u8 *out, size_t out_nbytes_avail,
62
- const u8 *expected_out, size_t expected_out_nbytes)
63
- {
64
- verify_decompression_libdeflate(in, in_nbytes, out, out_nbytes_avail,
65
- expected_out, expected_out_nbytes);
66
- verify_decompression_zlib(in, in_nbytes, out, out_nbytes_avail,
67
- expected_out, expected_out_nbytes);
68
-
69
- }
70
-
71
- /* Test that an empty offset code is accepted. */
72
- static void
73
- test_empty_offset_code(void)
74
- {
75
- static const u8 expected_out[] = { 'A', 'B', 'A', 'A' };
76
- u8 in[128];
77
- u8 out[128];
78
- struct output_bitstream os = { .next = in, .end = in + sizeof(in) };
79
- int i;
80
-
81
- /*
82
- * Generate a DEFLATE stream containing a "dynamic Huffman" block
83
- * containing literals, but no offsets; and having an empty offset code
84
- * (all codeword lengths set to 0).
85
- *
86
- * Litlen code:
87
- * litlensym_A freq=3 len=1 codeword= 0
88
- * litlensym_B freq=1 len=2 codeword=01
89
- * litlensym_256 (end-of-block) freq=1 len=2 codeword=11
90
- * Offset code:
91
- * (empty)
92
- *
93
- * Litlen and offset codeword lengths:
94
- * [0..'A'-1] = 0 presym_18
95
- * ['A'] = 1 presym_1
96
- * ['B'] = 2 presym_2
97
- * ['B'+1..255] = 0 presym_18 presym_18
98
- * [256] = 2 presym_2
99
- * [257] = 0 presym_0
100
- *
101
- * Precode:
102
- * presym_0 freq=1 len=3 codeword=011
103
- * presym_1 freq=1 len=3 codeword=111
104
- * presym_2 freq=2 len=2 codeword= 01
105
- * presym_18 freq=3 len=1 codeword= 0
106
- */
107
-
108
- ASSERT(put_bits(&os, 1, 1)); /* BFINAL: 1 */
109
- ASSERT(put_bits(&os, 2, 2)); /* BTYPE: DYNAMIC_HUFFMAN */
110
- ASSERT(put_bits(&os, 0, 5)); /* num_litlen_syms: 0 + 257 */
111
- ASSERT(put_bits(&os, 0, 5)); /* num_offset_syms: 0 + 1 */
112
- ASSERT(put_bits(&os, 14, 4)); /* num_explicit_precode_lens: 14 + 4 */
113
-
114
- /*
115
- * Precode codeword lengths: order is
116
- * [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]
117
- */
118
- for (i = 0; i < 2; i++) /* presym_{16,17}: len=0 */
119
- ASSERT(put_bits(&os, 0, 3));
120
- ASSERT(put_bits(&os, 1, 3)); /* presym_18: len=1 */
121
- ASSERT(put_bits(&os, 3, 3)); /* presym_0: len=3 */
122
- for (i = 0; i < 11; i++) /* presym_{8,...,13}: len=0 */
123
- ASSERT(put_bits(&os, 0, 3));
124
- ASSERT(put_bits(&os, 2, 3)); /* presym_2: len=2 */
125
- ASSERT(put_bits(&os, 0, 3)); /* presym_14: len=0 */
126
- ASSERT(put_bits(&os, 3, 3)); /* presym_1: len=3 */
127
-
128
- /* Litlen and offset codeword lengths */
129
- ASSERT(put_bits(&os, 0x0, 1) &&
130
- put_bits(&os, 54, 7)); /* presym_18, 65 zeroes */
131
- ASSERT(put_bits(&os, 0x7, 3)); /* presym_1 */
132
- ASSERT(put_bits(&os, 0x1, 2)); /* presym_2 */
133
- ASSERT(put_bits(&os, 0x0, 1) &&
134
- put_bits(&os, 89, 7)); /* presym_18, 100 zeroes */
135
- ASSERT(put_bits(&os, 0x0, 1) &&
136
- put_bits(&os, 78, 7)); /* presym_18, 89 zeroes */
137
- ASSERT(put_bits(&os, 0x1, 2)); /* presym_2 */
138
- ASSERT(put_bits(&os, 0x3, 3)); /* presym_0 */
139
-
140
- /* Litlen symbols */
141
- ASSERT(put_bits(&os, 0x0, 1)); /* litlensym_A */
142
- ASSERT(put_bits(&os, 0x1, 2)); /* litlensym_B */
143
- ASSERT(put_bits(&os, 0x0, 1)); /* litlensym_A */
144
- ASSERT(put_bits(&os, 0x0, 1)); /* litlensym_A */
145
- ASSERT(put_bits(&os, 0x3, 2)); /* litlensym_256 (end-of-block) */
146
-
147
- ASSERT(flush_bits(&os));
148
-
149
- verify_decompression(in, os.next - in, out, sizeof(out),
150
- expected_out, sizeof(expected_out));
151
- }
152
-
153
- /* Test that a litrunlen code containing only one symbol is accepted. */
154
- static void
155
- test_singleton_litrunlen_code(void)
156
- {
157
- u8 in[128];
158
- u8 out[128];
159
- struct output_bitstream os = { .next = in, .end = in + sizeof(in) };
160
- int i;
161
-
162
- /*
163
- * Litlen code:
164
- * litlensym_256 (end-of-block) freq=1 len=1 codeword=0
165
- * Offset code:
166
- * (empty)
167
- *
168
- * Litlen and offset codeword lengths:
169
- * [0..256] = 0 presym_18 presym_18
170
- * [256] = 1 presym_1
171
- * [257] = 0 presym_0
172
- *
173
- * Precode:
174
- * presym_0 freq=1 len=2 codeword=01
175
- * presym_1 freq=1 len=2 codeword=11
176
- * presym_18 freq=2 len=1 codeword= 0
177
- */
178
-
179
- ASSERT(put_bits(&os, 1, 1)); /* BFINAL: 1 */
180
- ASSERT(put_bits(&os, 2, 2)); /* BTYPE: DYNAMIC_HUFFMAN */
181
- ASSERT(put_bits(&os, 0, 5)); /* num_litlen_syms: 0 + 257 */
182
- ASSERT(put_bits(&os, 0, 5)); /* num_offset_syms: 0 + 1 */
183
- ASSERT(put_bits(&os, 14, 4)); /* num_explicit_precode_lens: 14 + 4 */
184
-
185
- /*
186
- * Precode codeword lengths: order is
187
- * [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]
188
- */
189
- for (i = 0; i < 2; i++) /* presym_{16,17}: len=0 */
190
- ASSERT(put_bits(&os, 0, 3));
191
- ASSERT(put_bits(&os, 1, 3)); /* presym_18: len=1 */
192
- ASSERT(put_bits(&os, 2, 3)); /* presym_0: len=2 */
193
- for (i = 0; i < 13; i++) /* presym_{8,...,14}: len=0 */
194
- ASSERT(put_bits(&os, 0, 3));
195
- ASSERT(put_bits(&os, 2, 3)); /* presym_1: len=2 */
196
-
197
- /* Litlen and offset codeword lengths */
198
- for (i = 0; i < 2; i++) {
199
- ASSERT(put_bits(&os, 0, 1) && /* presym_18, 128 zeroes */
200
- put_bits(&os, 117, 7));
201
- }
202
- ASSERT(put_bits(&os, 0x3, 2)); /* presym_1 */
203
- ASSERT(put_bits(&os, 0x1, 2)); /* presym_0 */
204
-
205
- /* Litlen symbols */
206
- ASSERT(put_bits(&os, 0x0, 1)); /* litlensym_256 (end-of-block) */
207
-
208
- ASSERT(flush_bits(&os));
209
-
210
- verify_decompression(in, os.next - in, out, sizeof(out), in, 0);
211
- }
212
-
213
- /* Test that an offset code containing only one symbol is accepted. */
214
- static void
215
- test_singleton_offset_code(void)
216
- {
217
- static const u8 expected_out[] = { 255, 255, 255, 255 };
218
- u8 in[128];
219
- u8 out[128];
220
- struct output_bitstream os = { .next = in, .end = in + sizeof(in) };
221
- int i;
222
-
223
- ASSERT(put_bits(&os, 1, 1)); /* BFINAL: 1 */
224
- ASSERT(put_bits(&os, 2, 2)); /* BTYPE: DYNAMIC_HUFFMAN */
225
-
226
- /*
227
- * Litlen code:
228
- * litlensym_255 freq=1 len=1 codeword= 0
229
- * litlensym_256 (end-of-block) freq=1 len=2 codeword=01
230
- * litlensym_257 (len 3) freq=1 len=2 codeword=11
231
- * Offset code:
232
- * offsetsym_0 (offset 0) freq=1 len=1 codeword=0
233
- *
234
- * Litlen and offset codeword lengths:
235
- * [0..254] = 0 presym_{18,18}
236
- * [255] = 1 presym_1
237
- * [256] = 1 presym_2
238
- * [257] = 1 presym_2
239
- * [258] = 1 presym_1
240
- *
241
- * Precode:
242
- * presym_1 freq=2 len=2 codeword=01
243
- * presym_2 freq=2 len=2 codeword=11
244
- * presym_18 freq=2 len=1 codeword= 0
245
- */
246
-
247
- ASSERT(put_bits(&os, 1, 5)); /* num_litlen_syms: 1 + 257 */
248
- ASSERT(put_bits(&os, 0, 5)); /* num_offset_syms: 0 + 1 */
249
- ASSERT(put_bits(&os, 14, 4)); /* num_explicit_precode_lens: 14 + 4 */
250
- /*
251
- * Precode codeword lengths: order is
252
- * [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]
253
- */
254
- for (i = 0; i < 2; i++) /* presym_{16,17}: len=0 */
255
- ASSERT(put_bits(&os, 0, 3));
256
- ASSERT(put_bits(&os, 1, 3)); /* presym_18: len=1 */
257
- for (i = 0; i < 12; i++) /* presym_{0,...,13}: len=0 */
258
- ASSERT(put_bits(&os, 0, 3));
259
- ASSERT(put_bits(&os, 2, 3)); /* presym_2: len=2 */
260
- ASSERT(put_bits(&os, 0, 3)); /* presym_14: len=0 */
261
- ASSERT(put_bits(&os, 2, 3)); /* presym_1: len=2 */
262
-
263
- /* Litlen and offset codeword lengths */
264
- ASSERT(put_bits(&os, 0x0, 1) && /* presym_18, 128 zeroes */
265
- put_bits(&os, 117, 7));
266
- ASSERT(put_bits(&os, 0x0, 1) && /* presym_18, 127 zeroes */
267
- put_bits(&os, 116, 7));
268
- ASSERT(put_bits(&os, 0x1, 2)); /* presym_1 */
269
- ASSERT(put_bits(&os, 0x3, 2)); /* presym_2 */
270
- ASSERT(put_bits(&os, 0x3, 2)); /* presym_2 */
271
- ASSERT(put_bits(&os, 0x1, 2)); /* presym_1 */
272
-
273
- /* Literal */
274
- ASSERT(put_bits(&os, 0x0, 1)); /* litlensym_255 */
275
-
276
- /* Match */
277
- ASSERT(put_bits(&os, 0x3, 2)); /* litlensym_257 */
278
- ASSERT(put_bits(&os, 0x0, 1)); /* offsetsym_0 */
279
-
280
- /* End of block */
281
- ASSERT(put_bits(&os, 0x1, 2)); /* litlensym_256 */
282
-
283
- ASSERT(flush_bits(&os));
284
-
285
- verify_decompression(in, os.next - in, out, sizeof(out),
286
- expected_out, sizeof(expected_out));
287
- }
288
-
289
- /* Test that an offset code containing only one symbol is accepted, even if that
290
- * symbol is not symbol 0. The codeword should be '0' in either case. */
291
- static void
292
- test_singleton_offset_code_notsymzero(void)
293
- {
294
- static const u8 expected_out[] = { 254, 255, 254, 255, 254 };
295
- u8 in[128];
296
- u8 out[128];
297
- struct output_bitstream os = { .next = in, .end = in + sizeof(in) };
298
- int i;
299
-
300
- ASSERT(put_bits(&os, 1, 1)); /* BFINAL: 1 */
301
- ASSERT(put_bits(&os, 2, 2)); /* BTYPE: DYNAMIC_HUFFMAN */
302
-
303
- /*
304
- * Litlen code:
305
- * litlensym_254 len=2 codeword=00
306
- * litlensym_255 len=2 codeword=10
307
- * litlensym_256 (end-of-block) len=2 codeword=01
308
- * litlensym_257 (len 3) len=2 codeword=11
309
- * Offset code:
310
- * offsetsym_1 (offset 2) len=1 codeword=0
311
- *
312
- * Litlen and offset codeword lengths:
313
- * [0..253] = 0 presym_{18,18}
314
- * [254] = 2 presym_2
315
- * [255] = 2 presym_2
316
- * [256] = 2 presym_2
317
- * [257] = 2 presym_2
318
- * [258] = 0 presym_0
319
- * [259] = 1 presym_1
320
- *
321
- * Precode:
322
- * presym_0 len=2 codeword=00
323
- * presym_1 len=2 codeword=10
324
- * presym_2 len=2 codeword=01
325
- * presym_18 len=2 codeword=11
326
- */
327
-
328
- ASSERT(put_bits(&os, 1, 5)); /* num_litlen_syms: 1 + 257 */
329
- ASSERT(put_bits(&os, 1, 5)); /* num_offset_syms: 1 + 1 */
330
- ASSERT(put_bits(&os, 14, 4)); /* num_explicit_precode_lens: 14 + 4 */
331
- /*
332
- * Precode codeword lengths: order is
333
- * [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]
334
- */
335
- for (i = 0; i < 2; i++) /* presym_{16,17}: len=0 */
336
- ASSERT(put_bits(&os, 0, 3));
337
- ASSERT(put_bits(&os, 2, 3)); /* presym_18: len=2 */
338
- ASSERT(put_bits(&os, 2, 3)); /* presym_0: len=2 */
339
- for (i = 0; i < 11; i++) /* presym_{8,...,13}: len=0 */
340
- ASSERT(put_bits(&os, 0, 3));
341
- ASSERT(put_bits(&os, 2, 3)); /* presym_2: len=2 */
342
- ASSERT(put_bits(&os, 0, 3)); /* presym_14: len=0 */
343
- ASSERT(put_bits(&os, 2, 3)); /* presym_1: len=2 */
344
-
345
- /* Litlen and offset codeword lengths */
346
- ASSERT(put_bits(&os, 0x3, 2) && /* presym_18, 128 zeroes */
347
- put_bits(&os, 117, 7));
348
- ASSERT(put_bits(&os, 0x3, 2) && /* presym_18, 126 zeroes */
349
- put_bits(&os, 115, 7));
350
- ASSERT(put_bits(&os, 0x1, 2)); /* presym_2 */
351
- ASSERT(put_bits(&os, 0x1, 2)); /* presym_2 */
352
- ASSERT(put_bits(&os, 0x1, 2)); /* presym_2 */
353
- ASSERT(put_bits(&os, 0x1, 2)); /* presym_2 */
354
- ASSERT(put_bits(&os, 0x0, 2)); /* presym_0 */
355
- ASSERT(put_bits(&os, 0x2, 2)); /* presym_1 */
356
-
357
- /* Literals */
358
- ASSERT(put_bits(&os, 0x0, 2)); /* litlensym_254 */
359
- ASSERT(put_bits(&os, 0x2, 2)); /* litlensym_255 */
360
-
361
- /* Match */
362
- ASSERT(put_bits(&os, 0x3, 2)); /* litlensym_257 */
363
- ASSERT(put_bits(&os, 0x0, 1)); /* offsetsym_1 */
364
-
365
- /* End of block */
366
- ASSERT(put_bits(&os, 0x1, 2)); /* litlensym_256 */
367
-
368
- ASSERT(flush_bits(&os));
369
-
370
- verify_decompression(in, os.next - in, out, sizeof(out),
371
- expected_out, sizeof(expected_out));
372
- }
373
-
374
- int
375
- tmain(int argc, tchar *argv[])
376
- {
377
- begin_program(argv);
378
-
379
- test_empty_offset_code();
380
- test_singleton_litrunlen_code();
381
- test_singleton_offset_code();
382
- test_singleton_offset_code_notsymzero();
383
-
384
- return 0;
385
- }
@@ -1,130 +0,0 @@
1
- /*
2
- * test_invalid_streams.c
3
- *
4
- * Test that invalid DEFLATE streams are rejected with LIBDEFLATE_BAD_DATA.
5
- *
6
- * This isn't actually very important, since DEFLATE doesn't have built-in error
7
- * detection, so corruption of a DEFLATE stream can only be reliably detected
8
- * using a separate checksum anyway. As long as the DEFLATE decompressor
9
- * handles all streams safely (no crashes, etc.), in practice it is fine for it
10
- * to automatically remap invalid streams to valid streams, instead of returning
11
- * an error. Corruption detection is the responsibility of the zlib or gzip
12
- * layer, or the application when an external checksum is used.
13
- *
14
- * Nevertheless, to reduce surprises when people intentionally compare zlib's
15
- * and libdeflate's handling of invalid DEFLATE streams, libdeflate implements
16
- * zlib's strict behavior when decoding DEFLATE, except when it would have a
17
- * significant performance cost.
18
- */
19
-
20
- #include "test_util.h"
21
-
22
- static void
23
- assert_decompression_error(const u8 *in, size_t in_nbytes)
24
- {
25
- struct libdeflate_decompressor *d;
26
- z_stream z;
27
- u8 out[128];
28
- const size_t out_nbytes_avail = sizeof(out);
29
- size_t actual_out_nbytes;
30
- enum libdeflate_result res;
31
-
32
- /* libdeflate */
33
- d = libdeflate_alloc_decompressor();
34
- ASSERT(d != NULL);
35
- res = libdeflate_deflate_decompress(d, in, in_nbytes,
36
- out, out_nbytes_avail,
37
- &actual_out_nbytes);
38
- ASSERT(res == LIBDEFLATE_BAD_DATA);
39
- libdeflate_free_decompressor(d);
40
-
41
- /* zlib, as a control */
42
- memset(&z, 0, sizeof(z));
43
- res = inflateInit2(&z, -15);
44
- ASSERT(res == Z_OK);
45
- z.next_in = (void *)in;
46
- z.avail_in = in_nbytes;
47
- z.next_out = (void *)out;
48
- z.avail_out = out_nbytes_avail;
49
- res = inflate(&z, Z_FINISH);
50
- ASSERT(res == Z_DATA_ERROR);
51
- inflateEnd(&z);
52
- }
53
-
54
- /*
55
- * Test that DEFLATE decompression returns an error if a block header contains
56
- * too many encoded litlen and offset codeword lengths.
57
- */
58
- static void
59
- test_too_many_codeword_lengths(void)
60
- {
61
- u8 in[128];
62
- struct output_bitstream os = { .next = in, .end = in + sizeof(in) };
63
- int i;
64
-
65
- ASSERT(put_bits(&os, 1, 1)); /* BFINAL: 1 */
66
- ASSERT(put_bits(&os, 2, 2)); /* BTYPE: DYNAMIC_HUFFMAN */
67
-
68
- /*
69
- * Litlen code:
70
- * litlensym_255 len=1 codeword=0
71
- * litlensym_256 (end-of-block) len=1 codeword=1
72
- * Offset code:
73
- * (empty)
74
- *
75
- * Litlen and offset codeword lengths:
76
- * [0..254] = 0 presym_{18,18}
77
- * [255] = 1 presym_1
78
- * [256] = 1 presym_1
79
- * [257...] = 0 presym_18 [TOO MANY]
80
- *
81
- * Precode:
82
- * presym_1 len=1 codeword=0
83
- * presym_18 len=1 codeword=1
84
- */
85
-
86
- ASSERT(put_bits(&os, 0, 5)); /* num_litlen_syms: 0 + 257 */
87
- ASSERT(put_bits(&os, 0, 5)); /* num_offset_syms: 0 + 1 */
88
- ASSERT(put_bits(&os, 14, 4)); /* num_explicit_precode_lens: 14 + 4 */
89
-
90
- /*
91
- * Precode codeword lengths: order is
92
- * [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]
93
- */
94
- for (i = 0; i < 2; i++) /* presym_{16,17}: len=0 */
95
- ASSERT(put_bits(&os, 0, 3));
96
- ASSERT(put_bits(&os, 1, 3)); /* presym_18: len=1 */
97
- ASSERT(put_bits(&os, 0, 3)); /* presym_0: len=0 */
98
- for (i = 0; i < 13; i++) /* presym_{8,...,14}: len=0 */
99
- ASSERT(put_bits(&os, 0, 3));
100
- ASSERT(put_bits(&os, 1, 3)); /* presym_1: len=1 */
101
-
102
- /* Litlen and offset codeword lengths */
103
- ASSERT(put_bits(&os, 0x1, 1) && /* presym_18, 128 zeroes */
104
- put_bits(&os, 117, 7));
105
- ASSERT(put_bits(&os, 0x1, 1) && /* presym_18, 127 zeroes */
106
- put_bits(&os, 116, 7));
107
- ASSERT(put_bits(&os, 0x0, 1)); /* presym_1 */
108
- ASSERT(put_bits(&os, 0x0, 1)); /* presym_1 */
109
- ASSERT(put_bits(&os, 0x1, 1) && /* presym_18, 128 zeroes [TOO MANY] */
110
- put_bits(&os, 117, 7));
111
-
112
- /* Literal */
113
- ASSERT(put_bits(&os, 0x0, 0)); /* litlensym_255 */
114
-
115
- /* End of block */
116
- ASSERT(put_bits(&os, 0x1, 1)); /* litlensym_256 */
117
-
118
- ASSERT(flush_bits(&os));
119
-
120
- assert_decompression_error(in, os.next - in);
121
- }
122
-
123
- int
124
- tmain(int argc, tchar *argv[])
125
- {
126
- begin_program(argv);
127
-
128
- test_too_many_codeword_lengths();
129
- return 0;
130
- }
@@ -1,72 +0,0 @@
1
- /*
2
- * test_litrunlen_overflow.c
3
- *
4
- * Regression test for commit f2f0df727444 ("deflate_compress: fix corruption
5
- * with long literal run"). Try to compress a file longer than 65535 bytes
6
- * where no 2-byte sequence (3 would be sufficient) is repeated <= 32768 bytes
7
- * apart, and the distribution of bytes remains constant throughout, and yet not
8
- * all bytes are used so the data is still slightly compressible. There will be
9
- * no matches in this data, but the compressor should still output a compressed
10
- * block, and this block should contain more than 65535 consecutive literals,
11
- * which triggered the bug.
12
- *
13
- * Note: on random data, this situation is extremely unlikely if the compressor
14
- * uses all matches it finds, since random data will on average have a 3-byte
15
- * match every (256**3)/32768 = 512 bytes.
16
- */
17
-
18
- #include "test_util.h"
19
-
20
- int
21
- tmain(int argc, tchar *argv[])
22
- {
23
- const int data_size = 2 * 250 * 251;
24
- u8 *orig_data, *compressed_data, *decompressed_data;
25
- int i, stride, multiple, j = 0;
26
- struct libdeflate_decompressor *d;
27
- static const int levels[] = { 3, 6, 12 };
28
-
29
- begin_program(argv);
30
-
31
- orig_data = xmalloc(data_size);
32
- compressed_data = xmalloc(data_size);
33
- decompressed_data = xmalloc(data_size);
34
-
35
- for (i = 0; i < 2; i++) {
36
- for (stride = 1; stride < 251; stride++) {
37
- for (multiple = 0; multiple < 251; multiple++)
38
- orig_data[j++] = (stride * multiple) % 251;
39
- }
40
- }
41
- ASSERT(j == data_size);
42
-
43
- d = libdeflate_alloc_decompressor();
44
- ASSERT(d != NULL);
45
-
46
- for (i = 0; i < ARRAY_LEN(levels); i++) {
47
- struct libdeflate_compressor *c;
48
- size_t csize;
49
- enum libdeflate_result res;
50
-
51
- c = libdeflate_alloc_compressor(levels[i]);
52
- ASSERT(c != NULL);
53
-
54
- csize = libdeflate_deflate_compress(c, orig_data, data_size,
55
- compressed_data, data_size);
56
- ASSERT(csize > 0 && csize < data_size);
57
-
58
- res = libdeflate_deflate_decompress(d, compressed_data, csize,
59
- decompressed_data,
60
- data_size, NULL);
61
- ASSERT(res == LIBDEFLATE_SUCCESS);
62
- ASSERT(memcmp(orig_data, decompressed_data, data_size) == 0);
63
-
64
- libdeflate_free_compressor(c);
65
- }
66
-
67
- libdeflate_free_decompressor(d);
68
- free(orig_data);
69
- free(compressed_data);
70
- free(decompressed_data);
71
- return 0;
72
- }
@@ -1,95 +0,0 @@
1
- /*
2
- * test_overread.c
3
- *
4
- * Test that the decompressor doesn't produce an unbounded amount of output if
5
- * it runs out of input, even when implicit zeroes appended to the input would
6
- * continue producing output (as is the case when the input ends during a
7
- * DYNAMIC_HUFFMAN block where a literal has an all-zeroes codeword).
8
- *
9
- * This is a regression test for commit 3f21ec9d6121 ("deflate_decompress: error
10
- * out if overread count gets too large").
11
- */
12
-
13
- #include "test_util.h"
14
-
15
- static void
16
- generate_test_input(struct output_bitstream *os)
17
- {
18
- int i;
19
-
20
- put_bits(os, 0, 1); /* BFINAL: 0 */
21
- put_bits(os, 2, 2); /* BTYPE: DYNAMIC_HUFFMAN */
22
-
23
- /*
24
- * Write the Huffman codes.
25
- *
26
- * Litlen code:
27
- * litlensym_0 (0) len=1 codeword=0
28
- * litlensym_256 (end-of-block) len=1 codeword=1
29
- * Offset code:
30
- * offsetsym_0 (unused) len=1 codeword=0
31
- *
32
- * Litlen and offset codeword lengths:
33
- * [0] = 1 presym_1
34
- * [1..255] = 0 presym_{18,18}
35
- * [256] = 1 presym_1
36
- * [257] = 1 presym_1
37
- *
38
- * Precode:
39
- * presym_1 len=1 codeword=0
40
- * presym_18 len=1 codeword=1
41
- */
42
- put_bits(os, 0, 5); /* num_litlen_syms: 0 + 257 */
43
- put_bits(os, 0, 5); /* num_offset_syms: 0 + 1 */
44
- put_bits(os, 14, 4); /* num_explicit_precode_lens: 14 + 4 */
45
- /*
46
- * Precode codeword lengths: order is
47
- * [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]
48
- */
49
- put_bits(os, 0, 3); /* presym_16: len=0 */
50
- put_bits(os, 0, 3); /* presym_17: len=0 */
51
- put_bits(os, 1, 3); /* presym_18: len=1 */
52
- for (i = 0; i < 14; i++) /* presym_{0,...,14}: len=0 */
53
- put_bits(os, 0, 3);
54
- put_bits(os, 1, 3); /* presym_1: len=1 */
55
-
56
- /* Litlen and offset codeword lengths */
57
- put_bits(os, 0, 1); /* presym_1 */
58
- put_bits(os, 1, 1); /* presym_18 ... */
59
- put_bits(os, 117, 7); /* ... 11 + 117 zeroes */
60
- put_bits(os, 1, 1); /* presym_18 ... */
61
- put_bits(os, 116, 7); /* ... 11 + 116 zeroes */
62
- put_bits(os, 0, 1); /* presym_1 */
63
- put_bits(os, 0, 1); /* presym_1 */
64
-
65
- /* Implicit zeroes would generate endless literals from here. */
66
-
67
- ASSERT(flush_bits(os));
68
- }
69
-
70
- int
71
- tmain(int argc, tchar *argv[])
72
- {
73
- u8 cdata[16];
74
- u8 udata[256];
75
- struct output_bitstream os =
76
- { .next = cdata, .end = cdata + sizeof(cdata) };
77
- struct libdeflate_decompressor *d;
78
- enum libdeflate_result res;
79
- size_t actual_out_nbytes;
80
-
81
- begin_program(argv);
82
-
83
- generate_test_input(&os);
84
- d = libdeflate_alloc_decompressor();
85
- ASSERT(d != NULL);
86
-
87
- res = libdeflate_deflate_decompress(d, cdata, os.next - cdata,
88
- udata, sizeof(udata),
89
- &actual_out_nbytes);
90
- /* Before the fix, the result was LIBDEFLATE_INSUFFICIENT_SPACE here. */
91
- ASSERT(res == LIBDEFLATE_BAD_DATA);
92
-
93
- libdeflate_free_decompressor(d);
94
- return 0;
95
- }