1 /* 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 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 20 static int 21 compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size) 22 { 23 ZSTD_inBuffer in = { data, size, 0 }; 24 while (in.pos < in.size) { 25 ZSTD_outBuffer tmp = out; 26 const size_t rc = ZSTD_compressStream(ctx, &tmp, &in); 27 if (ZSTD_isError(rc)) return 1; 28 } 29 { ZSTD_outBuffer tmp = out; 30 const size_t rc = ZSTD_flushStream(ctx, &tmp); 31 if (rc != 0) { return 1; } 32 } 33 return 0; 34 } 35 36 int main(int argc, const char** argv) 37 { 38 ZSTD_CStream* ctx; 39 unsigned windowLog = 18; 40 (void)argc; 41 (void)argv; 42 /* Create stream */ 43 ctx = ZSTD_createCCtx(); 44 if (!ctx) { return 1; } 45 /* Set parameters */ 46 if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_windowLog, windowLog))) 47 return 2; 48 if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_chainLog, 13))) 49 return 2; 50 if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_hashLog, 14))) 51 return 2; 52 if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_searchLog, 1))) 53 return 2; 54 if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_minMatch, 7))) 55 return 2; 56 if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_targetLength, 16))) 57 return 2; 58 if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_strategy, ZSTD_fast))) 59 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 ZSTD_freeCCtx(ctx); 101 return 0; 102 } 103