Fix seekable decompress hanging

This commit is contained in:
Sen Huang
2021-03-02 14:30:03 -08:00
parent 3cbdbb888b
commit 527a20c3cd
2 changed files with 10 additions and 3 deletions
@@ -53,7 +53,7 @@ int main(int argc, const char** argv)
} }
printf("Success!\n"); printf("Success!\n");
printf("Test %u - check that seekable decompress does not hang: ", testNb++); printf("Test %u - check #2 that seekable decompress does not hang: ", testNb++);
{ /* Github issue #FIXME */ { /* Github issue #FIXME */
const size_t compressed_size = 27; const size_t compressed_size = 27;
const uint8_t compressed_data[27] = { const uint8_t compressed_data[27] = {
@@ -85,8 +85,8 @@ int main(int argc, const char** argv)
'\x92', '\x92',
'\x8f', '\x8f',
}; };
const size_t uncompressed_size = 8936; const size_t uncompressed_size = 400;
uint8_t uncompressed_data[8936]; uint8_t uncompressed_data[400];
ZSTD_seekable* stream = ZSTD_seekable_create(); ZSTD_seekable* stream = ZSTD_seekable_create();
size_t status = ZSTD_seekable_initBuff(stream, compressed_data, compressed_size); size_t status = ZSTD_seekable_initBuff(stream, compressed_data, compressed_size);
@@ -383,6 +383,7 @@ size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsign
{ {
U32 targetFrame = ZSTD_seekable_offsetToFrameIndex(zs, offset); U32 targetFrame = ZSTD_seekable_offsetToFrameIndex(zs, offset);
U32 noOutputProgressCount = 0; U32 noOutputProgressCount = 0;
size_t srcBytesRead = 0;
do { do {
/* check if we can continue from a previous decompress job */ /* check if we can continue from a previous decompress job */
if (targetFrame != zs->curFrame || offset != zs->decompressedOffset) { if (targetFrame != zs->curFrame || offset != zs->decompressedOffset) {
@@ -395,12 +396,16 @@ size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsign
zs->in = (ZSTD_inBuffer){zs->inBuff, 0, 0}; zs->in = (ZSTD_inBuffer){zs->inBuff, 0, 0};
XXH64_reset(&zs->xxhState, 0); XXH64_reset(&zs->xxhState, 0);
ZSTD_DCtx_reset(zs->dstream, ZSTD_reset_session_only); ZSTD_DCtx_reset(zs->dstream, ZSTD_reset_session_only);
if (srcBytesRead > zs->buffWrapper.size) {
return ERROR(seekableIO);
}
} }
while (zs->decompressedOffset < offset + len) { while (zs->decompressedOffset < offset + len) {
size_t toRead; size_t toRead;
ZSTD_outBuffer outTmp; ZSTD_outBuffer outTmp;
size_t prevOutPos; size_t prevOutPos;
size_t prevInPos;
size_t forwardProgress; size_t forwardProgress;
if (zs->decompressedOffset < offset) { if (zs->decompressedOffset < offset) {
/* dummy decompressions until we get to the target offset */ /* dummy decompressions until we get to the target offset */
@@ -410,6 +415,7 @@ size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsign
} }
prevOutPos = outTmp.pos; prevOutPos = outTmp.pos;
prevInPos = zs->in.pos;
toRead = ZSTD_decompressStream(zs->dstream, &outTmp, &zs->in); toRead = ZSTD_decompressStream(zs->dstream, &outTmp, &zs->in);
if (ZSTD_isError(toRead)) { if (ZSTD_isError(toRead)) {
return toRead; return toRead;
@@ -428,6 +434,7 @@ size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsign
noOutputProgressCount = 0; noOutputProgressCount = 0;
} }
zs->decompressedOffset += forwardProgress; zs->decompressedOffset += forwardProgress;
srcBytesRead += zs->in.pos - prevInPos;
if (toRead == 0) { if (toRead == 0) {
/* frame complete */ /* frame complete */