]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Fix seekable decompress hanging 2516/head
authorSen Huang <senhuang96@fb.com>
Tue, 2 Mar 2021 22:30:03 +0000 (14:30 -0800)
committerSen Huang <senhuang96@fb.com>
Tue, 2 Mar 2021 22:30:03 +0000 (14:30 -0800)
contrib/seekable_format/tests/seekable_tests.c
contrib/seekable_format/zstdseek_decompress.c

index 44efe2b010d9e88789d148c727b795bc07cfa10e..2a159a319809a8db7007eb743270fb1dd4c84540 100644 (file)
@@ -53,7 +53,7 @@ int main(int argc, const char** argv)
     }
     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 */
         const size_t compressed_size = 27;
         const uint8_t compressed_data[27] = {
@@ -85,8 +85,8 @@ int main(int argc, const char** argv)
            '\x92',
            '\x8f',
        };
-        const size_t uncompressed_size = 8936;
-        uint8_t uncompressed_data[8936];
+        const size_t uncompressed_size = 400;
+        uint8_t uncompressed_data[400];
 
         ZSTD_seekable* stream = ZSTD_seekable_create();
         size_t status = ZSTD_seekable_initBuff(stream, compressed_data, compressed_size);
index 4f76158e2d74b53237e20ba9a3d2c349bea9bc55..ed0880ef852cf39dca6693b512542b7e6ef821c9 100644 (file)
@@ -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 noOutputProgressCount = 0;
+    size_t srcBytesRead = 0;
     do {
         /* check if we can continue from a previous decompress job */
         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};
             XXH64_reset(&zs->xxhState, 0);
             ZSTD_DCtx_reset(zs->dstream, ZSTD_reset_session_only);
+            if (srcBytesRead > zs->buffWrapper.size) {
+                return ERROR(seekableIO);
+            }
         }
 
         while (zs->decompressedOffset < offset + len) {
             size_t toRead;
             ZSTD_outBuffer outTmp;
             size_t prevOutPos;
+            size_t prevInPos;
             size_t forwardProgress;
             if (zs->decompressedOffset < 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;
+            prevInPos = zs->in.pos;
             toRead = ZSTD_decompressStream(zs->dstream, &outTmp, &zs->in);
             if (ZSTD_isError(toRead)) {
                 return toRead;
@@ -428,6 +434,7 @@ size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsign
                 noOutputProgressCount = 0;
             }
             zs->decompressedOffset += forwardProgress;
+            srcBytesRead += zs->in.pos - prevInPos;
 
             if (toRead == 0) {
                 /* frame complete */