summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/lz4hc.c38
-rw-r--r--tests/fuzzer.c20
2 files changed, 38 insertions, 20 deletions
diff --git a/lib/lz4hc.c b/lib/lz4hc.c
index ef7ded3..a74144a 100644
--- a/lib/lz4hc.c
+++ b/lib/lz4hc.c
@@ -1003,18 +1003,16 @@ int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr)
LZ4_streamHC_t* LZ4_initStreamHC (void* buffer, size_t size)
{
LZ4_streamHC_t* const LZ4_streamHCPtr = (LZ4_streamHC_t*)buffer;
+ LZ4HC_CCtx_internal* const hcstate = &(LZ4_streamHCPtr->internal_donotuse);
+ /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */
+ LZ4_STATIC_ASSERT(sizeof(LZ4HC_CCtx_internal) <= LZ4_STREAMHCSIZE);
+ DEBUGLOG(4, "LZ4_initStreamHC(%p, %u)", buffer, (unsigned)size);
+ /* check conditions */
if (buffer == NULL) return NULL;
if (size < sizeof(LZ4_streamHC_t)) return NULL;
if (!LZ4_isAligned(buffer, LZ4_streamHC_t_alignment())) return NULL;
- /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */
- LZ4_STATIC_ASSERT(sizeof(LZ4HC_CCtx_internal) <= LZ4_STREAMHCSIZE);
- DEBUGLOG(4, "LZ4_initStreamHC(%p, %u)", LZ4_streamHCPtr, (unsigned)size);
- /* end-base will trigger a clearTable on starting compression */
- LZ4_streamHCPtr->internal_donotuse.end = (const BYTE *)(ptrdiff_t)-1;
- LZ4_streamHCPtr->internal_donotuse.base = NULL;
- LZ4_streamHCPtr->internal_donotuse.dictCtx = NULL;
- LZ4_streamHCPtr->internal_donotuse.favorDecSpeed = 0;
- LZ4_streamHCPtr->internal_donotuse.dirty = 0;
+ /* init */
+ MEM_INIT(hcstate, 0, sizeof(*hcstate));
LZ4_setCompressionLevel(LZ4_streamHCPtr, LZ4HC_CLEVEL_DEFAULT);
return LZ4_streamHCPtr;
}
@@ -1100,10 +1098,11 @@ static void LZ4HC_setExternalDict(LZ4HC_CCtx_internal* ctxPtr, const BYTE* newBl
ctxPtr->dictCtx = NULL;
}
-static int LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr,
- const char* src, char* dst,
- int* srcSizePtr, int dstCapacity,
- limitedOutput_directive limit)
+static int
+LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr,
+ const char* src, char* dst,
+ int* srcSizePtr, int dstCapacity,
+ limitedOutput_directive limit)
{
LZ4HC_CCtx_internal* const ctxPtr = &LZ4_streamHCPtr->internal_donotuse;
DEBUGLOG(5, "LZ4_compressHC_continue_generic(ctx=%p, src=%p, srcSize=%d, limit=%d)",
@@ -1131,8 +1130,7 @@ static int LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr,
if (sourceEnd > dictEnd) sourceEnd = dictEnd;
ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase);
if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit;
- }
- }
+ } }
return LZ4HC_compress_generic (ctxPtr, src, dst, srcSizePtr, dstCapacity, ctxPtr->compressionLevel, limit);
}
@@ -1152,13 +1150,17 @@ int LZ4_compress_HC_continue_destSize (LZ4_streamHC_t* LZ4_streamHCPtr, const ch
-/* dictionary saving */
-
+/* LZ4_saveDictHC :
+ * save history content
+ * into a user-provided buffer
+ * which is then used to continue compression
+ */
int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize)
{
LZ4HC_CCtx_internal* const streamPtr = &LZ4_streamHCPtr->internal_donotuse;
int const prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit));
- DEBUGLOG(4, "LZ4_saveDictHC(%p, %p, %d)", LZ4_streamHCPtr, safeBuffer, dictSize);
+ DEBUGLOG(5, "LZ4_saveDictHC(%p, %p, %d)", LZ4_streamHCPtr, safeBuffer, dictSize);
+ assert(prefixSize >= 0);
if (dictSize > 64 KB) dictSize = 64 KB;
if (dictSize < 4) dictSize = 0;
if (dictSize > prefixSize) dictSize = prefixSize;
diff --git a/tests/fuzzer.c b/tests/fuzzer.c
index 29c6a8a..a411dd4 100644
--- a/tests/fuzzer.c
+++ b/tests/fuzzer.c
@@ -1135,13 +1135,13 @@ static void FUZ_unitTests(int compressionLevel)
shct* const shc = (shct*)malloc(sizeof(*shc));
assert(shc != NULL);
memset(shc, 0, sizeof(*shc));
- DISPLAYLEVEL(3, "state1(%p) state2(%p) state3(%p) size(0x%x): ",
+ DISPLAYLEVEL(3, "state1(%p) state2(%p) state3(%p) LZ4_stream_t size(0x%x): ",
&(shc->state1), &(shc->state2), &(shc->state3), (unsigned)sizeof(LZ4_stream_t));
FUZ_CHECKTEST( LZ4_initStream(&(shc->state1), sizeof(shc->state1)) == NULL, "state1 (%p) failed init", &(shc->state1) );
FUZ_CHECKTEST( LZ4_initStream(&(shc->state2), sizeof(shc->state2)) == NULL, "state2 (%p) failed init", &(shc->state2) );
FUZ_CHECKTEST( LZ4_initStream(&(shc->state3), sizeof(shc->state3)) == NULL, "state3 (%p) failed init", &(shc->state3) );
FUZ_CHECKTEST( LZ4_initStream((char*)&(shc->state1) + 1, sizeof(shc->state1)) != NULL,
- "hc1+1 (%p) init must fail, due to bad alignment", (char*)&(shc->state1) + 1 );
+ "hc1+1 (%p) init must fail, due to bad alignment", (char*)&(shc->state1) + 1 );
free(shc);
}
DISPLAYLEVEL(3, "all inits OK \n");
@@ -1268,6 +1268,22 @@ static void FUZ_unitTests(int compressionLevel)
} }
DISPLAYLEVEL(3, "OK \n");
+ /* saveDictHC test #926 */
+ DISPLAYLEVEL(3, "saveDictHC test #926 : ");
+ { LZ4_streamHC_t* const ctx = LZ4_initStreamHC(&sHC, sizeof(sHC));
+ assert(ctx != NULL); /* ensure init is successful */
+
+ /* Check access violation with asan */
+ FUZ_CHECKTEST( LZ4_saveDictHC(&sHC, NULL, 0) != 0,
+ "LZ4_saveDictHC() can't save anything into (NULL,0)");
+
+ /* Check access violation with asan */
+ { char tmp_buffer[240] = { 0 };
+ FUZ_CHECKTEST( LZ4_saveDictHC(&sHC, tmp_buffer, sizeof(tmp_buffer)) != 0,
+ "LZ4_saveDictHC() can't save anything since compression hasn't started");
+ } }
+
+
/* long sequence test */
DISPLAYLEVEL(3, "Long sequence HC_destSize test : ");
{ size_t const blockSize = 1 MB;