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