Compress-Zstd

 view release on metacpan or  search on metacpan

ext/zstd/tests/zbufftest.c  view on Meta::CPAN

            srcBuffer = cNoiseBuffer[buffNb];
        }

        /* compression init */
        {   U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;
            U32 const cLevel = (FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (testLog/3))) + 1;
            maxTestSize = FUZ_rLogLength(&lseed, testLog);
            dictSize  = (FUZ_rand(&lseed)==1) ? FUZ_randomLength(&lseed, maxSampleLog) : 0;
            /* random dictionary selection */
            {   size_t const dictStart = FUZ_rand(&lseed) % (srcBufferSize - dictSize);
                dict = srcBuffer + dictStart;
            }
            {   ZSTD_parameters params = ZSTD_getParams(cLevel, 0, dictSize);
                params.fParams.checksumFlag = FUZ_rand(&lseed) & 1;
                params.fParams.noDictIDFlag = FUZ_rand(&lseed) & 1;
                {   size_t const initError = ZBUFF_compressInit_advanced(zc, dict, dictSize, params, ZSTD_CONTENTSIZE_UNKNOWN);
                    CHECK (ZBUFF_isError(initError),"init error : %s", ZBUFF_getErrorName(initError));
        }   }   }

        /* multi-segments compression test */
        XXH64_reset(&xxhState, 0);
        nbChunks    = (FUZ_rand(&lseed) & 127) + 2;
        for (n=0, cSize=0, totalTestSize=0 ; (n<nbChunks) && (totalTestSize < maxTestSize) ; n++) {
            /* compress random chunk into random size dst buffer */
            {   size_t readChunkSize = FUZ_randomLength(&lseed, maxSampleLog);
                size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
                size_t dstBuffSize = MIN(cBufferSize - cSize, randomDstSize);
                size_t const srcStart = FUZ_rand(&lseed) % (srcBufferSize - readChunkSize);

                size_t const compressionError = ZBUFF_compressContinue(zc, cBuffer+cSize, &dstBuffSize, srcBuffer+srcStart, &readChunkSize);
                CHECK (ZBUFF_isError(compressionError), "compression error : %s", ZBUFF_getErrorName(compressionError));

                XXH64_update(&xxhState, srcBuffer+srcStart, readChunkSize);
                memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, readChunkSize);
                cSize += dstBuffSize;
                totalTestSize += readChunkSize;
            }

            /* random flush operation, to mess around */
            if ((FUZ_rand(&lseed) & 15) == 0) {
                size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
                size_t dstBuffSize = MIN(cBufferSize - cSize, randomDstSize);
                size_t const flushError = ZBUFF_compressFlush(zc, cBuffer+cSize, &dstBuffSize);
                CHECK (ZBUFF_isError(flushError), "flush error : %s", ZBUFF_getErrorName(flushError));
                cSize += dstBuffSize;
        }   }

        /* final frame epilogue */
        {   size_t remainingToFlush = (size_t)(-1);
            while (remainingToFlush) {
                size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
                size_t dstBuffSize = MIN(cBufferSize - cSize, randomDstSize);
                U32 const enoughDstSize = dstBuffSize >= remainingToFlush;
                remainingToFlush = ZBUFF_compressEnd(zc, cBuffer+cSize, &dstBuffSize);
                CHECK (ZBUFF_isError(remainingToFlush), "flush error : %s", ZBUFF_getErrorName(remainingToFlush));
                CHECK (enoughDstSize && remainingToFlush, "ZBUFF_compressEnd() not fully flushed (%u remaining), but enough space available", (U32)remainingToFlush);
                cSize += dstBuffSize;
        }   }
        crcOrig = XXH64_digest(&xxhState);

        /* multi - fragments decompression test */
        ZBUFF_decompressInitDictionary(zd, dict, dictSize);
        errorCode = 1;
        for (totalCSize = 0, totalGenSize = 0 ; errorCode ; ) {
            size_t readCSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
            size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
            size_t dstBuffSize = MIN(dstBufferSize - totalGenSize, randomDstSize);
            errorCode = ZBUFF_decompressContinue(zd, dstBuffer+totalGenSize, &dstBuffSize, cBuffer+totalCSize, &readCSrcSize);
            CHECK (ZBUFF_isError(errorCode), "decompression error : %s", ZBUFF_getErrorName(errorCode));
            totalGenSize += dstBuffSize;
            totalCSize += readCSrcSize;
        }
        CHECK (errorCode != 0, "frame not fully decoded");
        CHECK (totalGenSize != totalTestSize, "decompressed data : wrong size")
        CHECK (totalCSize != cSize, "compressed data should be fully read")
        { U64 const crcDest = XXH64(dstBuffer, totalTestSize, 0);
          if (crcDest!=crcOrig) findDiff(copyBuffer, dstBuffer, totalTestSize);
          CHECK (crcDest!=crcOrig, "decompressed data corrupted"); }

        /*=====   noisy/erroneous src decompression test   =====*/

        /* add some noise */
        {   U32 const nbNoiseChunks = (FUZ_rand(&lseed) & 7) + 2;
            U32 nn; for (nn=0; nn<nbNoiseChunks; nn++) {
                size_t const randomNoiseSize = FUZ_randomLength(&lseed, maxSampleLog);
                size_t const noiseSize  = MIN((cSize/3) , randomNoiseSize);
                size_t const noiseStart = FUZ_rand(&lseed) % (srcBufferSize - noiseSize);
                size_t const cStart = FUZ_rand(&lseed) % (cSize - noiseSize);
                memcpy(cBuffer+cStart, srcBuffer+noiseStart, noiseSize);
        }   }

        /* try decompression on noisy data */
        ZBUFF_decompressInit(zd);
        totalCSize = 0;
        totalGenSize = 0;
        while ( (totalCSize < cSize) && (totalGenSize < dstBufferSize) ) {
            size_t readCSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
            size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
            size_t dstBuffSize = MIN(dstBufferSize - totalGenSize, randomDstSize);
            size_t const decompressError = ZBUFF_decompressContinue(zd, dstBuffer+totalGenSize, &dstBuffSize, cBuffer+totalCSize, &readCSrcSize);
            if (ZBUFF_isError(decompressError)) break;   /* error correctly detected */
            totalGenSize += dstBuffSize;
            totalCSize += readCSrcSize;
    }   }
    DISPLAY("\r%u fuzzer tests completed   \n", testNb);

_cleanup:
    ZBUFF_freeCCtx(zc);
    ZBUFF_freeDCtx(zd);
    free(cNoiseBuffer[0]);
    free(cNoiseBuffer[1]);
    free(cNoiseBuffer[2]);
    free(cNoiseBuffer[3]);
    free(cNoiseBuffer[4]);
    free(copyBuffer);
    free(cBuffer);
    free(dstBuffer);
    return result;

_output_error:
    result = 1;



( run in 0.765 second using v1.01-cache-2.11-cpan-364913b4093 )