Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions lib/compress/zstd_compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,7 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
{
DEBUGLOG(4, "ZSTD_CCtx_setParameter (%i, %i)", (int)param, value);
RETURN_ERROR_IF(!cctx, GENERIC, "NULL pointer!");
if (cctx->streamStage != zcss_init) {
if (ZSTD_isUpdateAuthorized(param)) {
cctx->cParamsChanged = 1;
Expand Down Expand Up @@ -792,6 +793,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
ZSTD_cParameter param, int value)
{
DEBUGLOG(4, "ZSTD_CCtxParams_setParameter (%i, %i)", (int)param, value);
RETURN_ERROR_IF(!CCtxParams, GENERIC, "NULL pointer!");
switch(param)
{
case ZSTD_c_format :
Expand Down Expand Up @@ -1043,12 +1045,14 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,

size_t ZSTD_CCtx_getParameter(ZSTD_CCtx const* cctx, ZSTD_cParameter param, int* value)
{
RETURN_ERROR_IF(!cctx || !value, GENERIC, "NULL pointer!");
return ZSTD_CCtxParams_getParameter(&cctx->requestedParams, param, value);
}

size_t ZSTD_CCtxParams_getParameter(
ZSTD_CCtx_params const* CCtxParams, ZSTD_cParameter param, int* value)
{
RETURN_ERROR_IF(!CCtxParams || !value, GENERIC, "NULL pointer!");
switch(param)
{
case ZSTD_c_format :
Expand Down Expand Up @@ -1251,6 +1255,7 @@ size_t ZSTD_CCtx_setParams(ZSTD_CCtx* cctx, ZSTD_parameters params)
size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize)
{
DEBUGLOG(4, "ZSTD_CCtx_setPledgedSrcSize to %llu bytes", pledgedSrcSize);
RETURN_ERROR_IF(!cctx, GENERIC, "NULL pointer!");
RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
"Can't set pledgedSrcSize when not in init stage.");
cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
Expand Down Expand Up @@ -1387,6 +1392,7 @@ size_t ZSTD_CCtx_refPrefix_advanced(
* Also dumps dictionary */
size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset)
{
RETURN_ERROR_IF(!cctx, GENERIC, "NULL pointer!");
if ( (reset == ZSTD_reset_session_only)
|| (reset == ZSTD_reset_session_and_parameters) ) {
cctx->streamStage = zcss_init;
Expand Down Expand Up @@ -4897,7 +4903,9 @@ size_t ZSTD_compressContinue(ZSTD_CCtx* cctx,

static size_t ZSTD_getBlockSize_deprecated(const ZSTD_CCtx* cctx)
{
ZSTD_compressionParameters const cParams = cctx->appliedParams.cParams;
ZSTD_compressionParameters cParams;
if (cctx == NULL) return 0;
cParams = cctx->appliedParams.cParams;
assert(!ZSTD_checkCParams(cParams));
return MIN(cctx->appliedParams.maxBlockSize, (size_t)1 << cParams.windowLog);
}
Expand Down Expand Up @@ -6480,6 +6488,7 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
{
DEBUGLOG(5, "ZSTD_compressStream2, endOp=%u ", (unsigned)endOp);
/* check conditions */
RETURN_ERROR_IF(!cctx || !output || !input, GENERIC, "NULL pointer!");
RETURN_ERROR_IF(output->pos > output->size, dstSize_tooSmall, "invalid output buffer");
RETURN_ERROR_IF(input->pos > input->size, srcSize_wrong, "invalid input buffer");
RETURN_ERROR_IF((U32)endOp > (U32)ZSTD_e_end, parameter_outOfBound, "invalid endDirective");
Expand Down Expand Up @@ -6580,6 +6589,7 @@ size_t ZSTD_compressStream2_simpleArgs (
{
ZSTD_outBuffer output;
ZSTD_inBuffer input;
RETURN_ERROR_IF(!dstPos || !srcPos, GENERIC, "NULL pointer!");
output.dst = dst;
output.size = dstCapacity;
output.pos = *dstPos;
Expand All @@ -6598,9 +6608,12 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize)
{
ZSTD_bufferMode_e const originalInBufferMode = cctx->requestedParams.inBufferMode;
ZSTD_bufferMode_e const originalOutBufferMode = cctx->requestedParams.outBufferMode;
ZSTD_bufferMode_e originalInBufferMode;
ZSTD_bufferMode_e originalOutBufferMode;
DEBUGLOG(4, "ZSTD_compress2 (srcSize=%u)", (unsigned)srcSize);
RETURN_ERROR_IF(!cctx, GENERIC, "NULL pointer!");
originalInBufferMode = cctx->requestedParams.inBufferMode;
originalOutBufferMode = cctx->requestedParams.outBufferMode;
ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);
/* Enable stable input/output buffers. */
cctx->requestedParams.inBufferMode = ZSTD_bm_stable;
Expand Down Expand Up @@ -8178,15 +8191,20 @@ static ZSTD_inBuffer inBuffer_forEndFlush(const ZSTD_CStream* zcs)
* @return : amount of data remaining to flush */
size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
{
ZSTD_inBuffer input = inBuffer_forEndFlush(zcs);
ZSTD_inBuffer input;
RETURN_ERROR_IF(!zcs || !output, GENERIC, "NULL pointer!");
input = inBuffer_forEndFlush(zcs);
input.size = input.pos; /* do not ingest more input during flush */
return ZSTD_compressStream2(zcs, output, &input, ZSTD_e_flush);
}

size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
{
ZSTD_inBuffer input = inBuffer_forEndFlush(zcs);
size_t const remainingToFlush = ZSTD_compressStream2(zcs, output, &input, ZSTD_e_end);
ZSTD_inBuffer input;
size_t remainingToFlush;
RETURN_ERROR_IF(!zcs || !output, GENERIC, "NULL pointer!");
input = inBuffer_forEndFlush(zcs);
remainingToFlush = ZSTD_compressStream2(zcs, output, &input, ZSTD_e_end);
FORWARD_IF_ERROR(remainingToFlush , "ZSTD_compressStream2(,,ZSTD_e_end) failed");
if (zcs->appliedParams.nbWorkers > 0) return remainingToFlush; /* minimal estimation */
/* single thread mode : attempt to calculate remaining to flush more precisely */
Expand Down
37 changes: 28 additions & 9 deletions lib/decompress/zstd_decompress.c
Original file line number Diff line number Diff line change
Expand Up @@ -1220,7 +1220,7 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
* Advanced Streaming Decompression API
* Bufferless and synchronous
****************************************/
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx ? dctx->expected : 0; }

/**
* Similar to ZSTD_nextSrcSizeToDecompress(), but when a block input can be streamed, we
Expand All @@ -1233,6 +1233,7 @@ size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
* @param inputSize - The total amount of input that the caller currently has.
*/
static size_t ZSTD_nextSrcSizeToDecompressWithInputSize(ZSTD_DCtx* dctx, size_t inputSize) {
if (!dctx) return 0;
if (!(dctx->stage == ZSTDds_decompressBlock || dctx->stage == ZSTDds_decompressLastBlock))
return dctx->expected;
if (dctx->bType != bt_raw)
Expand All @@ -1241,6 +1242,7 @@ static size_t ZSTD_nextSrcSizeToDecompressWithInputSize(ZSTD_DCtx* dctx, size_t
}

ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
if (dctx == NULL) return ZSTDnit_frameHeader;
switch(dctx->stage)
{
default: /* should not happen */
Expand Down Expand Up @@ -1558,6 +1560,7 @@ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict

size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
{
RETURN_ERROR_IF(!dctx, GENERIC, "NULL pointer!");
assert(dctx != NULL);
#if ZSTD_TRACE
dctx->traceCtx = (ZSTD_trace_decompress_begin != NULL) ? ZSTD_trace_decompress_begin(dctx) : 0;
Expand Down Expand Up @@ -1600,6 +1603,7 @@ size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t
size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
{
DEBUGLOG(4, "ZSTD_decompressBegin_usingDDict");
RETURN_ERROR_IF(!dctx, GENERIC, "NULL pointer!");
assert(dctx != NULL);
if (ddict) {
const char* const dictStart = (const char*)ZSTD_DDict_dictContent(ddict);
Expand Down Expand Up @@ -1875,6 +1879,7 @@ static int ZSTD_dParam_withinBounds(ZSTD_dParameter dParam, int value)

size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value)
{
RETURN_ERROR_IF(!dctx || !value, GENERIC, "NULL pointer!");
switch (param) {
case ZSTD_d_windowLogMax:
*value = (int)ZSTD_highbit32((U32)dctx->maxWindowSize);
Expand Down Expand Up @@ -1904,6 +1909,7 @@ size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value

size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value)
{
RETURN_ERROR_IF(!dctx, GENERIC, "NULL pointer!");
RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
switch(dParam) {
case ZSTD_d_windowLogMax:
Expand Down Expand Up @@ -1945,6 +1951,7 @@ size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value

size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset)
{
RETURN_ERROR_IF(!dctx, GENERIC, "NULL pointer!");
if ( (reset == ZSTD_reset_session_only)
|| (reset == ZSTD_reset_session_and_parameters) ) {
dctx->streamStage = zdss_init;
Expand Down Expand Up @@ -2084,17 +2091,18 @@ static size_t ZSTD_decompressContinueStream(

size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
{
const char* const src = (const char*)input->src;
const char* const istart = input->pos != 0 ? src + input->pos : src;
const char* const iend = input->size != 0 ? src + input->size : src;
const char* ip = istart;
char* const dst = (char*)output->dst;
char* const ostart = output->pos != 0 ? dst + output->pos : dst;
char* const oend = output->size != 0 ? dst + output->size : dst;
char* op = ostart;
const char* src;
const char* istart;
const char* iend;
const char* ip;
char* dst;
char* ostart;
char* oend;
char* op;
U32 someMoreWork = 1;

DEBUGLOG(5, "ZSTD_decompressStream");
RETURN_ERROR_IF(!zds || !output || !input, GENERIC, "NULL pointer!");
assert(zds != NULL);
RETURN_ERROR_IF(
input->pos > input->size,
Expand All @@ -2106,6 +2114,16 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
dstSize_tooSmall,
"forbidden. out: pos: %u vs size: %u",
(U32)output->pos, (U32)output->size);

src = (const char*)input->src;
istart = input->pos != 0 ? src + input->pos : src;
iend = input->size != 0 ? src + input->size : src;
ip = istart;
dst = (char*)output->dst;
ostart = output->pos != 0 ? dst + output->pos : dst;
oend = output->size != 0 ? dst + output->size : dst;
op = ostart;

DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos));
FORWARD_IF_ERROR(ZSTD_checkOutBuffer(zds, output), "");

Expand Down Expand Up @@ -2395,6 +2413,7 @@ size_t ZSTD_decompressStream_simpleArgs (
{
ZSTD_outBuffer output;
ZSTD_inBuffer input;
RETURN_ERROR_IF(!dstPos || !srcPos, GENERIC, "NULL pointer!");
output.dst = dst;
output.size = dstCapacity;
output.pos = *dstPos;
Expand Down
22 changes: 22 additions & 0 deletions tests/zstreamtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,28 @@ static int basicUnitTests(U32 seed, double compressibility, int bigTests)
}
dictID = ZDICT_getDictID(dictionary.start, dictionary.filled);

/* Defensive NULL pointer checks */
DISPLAYLEVEL(3, "test%3i : defensive NULL pointer handling : ", testNb++);
{
int val = 0;
CHECK(!ZSTD_isError(ZSTD_CCtx_setParameter(NULL, ZSTD_c_compressionLevel, 1)), "Expected error on NULL CCtx setParameter");
CHECK(!ZSTD_isError(ZSTD_CCtx_getParameter(NULL, ZSTD_c_compressionLevel, &val)), "Expected error on NULL CCtx getParameter");
CHECK(!ZSTD_isError(ZSTD_CCtx_getParameter(zc, ZSTD_c_compressionLevel, NULL)), "Expected error on NULL value in CCtx getParameter");
CHECK(!ZSTD_isError(ZSTD_CCtx_reset(NULL, ZSTD_reset_session_only)), "Expected error on NULL CCtx reset");
CHECK(!ZSTD_isError(ZSTD_CCtx_setPledgedSrcSize(NULL, 100)), "Expected error on NULL CCtx setPledgedSrcSize");
CHECK(!ZSTD_isError(ZSTD_CCtxParams_setParameter(NULL, ZSTD_c_compressionLevel, 1)), "Expected error on NULL CCtxParams setParameter");
CHECK(!ZSTD_isError(ZSTD_CCtxParams_getParameter(NULL, ZSTD_c_compressionLevel, &val)), "Expected error on NULL CCtxParams getParameter");
CHECK(!ZSTD_isError(ZSTD_DCtx_setParameter(NULL, ZSTD_d_windowLogMax, 20)), "Expected error on NULL DCtx setParameter");
CHECK(!ZSTD_isError(ZSTD_DCtx_getParameter(NULL, ZSTD_d_windowLogMax, &val)), "Expected error on NULL DCtx getParameter");
CHECK(!ZSTD_isError(ZSTD_DCtx_getParameter(zd, ZSTD_d_windowLogMax, NULL)), "Expected error on NULL value in DCtx getParameter");
CHECK(!ZSTD_isError(ZSTD_DCtx_reset(NULL, ZSTD_reset_session_only)), "Expected error on NULL DCtx reset");
CHECK(!ZSTD_isError(ZSTD_decompressBegin(NULL)), "Expected error on NULL DCtx decompressBegin");
CHECK(!ZSTD_isError(ZSTD_decompressBegin_usingDDict(NULL, NULL)), "Expected error on NULL DCtx decompressBegin_usingDDict");
CHECK(ZSTD_nextSrcSizeToDecompress(NULL) != 0, "Expected 0 on NULL DCtx nextSrcSizeToDecompress");
CHECK(ZSTD_getBlockSize(NULL) != 0, "Expected 0 on NULL CCtx getBlockSize");
}
DISPLAYLEVEL(3, "OK \n");

/* Basic compression test */
DISPLAYLEVEL(3, "test%3i : compress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
CHECK_Z( ZSTD_initCStream(zc, 1 /* cLevel */) );
Expand Down