xref: /netbsd-src/external/bsd/zstd/dist/tests/legacy.c (revision 3117ece4fc4a4ca4489ba793710b60b0d26bab6c)
1*3117ece4Schristos /*
2*3117ece4Schristos  * Copyright (c) Meta Platforms, Inc. and affiliates.
3*3117ece4Schristos  * All rights reserved.
4*3117ece4Schristos  *
5*3117ece4Schristos  * This source code is licensed under both the BSD-style license (found in the
6*3117ece4Schristos  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7*3117ece4Schristos  * in the COPYING file in the root directory of this source tree).
8*3117ece4Schristos  * You may select, at your option, one of the above-listed licenses.
9*3117ece4Schristos  */
10*3117ece4Schristos 
11*3117ece4Schristos /*
12*3117ece4Schristos     This program uses hard-coded data compressed with Zstd legacy versions
13*3117ece4Schristos     and tests that the API decompresses them correctly
14*3117ece4Schristos */
15*3117ece4Schristos 
16*3117ece4Schristos /*===========================================
17*3117ece4Schristos *   Dependencies
18*3117ece4Schristos *==========================================*/
19*3117ece4Schristos #include <stddef.h>              /* size_t */
20*3117ece4Schristos #include <stdlib.h>              /* malloc, free */
21*3117ece4Schristos #include <stdio.h>               /* fprintf */
22*3117ece4Schristos #include <string.h>              /* strlen */
23*3117ece4Schristos #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_decompressBound */
24*3117ece4Schristos #include "zstd.h"
25*3117ece4Schristos #include "zstd_errors.h"
26*3117ece4Schristos 
27*3117ece4Schristos /*===========================================
28*3117ece4Schristos *   Macros
29*3117ece4Schristos *==========================================*/
30*3117ece4Schristos #define DISPLAY(...)          fprintf(stderr, __VA_ARGS__)
31*3117ece4Schristos 
32*3117ece4Schristos /*===========================================
33*3117ece4Schristos *   Precompressed frames
34*3117ece4Schristos *==========================================*/
35*3117ece4Schristos const char* const COMPRESSED; /* content is at end of file */
36*3117ece4Schristos size_t const COMPRESSED_SIZE = 917;
37*3117ece4Schristos const char* const EXPECTED; /* content is at end of file */
38*3117ece4Schristos 
39*3117ece4Schristos 
40*3117ece4Schristos static int testSimpleAPI(void)
41*3117ece4Schristos {
42*3117ece4Schristos     size_t const size = strlen(EXPECTED);
43*3117ece4Schristos     char* const output = malloc(size);
44*3117ece4Schristos 
45*3117ece4Schristos     if (!output) {
46*3117ece4Schristos         DISPLAY("ERROR: Not enough memory!\n");
47*3117ece4Schristos         return 1;
48*3117ece4Schristos     }
49*3117ece4Schristos 
50*3117ece4Schristos     {
51*3117ece4Schristos         size_t const ret = ZSTD_decompress(output, size, COMPRESSED, COMPRESSED_SIZE);
52*3117ece4Schristos         if (ZSTD_isError(ret)) {
53*3117ece4Schristos             if (ret == ZSTD_error_prefix_unknown) {
54*3117ece4Schristos                 DISPLAY("ERROR: Invalid frame magic number, was this compiled "
55*3117ece4Schristos                         "without legacy support?\n");
56*3117ece4Schristos             } else {
57*3117ece4Schristos                 DISPLAY("ERROR: %s\n", ZSTD_getErrorName(ret));
58*3117ece4Schristos             }
59*3117ece4Schristos             return 1;
60*3117ece4Schristos         }
61*3117ece4Schristos         if (ret != size) {
62*3117ece4Schristos             DISPLAY("ERROR: Wrong decoded size\n");
63*3117ece4Schristos         }
64*3117ece4Schristos     }
65*3117ece4Schristos     if (memcmp(EXPECTED, output, size) != 0) {
66*3117ece4Schristos         DISPLAY("ERROR: Wrong decoded output produced\n");
67*3117ece4Schristos         return 1;
68*3117ece4Schristos     }
69*3117ece4Schristos 
70*3117ece4Schristos     free(output);
71*3117ece4Schristos     DISPLAY("Simple API OK\n");
72*3117ece4Schristos     return 0;
73*3117ece4Schristos }
74*3117ece4Schristos 
75*3117ece4Schristos 
76*3117ece4Schristos static int testStreamingAPI(void)
77*3117ece4Schristos {
78*3117ece4Schristos     int error_code = 0;
79*3117ece4Schristos     size_t const outBuffSize = ZSTD_DStreamOutSize();
80*3117ece4Schristos     char* const outBuff = malloc(outBuffSize);
81*3117ece4Schristos     ZSTD_DStream* const stream = ZSTD_createDStream();
82*3117ece4Schristos     ZSTD_inBuffer input = { COMPRESSED, COMPRESSED_SIZE, 0 };
83*3117ece4Schristos     size_t outputPos = 0;
84*3117ece4Schristos     int needsInit = 1;
85*3117ece4Schristos 
86*3117ece4Schristos     if (outBuff == NULL) {
87*3117ece4Schristos         DISPLAY("ERROR: Could not allocate memory\n");
88*3117ece4Schristos         return 1;
89*3117ece4Schristos     }
90*3117ece4Schristos     if (stream == NULL) {
91*3117ece4Schristos         DISPLAY("ERROR: Could not create dstream\n");
92*3117ece4Schristos         free(outBuff);
93*3117ece4Schristos         return 1;
94*3117ece4Schristos     }
95*3117ece4Schristos 
96*3117ece4Schristos     while (1) {
97*3117ece4Schristos         ZSTD_outBuffer output = {outBuff, outBuffSize, 0};
98*3117ece4Schristos         if (needsInit) {
99*3117ece4Schristos             size_t const ret = ZSTD_initDStream(stream);
100*3117ece4Schristos             if (ZSTD_isError(ret)) {
101*3117ece4Schristos                 DISPLAY("ERROR: ZSTD_initDStream: %s\n", ZSTD_getErrorName(ret));
102*3117ece4Schristos                 error_code = 1;
103*3117ece4Schristos                 break;
104*3117ece4Schristos         }   }
105*3117ece4Schristos 
106*3117ece4Schristos         {   size_t const ret = ZSTD_decompressStream(stream, &output, &input);
107*3117ece4Schristos             if (ZSTD_isError(ret)) {
108*3117ece4Schristos                 DISPLAY("ERROR: ZSTD_decompressStream: %s\n", ZSTD_getErrorName(ret));
109*3117ece4Schristos                 error_code = 1;
110*3117ece4Schristos                 break;
111*3117ece4Schristos             }
112*3117ece4Schristos 
113*3117ece4Schristos             if (ret == 0) {
114*3117ece4Schristos                 needsInit = 1;
115*3117ece4Schristos         }   }
116*3117ece4Schristos 
117*3117ece4Schristos         if (memcmp(outBuff, EXPECTED + outputPos, output.pos) != 0) {
118*3117ece4Schristos             DISPLAY("ERROR: Wrong decoded output produced\n");
119*3117ece4Schristos             error_code = 1;
120*3117ece4Schristos             break;
121*3117ece4Schristos         }
122*3117ece4Schristos         outputPos += output.pos;
123*3117ece4Schristos         if (input.pos == input.size && output.pos < output.size) {
124*3117ece4Schristos             break;
125*3117ece4Schristos         }
126*3117ece4Schristos     }
127*3117ece4Schristos 
128*3117ece4Schristos     free(outBuff);
129*3117ece4Schristos     ZSTD_freeDStream(stream);
130*3117ece4Schristos     if (error_code == 0) DISPLAY("Streaming API OK\n");
131*3117ece4Schristos     return error_code;
132*3117ece4Schristos }
133*3117ece4Schristos 
134*3117ece4Schristos static int testFrameDecoding(void)
135*3117ece4Schristos {
136*3117ece4Schristos     if (strlen(EXPECTED) > ZSTD_decompressBound(COMPRESSED, COMPRESSED_SIZE)) {
137*3117ece4Schristos         DISPLAY("ERROR: ZSTD_decompressBound: decompressed bound too small\n");
138*3117ece4Schristos         return 1;
139*3117ece4Schristos     }
140*3117ece4Schristos     {   const char* ip = COMPRESSED;
141*3117ece4Schristos         size_t remainingSize = COMPRESSED_SIZE;
142*3117ece4Schristos         while (1) {
143*3117ece4Schristos             size_t frameSize = ZSTD_findFrameCompressedSize(ip, remainingSize);
144*3117ece4Schristos             if (ZSTD_isError(frameSize)) {
145*3117ece4Schristos                 DISPLAY("ERROR: ZSTD_findFrameCompressedSize: %s\n", ZSTD_getErrorName(frameSize));
146*3117ece4Schristos                 return 1;
147*3117ece4Schristos             }
148*3117ece4Schristos             if (frameSize > remainingSize) {
149*3117ece4Schristos                 DISPLAY("ERROR: ZSTD_findFrameCompressedSize: expected frameSize to align with src buffer");
150*3117ece4Schristos                 return 1;
151*3117ece4Schristos             }
152*3117ece4Schristos             ip += frameSize;
153*3117ece4Schristos             remainingSize -= frameSize;
154*3117ece4Schristos             if (remainingSize == 0) break;
155*3117ece4Schristos         }
156*3117ece4Schristos     }
157*3117ece4Schristos     DISPLAY("Frame Decoding OK\n");
158*3117ece4Schristos     return 0;
159*3117ece4Schristos }
160*3117ece4Schristos 
161*3117ece4Schristos int main(void)
162*3117ece4Schristos {
163*3117ece4Schristos     {   int const ret = testSimpleAPI();
164*3117ece4Schristos         if (ret) return ret; }
165*3117ece4Schristos     {   int const ret = testStreamingAPI();
166*3117ece4Schristos         if (ret) return ret; }
167*3117ece4Schristos     {   int const ret = testFrameDecoding();
168*3117ece4Schristos         if (ret) return ret; }
169*3117ece4Schristos 
170*3117ece4Schristos     DISPLAY("OK\n");
171*3117ece4Schristos     return 0;
172*3117ece4Schristos }
173*3117ece4Schristos 
174*3117ece4Schristos /* Consists of the "EXPECTED" string compressed with default settings on
175*3117ece4Schristos     - v0.4.3
176*3117ece4Schristos     - v0.5.0
177*3117ece4Schristos     - v0.6.0
178*3117ece4Schristos     - v0.7.0
179*3117ece4Schristos     - v0.8.0
180*3117ece4Schristos */
181*3117ece4Schristos const char* const COMPRESSED =
182*3117ece4Schristos     "\x24\xB5\x2F\xFD\x00\x00\x00\xBB\xB0\x02\xC0\x10\x00\x1E\xB0\x01"
183*3117ece4Schristos     "\x02\x00\x00\x80\x00\xE8\x92\x34\x12\x97\xC8\xDF\xE9\xF3\xEF\x53"
184*3117ece4Schristos     "\xEA\x1D\x27\x4F\x0C\x44\x90\x0C\x8D\xF1\xB4\x89\x17\x00\x18\x00"
185*3117ece4Schristos     "\x18\x00\x3F\xE6\xE2\xE3\x74\xD6\xEC\xC9\x4A\xE0\x71\x71\x42\x3E"
186*3117ece4Schristos     "\x64\x4F\x6A\x45\x4E\x78\xEC\x49\x03\x3F\xC6\x80\xAB\x8F\x75\x5E"
187*3117ece4Schristos     "\x6F\x2E\x3E\x7E\xC6\xDC\x45\x69\x6C\xC5\xFD\xC7\x40\xB8\x84\x8A"
188*3117ece4Schristos     "\x01\xEB\xA8\xD1\x40\x39\x90\x4C\x64\xF8\xEB\x53\xE6\x18\x0B\x67"
189*3117ece4Schristos     "\x12\xAD\xB8\x99\xB3\x5A\x6F\x8A\x19\x03\x01\x50\x67\x56\xF5\x9F"
190*3117ece4Schristos     "\x35\x84\x60\xA0\x60\x91\xC9\x0A\xDC\xAB\xAB\xE0\xE2\x81\xFA\xCF"
191*3117ece4Schristos     "\xC6\xBA\x01\x0E\x00\x54\x00\x00\x19\x00\x00\x54\x14\x00\x24\x24"
192*3117ece4Schristos     "\x04\xFE\x04\x84\x4E\x41\x00\x27\xE2\x02\xC4\xB1\x00\xD2\x51\x00"
193*3117ece4Schristos     "\x79\x58\x41\x28\x00\xE0\x0C\x01\x68\x65\x00\x04\x13\x0C\xDA\x0C"
194*3117ece4Schristos     "\x80\x22\x06\xC0\x00\x00\x25\xB5\x2F\xFD\x00\x00\x00\xAD\x12\xB0"
195*3117ece4Schristos     "\x7D\x1E\xB0\x01\x02\x00\x00\x80\x00\xE8\x92\x34\x12\x97\xC8\xDF"
196*3117ece4Schristos     "\xE9\xF3\xEF\x53\xEA\x1D\x27\x4F\x0C\x44\x90\x0C\x8D\xF1\xB4\x89"
197*3117ece4Schristos     "\x03\x01\x50\x67\x56\xF5\x9F\x35\x84\x60\xA0\x60\x91\xC9\x0A\xDC"
198*3117ece4Schristos     "\xAB\xAB\xE0\xE2\x81\xFA\xCF\xC6\xBA\xEB\xA8\xD1\x40\x39\x90\x4C"
199*3117ece4Schristos     "\x64\xF8\xEB\x53\xE6\x18\x0B\x67\x12\xAD\xB8\x99\xB3\x5A\x6F\x8A"
200*3117ece4Schristos     "\xF9\x63\x0C\xB8\xFA\x58\xE7\xF5\xE6\xE2\xE3\x67\xCC\x5D\x94\xC6"
201*3117ece4Schristos     "\x56\xDC\x7F\x0C\x84\x4B\xA8\xF8\x63\x2E\x3E\x4E\x67\xCD\x9E\xAC"
202*3117ece4Schristos     "\x04\x1E\x17\x27\xE4\x43\xF6\xA4\x56\xE4\x84\xC7\x9E\x34\x0E\x00"
203*3117ece4Schristos     "\x00\x32\x40\x80\xA8\x00\x01\x49\x81\xE0\x3C\x01\x29\x1D\x00\x87"
204*3117ece4Schristos     "\xCE\x80\x75\x08\x80\x72\x24\x00\x7B\x52\x00\x94\x00\x20\xCC\x01"
205*3117ece4Schristos     "\x86\xD2\x00\x81\x09\x83\xC1\x34\xA0\x88\x01\xC0\x00\x00\x26\xB5"
206*3117ece4Schristos     "\x2F\xFD\x42\xEF\x00\x00\xA6\x12\xB0\x7D\x1E\xB0\x01\x02\x00\x00"
207*3117ece4Schristos     "\x54\xA0\xBA\x24\x8D\xC4\x25\xF2\x77\xFA\xFC\xFB\x94\x7A\xC7\xC9"
208*3117ece4Schristos     "\x13\x03\x11\x24\x43\x63\x3C\x6D\x22\x03\x01\x50\x67\x56\xF5\x9F"
209*3117ece4Schristos     "\x35\x84\x60\xA0\x60\x91\xC9\x0A\xDC\xAB\xAB\xE0\xE2\x81\xFA\xCF"
210*3117ece4Schristos     "\xC6\xBA\xEB\xA8\xD1\x40\x39\x90\x4C\x64\xF8\xEB\x53\xE6\x18\x0B"
211*3117ece4Schristos     "\x67\x12\xAD\xB8\x99\xB3\x5A\x6F\x8A\xF9\x63\x0C\xB8\xFA\x58\xE7"
212*3117ece4Schristos     "\xF5\xE6\xE2\xE3\x67\xCC\x5D\x94\xC6\x56\xDC\x7F\x0C\x84\x4B\xA8"
213*3117ece4Schristos     "\xF8\x63\x2E\x3E\x4E\x67\xCD\x9E\xAC\x04\x1E\x17\x27\xE4\x43\xF6"
214*3117ece4Schristos     "\xA4\x56\xE4\x84\xC7\x9E\x34\x0E\x00\x35\x0B\x71\xB5\xC0\x2A\x5C"
215*3117ece4Schristos     "\x26\x94\x22\x20\x8B\x4C\x8D\x13\x47\x58\x67\x15\x6C\xF1\x1C\x4B"
216*3117ece4Schristos     "\x54\x10\x9D\x31\x50\x85\x4B\x54\x0E\x01\x4B\x3D\x01\xC0\x00\x00"
217*3117ece4Schristos     "\x27\xB5\x2F\xFD\x20\xEF\x00\x00\xA6\x12\xE4\x84\x1F\xB0\x01\x10"
218*3117ece4Schristos     "\x00\x00\x00\x35\x59\xA6\xE7\xA1\xEF\x7C\xFC\xBD\x3F\xFF\x9F\xEF"
219*3117ece4Schristos     "\xEE\xEF\x61\xC3\xAA\x31\x1D\x34\x38\x22\x22\x04\x44\x21\x80\x32"
220*3117ece4Schristos     "\xAD\x28\xF3\xD6\x28\x0C\x0A\x0E\xD6\x5C\xAC\x19\x8D\x20\x5F\x45"
221*3117ece4Schristos     "\x02\x2E\x17\x50\x66\x6D\xAC\x8B\x9C\x6E\x07\x73\x46\xBB\x44\x14"
222*3117ece4Schristos     "\xE7\x98\xC3\xB9\x17\x32\x6E\x33\x7C\x0E\x21\xB1\xDB\xCB\x89\x51"
223*3117ece4Schristos     "\x23\x34\xAB\x9D\xBC\x6D\x20\xF5\x03\xA9\x91\x4C\x2E\x1F\x59\xDB"
224*3117ece4Schristos     "\xD9\x35\x67\x4B\x0C\x95\x79\x10\x00\x85\xA6\x96\x95\x2E\xDF\x78"
225*3117ece4Schristos     "\x7B\x4A\x5C\x09\x76\x97\xD1\x5C\x96\x12\x75\x35\xA3\x55\x4A\xD4"
226*3117ece4Schristos     "\x0B\x00\x35\x0B\x71\xB5\xC0\x2A\x5C\xE6\x08\x45\xF1\x39\x43\xF1"
227*3117ece4Schristos     "\x1C\x4B\x54\x10\x9D\x31\x50\x85\x4B\x54\x0E\x01\x4B\x3D\x01\xC0"
228*3117ece4Schristos     "\x00\x00\x28\xB5\x2F\xFD\x24\xEF\x35\x05\x00\x92\x0B\x21\x1F\xB0"
229*3117ece4Schristos     "\x01\x10\x00\x00\x00\x35\x59\xA6\xE7\xA1\xEF\x7C\xFC\xBD\x3F\xFF"
230*3117ece4Schristos     "\x9F\xEF\xEE\xEF\x61\xC3\xAA\x31\x1D\x34\x38\x22\x22\x04\x44\x21"
231*3117ece4Schristos     "\x80\x32\xAD\x28\xF3\xD6\x28\x0C\x0A\x0E\xD6\x5C\xAC\x19\x8D\x20"
232*3117ece4Schristos     "\x5F\x45\x02\x2E\x17\x50\x66\x6D\xAC\x8B\x9C\x6E\x07\x73\x46\xBB"
233*3117ece4Schristos     "\x44\x14\xE7\x98\xC3\xB9\x17\x32\x6E\x33\x7C\x0E\x21\xB1\xDB\xCB"
234*3117ece4Schristos     "\x89\x51\x23\x34\xAB\x9D\xBC\x6D\x20\xF5\x03\xA9\x91\x4C\x2E\x1F"
235*3117ece4Schristos     "\x59\xDB\xD9\x35\x67\x4B\x0C\x95\x79\x10\x00\x85\xA6\x96\x95\x2E"
236*3117ece4Schristos     "\xDF\x78\x7B\x4A\x5C\x09\x76\x97\xD1\x5C\x96\x12\x75\x35\xA3\x55"
237*3117ece4Schristos     "\x4A\xD4\x0B\x00\x35\x0B\x71\xB5\xC0\x2A\x5C\xE6\x08\x45\xF1\x39"
238*3117ece4Schristos     "\x43\xF1\x1C\x4B\x54\x10\x9D\x31\x50\x85\x4B\x54\x0E\x01\x4B\x3D"
239*3117ece4Schristos     "\x01\xD2\x2F\x21\x80";
240*3117ece4Schristos 
241*3117ece4Schristos const char* const EXPECTED =
242*3117ece4Schristos     "snowden is snowed in / he's now then in his snow den / when does the snow end?\n"
243*3117ece4Schristos     "goodbye little dog / you dug some holes in your day / they'll be hard to fill.\n"
244*3117ece4Schristos     "when life shuts a door, / just open it. it’s a door. / that is how doors work.\n"
245*3117ece4Schristos 
246*3117ece4Schristos     "snowden is snowed in / he's now then in his snow den / when does the snow end?\n"
247*3117ece4Schristos     "goodbye little dog / you dug some holes in your day / they'll be hard to fill.\n"
248*3117ece4Schristos     "when life shuts a door, / just open it. it’s a door. / that is how doors work.\n"
249*3117ece4Schristos 
250*3117ece4Schristos     "snowden is snowed in / he's now then in his snow den / when does the snow end?\n"
251*3117ece4Schristos     "goodbye little dog / you dug some holes in your day / they'll be hard to fill.\n"
252*3117ece4Schristos     "when life shuts a door, / just open it. it’s a door. / that is how doors work.\n"
253*3117ece4Schristos 
254*3117ece4Schristos     "snowden is snowed in / he's now then in his snow den / when does the snow end?\n"
255*3117ece4Schristos     "goodbye little dog / you dug some holes in your day / they'll be hard to fill.\n"
256*3117ece4Schristos     "when life shuts a door, / just open it. it’s a door. / that is how doors work.\n"
257*3117ece4Schristos 
258*3117ece4Schristos     "snowden is snowed in / he's now then in his snow den / when does the snow end?\n"
259*3117ece4Schristos     "goodbye little dog / you dug some holes in your day / they'll be hard to fill.\n"
260*3117ece4Schristos     "when life shuts a door, / just open it. it’s a door. / that is how doors work.\n";
261