xref: /netbsd-src/external/bsd/zstd/dist/tests/longmatch.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 #include <stdio.h>
13*3117ece4Schristos #include <stddef.h>
14*3117ece4Schristos #include <stdlib.h>
15*3117ece4Schristos #include <stdint.h>
16*3117ece4Schristos #include "mem.h"
17*3117ece4Schristos #define ZSTD_STATIC_LINKING_ONLY
18*3117ece4Schristos #include "zstd.h"
19*3117ece4Schristos 
20*3117ece4Schristos static int
21*3117ece4Schristos compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size)
22*3117ece4Schristos {
23*3117ece4Schristos   ZSTD_inBuffer in = { data, size, 0 };
24*3117ece4Schristos   while (in.pos < in.size) {
25*3117ece4Schristos     ZSTD_outBuffer tmp = out;
26*3117ece4Schristos     const size_t rc = ZSTD_compressStream(ctx, &tmp, &in);
27*3117ece4Schristos     if (ZSTD_isError(rc)) return 1;
28*3117ece4Schristos   }
29*3117ece4Schristos   { ZSTD_outBuffer tmp = out;
30*3117ece4Schristos     const size_t rc = ZSTD_flushStream(ctx, &tmp);
31*3117ece4Schristos     if (rc != 0) { return 1; }
32*3117ece4Schristos   }
33*3117ece4Schristos   return 0;
34*3117ece4Schristos }
35*3117ece4Schristos 
36*3117ece4Schristos int main(int argc, const char** argv)
37*3117ece4Schristos {
38*3117ece4Schristos   ZSTD_CStream* ctx;
39*3117ece4Schristos   unsigned windowLog = 18;
40*3117ece4Schristos   (void)argc;
41*3117ece4Schristos   (void)argv;
42*3117ece4Schristos   /* Create stream */
43*3117ece4Schristos   ctx = ZSTD_createCCtx();
44*3117ece4Schristos   if (!ctx) { return 1; }
45*3117ece4Schristos   /* Set parameters */
46*3117ece4Schristos   if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_windowLog, windowLog)))
47*3117ece4Schristos     return 2;
48*3117ece4Schristos   if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_chainLog, 13)))
49*3117ece4Schristos     return 2;
50*3117ece4Schristos   if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_hashLog, 14)))
51*3117ece4Schristos     return 2;
52*3117ece4Schristos   if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_searchLog, 1)))
53*3117ece4Schristos     return 2;
54*3117ece4Schristos   if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_minMatch, 7)))
55*3117ece4Schristos     return 2;
56*3117ece4Schristos   if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_targetLength, 16)))
57*3117ece4Schristos     return 2;
58*3117ece4Schristos   if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_strategy, ZSTD_fast)))
59*3117ece4Schristos     return 2;
60*3117ece4Schristos   {
61*3117ece4Schristos     U64 compressed = 0;
62*3117ece4Schristos     const U64 toCompress = ((U64)1) << 33;
63*3117ece4Schristos     const size_t size = 1 << windowLog;
64*3117ece4Schristos     size_t pos = 0;
65*3117ece4Schristos     char *srcBuffer = (char*) malloc(1 << windowLog);
66*3117ece4Schristos     char *dstBuffer = (char*) malloc(ZSTD_compressBound(1 << windowLog));
67*3117ece4Schristos     ZSTD_outBuffer out = { dstBuffer, ZSTD_compressBound(1 << windowLog), 0 };
68*3117ece4Schristos     const char match[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
69*3117ece4Schristos     const size_t randomData = (1 << windowLog) - 2*sizeof(match);
70*3117ece4Schristos     size_t i;
71*3117ece4Schristos     printf("\n ===   Long Match Test   === \n");
72*3117ece4Schristos     printf("Creating random data to produce long matches \n");
73*3117ece4Schristos     for (i = 0; i < sizeof(match); ++i) {
74*3117ece4Schristos       srcBuffer[i] = match[i];
75*3117ece4Schristos     }
76*3117ece4Schristos     for (i = 0; i < randomData; ++i) {
77*3117ece4Schristos       srcBuffer[sizeof(match) + i] = (char)(rand() & 0xFF);
78*3117ece4Schristos     }
79*3117ece4Schristos     for (i = 0; i < sizeof(match); ++i) {
80*3117ece4Schristos       srcBuffer[sizeof(match) + randomData + i] = match[i];
81*3117ece4Schristos     }
82*3117ece4Schristos     printf("Compressing, trying to generate a segfault \n");
83*3117ece4Schristos     if (compress(ctx, out, srcBuffer, size)) {
84*3117ece4Schristos       return 1;
85*3117ece4Schristos     }
86*3117ece4Schristos     compressed += size;
87*3117ece4Schristos     while (compressed < toCompress) {
88*3117ece4Schristos       const size_t block = rand() % (size - pos + 1);
89*3117ece4Schristos       if (pos == size) { pos = 0; }
90*3117ece4Schristos       if (compress(ctx, out, srcBuffer + pos, block)) {
91*3117ece4Schristos         return 1;
92*3117ece4Schristos       }
93*3117ece4Schristos       pos += block;
94*3117ece4Schristos       compressed += block;
95*3117ece4Schristos     }
96*3117ece4Schristos     printf("Compression completed successfully (no error triggered)\n");
97*3117ece4Schristos     free(srcBuffer);
98*3117ece4Schristos     free(dstBuffer);
99*3117ece4Schristos   }
100*3117ece4Schristos   ZSTD_freeCCtx(ctx);
101*3117ece4Schristos   return 0;
102*3117ece4Schristos }
103