1 #include <stddef.h>
2 #include <stdint.h>
3 #include <stdlib.h> // malloc
4 #include <stdio.h>
5 #include <assert.h>
6
7 #include "zstd_seekable.h"
8
9 /* Basic unit tests for zstd seekable format */
main(int argc,const char ** argv)10 int main(int argc, const char** argv)
11 {
12 unsigned testNb = 1;
13 (void)argc; (void)argv;
14 printf("Beginning zstd seekable format tests...\n");
15
16 printf("Test %u - simple round trip: ", testNb++);
17 { size_t const inSize = 4000;
18 void* const inBuffer = malloc(inSize);
19 assert(inBuffer != NULL);
20
21 size_t const seekCapacity = 5000;
22 void* const seekBuffer = malloc(seekCapacity);
23 assert(seekBuffer != NULL);
24 size_t seekSize;
25
26 size_t const outCapacity = inSize;
27 void* const outBuffer = malloc(outCapacity);
28 assert(outBuffer != NULL);
29
30 ZSTD_seekable_CStream* const zscs = ZSTD_seekable_createCStream();
31 assert(zscs != NULL);
32
33 { size_t const initStatus = ZSTD_seekable_initCStream(zscs, 9, 0 /* checksumFlag */, (unsigned)inSize /* maxFrameSize */);
34 assert(!ZSTD_isError(initStatus));
35 }
36
37 { ZSTD_outBuffer outb = { .dst=seekBuffer, .pos=0, .size=seekCapacity };
38 ZSTD_inBuffer inb = { .src=inBuffer, .pos=0, .size=inSize };
39
40 size_t const cStatus = ZSTD_seekable_compressStream(zscs, &outb, &inb);
41 assert(!ZSTD_isError(cStatus));
42 assert(inb.pos == inb.size);
43
44 size_t const endStatus = ZSTD_seekable_endStream(zscs, &outb);
45 assert(!ZSTD_isError(endStatus));
46 seekSize = outb.pos;
47 }
48
49 ZSTD_seekable* const stream = ZSTD_seekable_create();
50 assert(stream != NULL);
51 { size_t const initStatus = ZSTD_seekable_initBuff(stream, seekBuffer, seekSize);
52 assert(!ZSTD_isError(initStatus)); }
53
54 { size_t const decStatus = ZSTD_seekable_decompress(stream, outBuffer, outCapacity, 0);
55 assert(decStatus == inSize); }
56
57 /* unit test ZSTD_seekTable functions */
58 ZSTD_seekTable* const zst = ZSTD_seekTable_create_fromSeekable(stream);
59 assert(zst != NULL);
60
61 unsigned const nbFrames = ZSTD_seekTable_getNumFrames(zst);
62 assert(nbFrames > 0);
63
64 unsigned long long const frame0Offset = ZSTD_seekTable_getFrameCompressedOffset(zst, 0);
65 assert(frame0Offset == 0);
66
67 unsigned long long const content0Offset = ZSTD_seekTable_getFrameDecompressedOffset(zst, 0);
68 assert(content0Offset == 0);
69
70 size_t const cSize = ZSTD_seekTable_getFrameCompressedSize(zst, 0);
71 assert(!ZSTD_isError(cSize));
72 assert(cSize <= seekCapacity);
73
74 size_t const origSize = ZSTD_seekTable_getFrameDecompressedSize(zst, 0);
75 assert(origSize == inSize);
76
77 unsigned const fo1idx = ZSTD_seekTable_offsetToFrameIndex(zst, 1);
78 assert(fo1idx == 0);
79
80 free(inBuffer);
81 free(seekBuffer);
82 free(outBuffer);
83 ZSTD_seekable_freeCStream(zscs);
84 ZSTD_seekTable_free(zst);
85 ZSTD_seekable_free(stream);
86 }
87 printf("Success!\n");
88
89
90 printf("Test %u - check that seekable decompress does not hang: ", testNb++);
91 { /* Github issue #2335 */
92 const size_t compressed_size = 17;
93 const uint8_t compressed_data[17] = {
94 '^',
95 '*',
96 'M',
97 '\x18',
98 '\t',
99 '\x00',
100 '\x00',
101 '\x00',
102 '\x00',
103 '\x00',
104 '\x00',
105 '\x00',
106 (uint8_t)('\x03'),
107 (uint8_t)('\xb1'),
108 (uint8_t)('\xea'),
109 (uint8_t)('\x92'),
110 (uint8_t)('\x8f'),
111 };
112 const size_t uncompressed_size = 32;
113 uint8_t uncompressed_data[32];
114
115 ZSTD_seekable* const stream = ZSTD_seekable_create();
116 assert(stream != NULL);
117 { size_t const status = ZSTD_seekable_initBuff(stream, compressed_data, compressed_size);
118 if (ZSTD_isError(status)) {
119 ZSTD_seekable_free(stream);
120 goto _test_error;
121 } }
122
123 /* Should return an error, but not hang */
124 { const size_t offset = 2;
125 size_t const status = ZSTD_seekable_decompress(stream, uncompressed_data, uncompressed_size, offset);
126 if (!ZSTD_isError(status)) {
127 ZSTD_seekable_free(stream);
128 goto _test_error;
129 } }
130
131 ZSTD_seekable_free(stream);
132 }
133 printf("Success!\n");
134
135 printf("Test %u - check #2 that seekable decompress does not hang: ", testNb++);
136 { /* Github issue #FIXME */
137 const size_t compressed_size = 27;
138 const uint8_t compressed_data[27] = {
139 (uint8_t)'\x28',
140 (uint8_t)'\xb5',
141 (uint8_t)'\x2f',
142 (uint8_t)'\xfd',
143 (uint8_t)'\x00',
144 (uint8_t)'\x32',
145 (uint8_t)'\x91',
146 (uint8_t)'\x00',
147 (uint8_t)'\x00',
148 (uint8_t)'\x00',
149 (uint8_t)'\x5e',
150 (uint8_t)'\x2a',
151 (uint8_t)'\x4d',
152 (uint8_t)'\x18',
153 (uint8_t)'\x09',
154 (uint8_t)'\x00',
155 (uint8_t)'\x00',
156 (uint8_t)'\x00',
157 (uint8_t)'\x00',
158 (uint8_t)'\x00',
159 (uint8_t)'\x00',
160 (uint8_t)'\x00',
161 (uint8_t)'\x00',
162 (uint8_t)'\xb1',
163 (uint8_t)'\xea',
164 (uint8_t)'\x92',
165 (uint8_t)'\x8f',
166 };
167 const size_t uncompressed_size = 400;
168 uint8_t uncompressed_data[400];
169
170 ZSTD_seekable* stream = ZSTD_seekable_create();
171 size_t status = ZSTD_seekable_initBuff(stream, compressed_data, compressed_size);
172 if (ZSTD_isError(status)) {
173 ZSTD_seekable_free(stream);
174 goto _test_error;
175 }
176
177 const size_t offset = 2;
178 /* Should return an error, but not hang */
179 status = ZSTD_seekable_decompress(stream, uncompressed_data, uncompressed_size, offset);
180 if (!ZSTD_isError(status)) {
181 ZSTD_seekable_free(stream);
182 goto _test_error;
183 }
184
185 ZSTD_seekable_free(stream);
186 }
187 printf("Success!\n");
188
189 /* TODO: Add more tests */
190 printf("Finished tests\n");
191 return 0;
192
193 _test_error:
194 printf("test failed! Exiting..\n");
195 return 1;
196 }
197