mirror of
https://github.com/facebook/zstd.git
synced 2024-11-24 05:46:45 +08:00
[lib] Validate buffers when ZSTD_c_stable{In,Out}Buffer is set
Adds the validation of the input/output buffers only. They are still unused.
This commit is contained in:
parent
e3e0775cc8
commit
c74be3f6de
@ -48,6 +48,7 @@ const char* ERR_getErrorString(ERR_enum code)
|
||||
case PREFIX(frameIndex_tooLarge): return "Frame index is too large";
|
||||
case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking";
|
||||
case PREFIX(dstBuffer_wrong): return "Destination buffer is wrong";
|
||||
case PREFIX(srcBuffer_wrong): return "Source buffer is wrong";
|
||||
case PREFIX(maxCode):
|
||||
default: return notErrorCode;
|
||||
}
|
||||
|
@ -77,6 +77,7 @@ typedef enum {
|
||||
ZSTD_error_frameIndex_tooLarge = 100,
|
||||
ZSTD_error_seekableIO = 102,
|
||||
ZSTD_error_dstBuffer_wrong = 104,
|
||||
ZSTD_error_srcBuffer_wrong = 105,
|
||||
ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */
|
||||
} ZSTD_ErrorCode;
|
||||
|
||||
|
@ -4193,6 +4193,41 @@ size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuf
|
||||
return ZSTD_nextInputSizeHint_MTorST(zcs);
|
||||
}
|
||||
|
||||
/* After a compression call set the expected input/output buffer.
|
||||
* This is validated at the start of the next compression call.
|
||||
*/
|
||||
static void ZSTD_setBufferExpectations(ZSTD_CCtx* cctx, ZSTD_outBuffer const* output, ZSTD_inBuffer const* input)
|
||||
{
|
||||
if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) {
|
||||
cctx->expectedInBuffer = *input;
|
||||
}
|
||||
if (cctx->appliedParams.outBufferMode == ZSTD_bm_stable) {
|
||||
cctx->expectedOutBufferSize = output->size - output->pos;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate that the input/output buffers match the expectations set by
|
||||
* ZSTD_setBufferExpectations.
|
||||
*/
|
||||
static size_t ZSTD_checkBufferStability(ZSTD_CCtx const* cctx,
|
||||
ZSTD_outBuffer const* output,
|
||||
ZSTD_inBuffer const* input,
|
||||
ZSTD_EndDirective endOp)
|
||||
{
|
||||
if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) {
|
||||
ZSTD_inBuffer const expect = cctx->expectedInBuffer;
|
||||
if (expect.src != input->src || expect.pos != input->pos || expect.size != input->size)
|
||||
RETURN_ERROR(srcBuffer_wrong, "ZSTD_c_stableInBuffer enabled but input differs!");
|
||||
if (endOp != ZSTD_e_end)
|
||||
RETURN_ERROR(srcBuffer_wrong, "ZSTD_c_stableInBuffer can only be used with ZSTD_e_end!");
|
||||
}
|
||||
if (cctx->appliedParams.outBufferMode == ZSTD_bm_stable) {
|
||||
size_t const outBufferSize = output->size - output->pos;
|
||||
if (cctx->expectedOutBufferSize != outBufferSize)
|
||||
RETURN_ERROR(dstBuffer_wrong, "ZSTD_c_stableOutBuffer enabled but output size differs!");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
|
||||
ZSTD_outBuffer* output,
|
||||
@ -4270,9 +4305,13 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
|
||||
cctx->outBuffContentSize = cctx->outBuffFlushedSize = 0;
|
||||
cctx->streamStage = zcss_load;
|
||||
cctx->frameEnded = 0;
|
||||
} }
|
||||
}
|
||||
/* Set initial buffer expectations now that we've initialized */
|
||||
ZSTD_setBufferExpectations(cctx, output, input);
|
||||
}
|
||||
/* end of transparent initialization stage */
|
||||
|
||||
FORWARD_IF_ERROR(ZSTD_checkBufferStability(cctx, output, input, endOp), "invalid buffers");
|
||||
/* compression stage */
|
||||
#ifdef ZSTD_MULTITHREAD
|
||||
if (cctx->appliedParams.nbWorkers > 0) {
|
||||
@ -4296,11 +4335,13 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
|
||||
* flush, or we are out of output space.
|
||||
*/
|
||||
assert(!forceMaxProgress || flushMin == 0 || output->pos == output->size);
|
||||
ZSTD_setBufferExpectations(cctx, output, input);
|
||||
return flushMin;
|
||||
}
|
||||
#endif
|
||||
FORWARD_IF_ERROR( ZSTD_compressStream_generic(cctx, output, input, endOp) , "");
|
||||
DEBUGLOG(5, "completed ZSTD_compressStream2");
|
||||
ZSTD_setBufferExpectations(cctx, output, input);
|
||||
return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */
|
||||
}
|
||||
|
||||
|
@ -291,6 +291,10 @@ struct ZSTD_CCtx_s {
|
||||
ZSTD_cStreamStage streamStage;
|
||||
U32 frameEnded;
|
||||
|
||||
/* Stable in/out buffer verification */
|
||||
ZSTD_inBuffer expectedInBuffer;
|
||||
size_t expectedOutBufferSize;
|
||||
|
||||
/* Dictionary */
|
||||
ZSTD_localDict localDict;
|
||||
const ZSTD_CDict* cdict;
|
||||
|
Loading…
Reference in New Issue
Block a user