1*01826a49SYabin Cui /*
2*01826a49SYabin Cui * Copyright (c) Meta Platforms, Inc. and affiliates.
3*01826a49SYabin Cui * All rights reserved.
4*01826a49SYabin Cui *
5*01826a49SYabin Cui * This source code is licensed under both the BSD-style license (found in the
6*01826a49SYabin Cui * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7*01826a49SYabin Cui * in the COPYING file in the root directory of this source tree).
8*01826a49SYabin Cui * You may select, at your option, one of the above-listed licenses.
9*01826a49SYabin Cui */
10*01826a49SYabin Cui
11*01826a49SYabin Cui
12*01826a49SYabin Cui #include <stdio.h>
13*01826a49SYabin Cui #include <stddef.h>
14*01826a49SYabin Cui #include <stdlib.h>
15*01826a49SYabin Cui #include <stdint.h>
16*01826a49SYabin Cui #include "mem.h"
17*01826a49SYabin Cui #define ZSTD_STATIC_LINKING_ONLY
18*01826a49SYabin Cui #include "zstd.h"
19*01826a49SYabin Cui
20*01826a49SYabin Cui static int
compress(ZSTD_CStream * ctx,ZSTD_outBuffer out,const void * data,size_t size)21*01826a49SYabin Cui compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size)
22*01826a49SYabin Cui {
23*01826a49SYabin Cui ZSTD_inBuffer in = { data, size, 0 };
24*01826a49SYabin Cui while (in.pos < in.size) {
25*01826a49SYabin Cui ZSTD_outBuffer tmp = out;
26*01826a49SYabin Cui const size_t rc = ZSTD_compressStream(ctx, &tmp, &in);
27*01826a49SYabin Cui if (ZSTD_isError(rc)) return 1;
28*01826a49SYabin Cui }
29*01826a49SYabin Cui { ZSTD_outBuffer tmp = out;
30*01826a49SYabin Cui const size_t rc = ZSTD_flushStream(ctx, &tmp);
31*01826a49SYabin Cui if (rc != 0) { return 1; }
32*01826a49SYabin Cui }
33*01826a49SYabin Cui return 0;
34*01826a49SYabin Cui }
35*01826a49SYabin Cui
main(int argc,const char ** argv)36*01826a49SYabin Cui int main(int argc, const char** argv)
37*01826a49SYabin Cui {
38*01826a49SYabin Cui ZSTD_CStream* ctx;
39*01826a49SYabin Cui unsigned windowLog = 18;
40*01826a49SYabin Cui (void)argc;
41*01826a49SYabin Cui (void)argv;
42*01826a49SYabin Cui /* Create stream */
43*01826a49SYabin Cui ctx = ZSTD_createCCtx();
44*01826a49SYabin Cui if (!ctx) { return 1; }
45*01826a49SYabin Cui /* Set parameters */
46*01826a49SYabin Cui if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_windowLog, windowLog)))
47*01826a49SYabin Cui return 2;
48*01826a49SYabin Cui if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_chainLog, 13)))
49*01826a49SYabin Cui return 2;
50*01826a49SYabin Cui if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_hashLog, 14)))
51*01826a49SYabin Cui return 2;
52*01826a49SYabin Cui if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_searchLog, 1)))
53*01826a49SYabin Cui return 2;
54*01826a49SYabin Cui if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_minMatch, 7)))
55*01826a49SYabin Cui return 2;
56*01826a49SYabin Cui if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_targetLength, 16)))
57*01826a49SYabin Cui return 2;
58*01826a49SYabin Cui if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_strategy, ZSTD_fast)))
59*01826a49SYabin Cui return 2;
60*01826a49SYabin Cui {
61*01826a49SYabin Cui U64 compressed = 0;
62*01826a49SYabin Cui const U64 toCompress = ((U64)1) << 33;
63*01826a49SYabin Cui const size_t size = 1 << windowLog;
64*01826a49SYabin Cui size_t pos = 0;
65*01826a49SYabin Cui char *srcBuffer = (char*) malloc(1 << windowLog);
66*01826a49SYabin Cui char *dstBuffer = (char*) malloc(ZSTD_compressBound(1 << windowLog));
67*01826a49SYabin Cui ZSTD_outBuffer out = { dstBuffer, ZSTD_compressBound(1 << windowLog), 0 };
68*01826a49SYabin Cui const char match[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
69*01826a49SYabin Cui const size_t randomData = (1 << windowLog) - 2*sizeof(match);
70*01826a49SYabin Cui size_t i;
71*01826a49SYabin Cui printf("\n === Long Match Test === \n");
72*01826a49SYabin Cui printf("Creating random data to produce long matches \n");
73*01826a49SYabin Cui for (i = 0; i < sizeof(match); ++i) {
74*01826a49SYabin Cui srcBuffer[i] = match[i];
75*01826a49SYabin Cui }
76*01826a49SYabin Cui for (i = 0; i < randomData; ++i) {
77*01826a49SYabin Cui srcBuffer[sizeof(match) + i] = (char)(rand() & 0xFF);
78*01826a49SYabin Cui }
79*01826a49SYabin Cui for (i = 0; i < sizeof(match); ++i) {
80*01826a49SYabin Cui srcBuffer[sizeof(match) + randomData + i] = match[i];
81*01826a49SYabin Cui }
82*01826a49SYabin Cui printf("Compressing, trying to generate a segfault \n");
83*01826a49SYabin Cui if (compress(ctx, out, srcBuffer, size)) {
84*01826a49SYabin Cui return 1;
85*01826a49SYabin Cui }
86*01826a49SYabin Cui compressed += size;
87*01826a49SYabin Cui while (compressed < toCompress) {
88*01826a49SYabin Cui const size_t block = rand() % (size - pos + 1);
89*01826a49SYabin Cui if (pos == size) { pos = 0; }
90*01826a49SYabin Cui if (compress(ctx, out, srcBuffer + pos, block)) {
91*01826a49SYabin Cui return 1;
92*01826a49SYabin Cui }
93*01826a49SYabin Cui pos += block;
94*01826a49SYabin Cui compressed += block;
95*01826a49SYabin Cui }
96*01826a49SYabin Cui printf("Compression completed successfully (no error triggered)\n");
97*01826a49SYabin Cui free(srcBuffer);
98*01826a49SYabin Cui free(dstBuffer);
99*01826a49SYabin Cui }
100*01826a49SYabin Cui ZSTD_freeCCtx(ctx);
101*01826a49SYabin Cui return 0;
102*01826a49SYabin Cui }
103