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