diff options
Diffstat (limited to 'tests/roundTripCrash.c')
-rw-r--r-- | tests/roundTripCrash.c | 241 |
1 files changed, 0 insertions, 241 deletions
diff --git a/tests/roundTripCrash.c b/tests/roundTripCrash.c deleted file mode 100644 index 3de5933185d5..000000000000 --- a/tests/roundTripCrash.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - -/* - This program takes a file in input, - performs a zstd round-trip test (compression - decompress) - compares the result with original - and generates a crash (double free) on corruption detection. -*/ - -/*=========================================== -* Dependencies -*==========================================*/ -#include <stddef.h> /* size_t */ -#include <stdlib.h> /* malloc, free, exit */ -#include <stdio.h> /* fprintf */ -#include <string.h> /* strcmp */ -#include <sys/types.h> /* stat */ -#include <sys/stat.h> /* stat */ -#include "xxhash.h" - -#define ZSTD_STATIC_LINKING_ONLY -#include "zstd.h" - -/*=========================================== -* Macros -*==========================================*/ -#define MIN(a,b) ( (a) < (b) ? (a) : (b) ) - -static void crash(int errorCode){ - /* abort if AFL/libfuzzer, exit otherwise */ - #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* could also use __AFL_COMPILER */ - abort(); - #else - exit(errorCode); - #endif -} - -#define CHECK_Z(f) { \ - size_t const err = f; \ - if (ZSTD_isError(err)) { \ - fprintf(stderr, \ - "Error=> %s: %s", \ - #f, ZSTD_getErrorName(err)); \ - crash(1); \ -} } - -/** roundTripTest() : -* Compresses `srcBuff` into `compressedBuff`, -* then decompresses `compressedBuff` into `resultBuff`. -* Compression level used is derived from first content byte. -* @return : result of decompression, which should be == `srcSize` -* or an error code if either compression or decompression fails. -* Note : `compressedBuffCapacity` should be `>= ZSTD_compressBound(srcSize)` -* for compression to be guaranteed to work */ -static size_t roundTripTest(void* resultBuff, size_t resultBuffCapacity, - void* compressedBuff, size_t compressedBuffCapacity, - const void* srcBuff, size_t srcBuffSize) -{ - static const int maxClevel = 19; - size_t const hashLength = MIN(128, srcBuffSize); - unsigned const h32 = XXH32(srcBuff, hashLength, 0); - int const cLevel = h32 % maxClevel; - size_t const cSize = ZSTD_compress(compressedBuff, compressedBuffCapacity, srcBuff, srcBuffSize, cLevel); - if (ZSTD_isError(cSize)) { - fprintf(stderr, "Compression error : %s \n", ZSTD_getErrorName(cSize)); - return cSize; - } - return ZSTD_decompress(resultBuff, resultBuffCapacity, compressedBuff, cSize); -} - -/** cctxParamRoundTripTest() : - * Same as roundTripTest() except allows experimenting with ZSTD_CCtx_params. */ -static size_t cctxParamRoundTripTest(void* resultBuff, size_t resultBuffCapacity, - void* compressedBuff, size_t compressedBuffCapacity, - const void* srcBuff, size_t srcBuffSize) -{ - ZSTD_CCtx* const cctx = ZSTD_createCCtx(); - ZSTD_CCtx_params* const cctxParams = ZSTD_createCCtxParams(); - ZSTD_inBuffer inBuffer = { srcBuff, srcBuffSize, 0 }; - ZSTD_outBuffer outBuffer = { compressedBuff, compressedBuffCapacity, 0 }; - - static const int maxClevel = 19; - size_t const hashLength = MIN(128, srcBuffSize); - unsigned const h32 = XXH32(srcBuff, hashLength, 0); - int const cLevel = h32 % maxClevel; - - /* Set parameters */ - CHECK_Z( ZSTD_CCtxParams_setParameter(cctxParams, ZSTD_c_compressionLevel, cLevel) ); - CHECK_Z( ZSTD_CCtxParams_setParameter(cctxParams, ZSTD_c_nbWorkers, 2) ); - CHECK_Z( ZSTD_CCtxParams_setParameter(cctxParams, ZSTD_c_overlapLog, 5) ); - - - /* Apply parameters */ - CHECK_Z( ZSTD_CCtx_setParametersUsingCCtxParams(cctx, cctxParams) ); - - CHECK_Z (ZSTD_compressStream2(cctx, &outBuffer, &inBuffer, ZSTD_e_end) ); - - ZSTD_freeCCtxParams(cctxParams); - ZSTD_freeCCtx(cctx); - - return ZSTD_decompress(resultBuff, resultBuffCapacity, compressedBuff, outBuffer.pos); -} - -static size_t checkBuffers(const void* buff1, const void* buff2, size_t buffSize) -{ - const char* ip1 = (const char*)buff1; - const char* ip2 = (const char*)buff2; - size_t pos; - - for (pos=0; pos<buffSize; pos++) - if (ip1[pos]!=ip2[pos]) - break; - - return pos; -} - -static void roundTripCheck(const void* srcBuff, size_t srcBuffSize, int testCCtxParams) -{ - size_t const cBuffSize = ZSTD_compressBound(srcBuffSize); - void* cBuff = malloc(cBuffSize); - void* rBuff = malloc(cBuffSize); - - if (!cBuff || !rBuff) { - fprintf(stderr, "not enough memory ! \n"); - exit (1); - } - - { size_t const result = testCCtxParams ? - cctxParamRoundTripTest(rBuff, cBuffSize, cBuff, cBuffSize, srcBuff, srcBuffSize) - : roundTripTest(rBuff, cBuffSize, cBuff, cBuffSize, srcBuff, srcBuffSize); - if (ZSTD_isError(result)) { - fprintf(stderr, "roundTripTest error : %s \n", ZSTD_getErrorName(result)); - crash(1); - } - if (result != srcBuffSize) { - fprintf(stderr, "Incorrect regenerated size : %u != %u\n", (unsigned)result, (unsigned)srcBuffSize); - crash(1); - } - if (checkBuffers(srcBuff, rBuff, srcBuffSize) != srcBuffSize) { - fprintf(stderr, "Silent decoding corruption !!!"); - crash(1); - } - } - - free(cBuff); - free(rBuff); -} - - -static size_t getFileSize(const char* infilename) -{ - int r; -#if defined(_MSC_VER) - struct _stat64 statbuf; - r = _stat64(infilename, &statbuf); - if (r || !(statbuf.st_mode & S_IFREG)) return 0; /* No good... */ -#else - struct stat statbuf; - r = stat(infilename, &statbuf); - if (r || !S_ISREG(statbuf.st_mode)) return 0; /* No good... */ -#endif - return (size_t)statbuf.st_size; -} - - -static int isDirectory(const char* infilename) -{ - int r; -#if defined(_MSC_VER) - struct _stat64 statbuf; - r = _stat64(infilename, &statbuf); - if (!r && (statbuf.st_mode & _S_IFDIR)) return 1; -#else - struct stat statbuf; - r = stat(infilename, &statbuf); - if (!r && S_ISDIR(statbuf.st_mode)) return 1; -#endif - return 0; -} - - -/** loadFile() : -* requirement : `buffer` size >= `fileSize` */ -static void loadFile(void* buffer, const char* fileName, size_t fileSize) -{ - FILE* const f = fopen(fileName, "rb"); - if (isDirectory(fileName)) { - fprintf(stderr, "Ignoring %s directory \n", fileName); - exit(2); - } - if (f==NULL) { - fprintf(stderr, "Impossible to open %s \n", fileName); - exit(3); - } - { size_t const readSize = fread(buffer, 1, fileSize, f); - if (readSize != fileSize) { - fprintf(stderr, "Error reading %s \n", fileName); - exit(5); - } } - fclose(f); -} - - -static void fileCheck(const char* fileName, int testCCtxParams) -{ - size_t const fileSize = getFileSize(fileName); - void* const buffer = malloc(fileSize + !fileSize /* avoid 0 */); - if (!buffer) { - fprintf(stderr, "not enough memory \n"); - exit(4); - } - loadFile(buffer, fileName, fileSize); - roundTripCheck(buffer, fileSize, testCCtxParams); - free (buffer); -} - -int main(int argCount, const char** argv) { - int argNb = 1; - int testCCtxParams = 0; - if (argCount < 2) { - fprintf(stderr, "Error : no argument : need input file \n"); - exit(9); - } - - if (!strcmp(argv[argNb], "--cctxParams")) { - testCCtxParams = 1; - argNb++; - } - - fileCheck(argv[argNb], testCCtxParams); - fprintf(stderr, "no pb detected\n"); - return 0; -} |