mirror of
https://github.com/facebook/zstd.git
synced 2025-12-09 00:03:18 -05:00
[decompress] Fix nullptr addition & improve fuzzer
Fix an instance of `NULL + 0` in `ZSTD_decompressStream()`. Also, improve our `stream_decompress` fuzzer to pass `NULL` in/out buffers to `ZSTD_decompressStream()`, and fix 2 issues that were immediately surfaced. Fixes #3351
This commit is contained in:
parent
15f32ad74c
commit
f31b83ff34
@ -2058,6 +2058,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|||||||
size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, (size_t)(oend-op), istart, cSize, ZSTD_getDDict(zds));
|
size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, (size_t)(oend-op), istart, cSize, ZSTD_getDDict(zds));
|
||||||
if (ZSTD_isError(decompressedSize)) return decompressedSize;
|
if (ZSTD_isError(decompressedSize)) return decompressedSize;
|
||||||
DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()")
|
DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()")
|
||||||
|
assert(istart != NULL);
|
||||||
ip = istart + cSize;
|
ip = istart + cSize;
|
||||||
op = op ? op + decompressedSize : op; /* can occur if frameContentSize = 0 (empty frame) */
|
op = op ? op + decompressedSize : op; /* can occur if frameContentSize = 0 (empty frame) */
|
||||||
zds->expected = 0;
|
zds->expected = 0;
|
||||||
@ -2143,6 +2144,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|||||||
}
|
}
|
||||||
if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
|
if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
|
||||||
FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, ip, neededInSize), "");
|
FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, ip, neededInSize), "");
|
||||||
|
assert(ip != NULL);
|
||||||
ip += neededInSize;
|
ip += neededInSize;
|
||||||
/* Function modifies the stage so we must break */
|
/* Function modifies the stage so we must break */
|
||||||
break;
|
break;
|
||||||
@ -2166,8 +2168,11 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|||||||
"should never happen");
|
"should never happen");
|
||||||
loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, (size_t)(iend-ip));
|
loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, (size_t)(iend-ip));
|
||||||
}
|
}
|
||||||
ip += loadedSize;
|
if (loadedSize != 0) {
|
||||||
zds->inPos += loadedSize;
|
/* ip may be NULL */
|
||||||
|
ip += loadedSize;
|
||||||
|
zds->inPos += loadedSize;
|
||||||
|
}
|
||||||
if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */
|
if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */
|
||||||
|
|
||||||
/* decode loaded input */
|
/* decode loaded input */
|
||||||
|
|||||||
@ -4029,7 +4029,8 @@ size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* zbd,
|
|||||||
size_t const toLoad = hSize - zbd->lhSize; /* if hSize!=0, hSize > zbd->lhSize */
|
size_t const toLoad = hSize - zbd->lhSize; /* if hSize!=0, hSize > zbd->lhSize */
|
||||||
if (ZSTDv06_isError(hSize)) return hSize;
|
if (ZSTDv06_isError(hSize)) return hSize;
|
||||||
if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
|
if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
|
||||||
memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip);
|
if (ip != NULL)
|
||||||
|
memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip);
|
||||||
zbd->lhSize += iend-ip;
|
zbd->lhSize += iend-ip;
|
||||||
*dstCapacityPtr = 0;
|
*dstCapacityPtr = 0;
|
||||||
return (hSize - zbd->lhSize) + ZSTDv06_blockHeaderSize; /* remaining header bytes + next block header */
|
return (hSize - zbd->lhSize) + ZSTDv06_blockHeaderSize; /* remaining header bytes + next block header */
|
||||||
|
|||||||
@ -4411,7 +4411,8 @@ size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* zbd,
|
|||||||
if (hSize != 0) {
|
if (hSize != 0) {
|
||||||
size_t const toLoad = hSize - zbd->lhSize; /* if hSize!=0, hSize > zbd->lhSize */
|
size_t const toLoad = hSize - zbd->lhSize; /* if hSize!=0, hSize > zbd->lhSize */
|
||||||
if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
|
if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
|
||||||
memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip);
|
if (ip != NULL)
|
||||||
|
memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip);
|
||||||
zbd->lhSize += iend-ip;
|
zbd->lhSize += iend-ip;
|
||||||
*dstCapacityPtr = 0;
|
*dstCapacityPtr = 0;
|
||||||
return (hSize - zbd->lhSize) + ZSTDv07_blockHeaderSize; /* remaining header bytes + next block header */
|
return (hSize - zbd->lhSize) + ZSTDv07_blockHeaderSize; /* remaining header bytes + next block header */
|
||||||
|
|||||||
@ -99,14 +99,14 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
|
|||||||
|
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
ZSTD_inBuffer in = makeInBuffer(&src, &size, producer);
|
ZSTD_inBuffer in = makeInBuffer(&src, &size, producer);
|
||||||
while (in.pos != in.size) {
|
do {
|
||||||
|
size_t const rc = ZSTD_decompressStream(dstream, &out, &in);
|
||||||
|
if (ZSTD_isError(rc)) goto error;
|
||||||
if (out.pos == out.size) {
|
if (out.pos == out.size) {
|
||||||
if (stableOutBuffer) goto error;
|
if (stableOutBuffer) goto error;
|
||||||
out = makeOutBuffer(producer, buf, bufSize);
|
out = makeOutBuffer(producer, buf, bufSize);
|
||||||
}
|
}
|
||||||
size_t const rc = ZSTD_decompressStream(dstream, &out, &in);
|
} while (in.pos != in.size);
|
||||||
if (ZSTD_isError(rc)) goto error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user