Browse code

eliminating potential infinite loop in libmspack quantum decompression code.

Micah Snyder authored on 2017/11/14 06:24:45
Showing 1 changed files
... ...
@@ -258,6 +258,10 @@ int qtmd_decompress(struct qtmd_stream *qtm, off_t out_bytes) {
258 258
   int i, j, selector, extra, sym, match_length;
259 259
   unsigned short H, L, C, symf;
260 260
 
261
+  unsigned char *prev_o_ptr = NULL, *prev_o_end = NULL;
262
+  off_t prev_out_bytes = 0;
263
+  int prev_i = 0;
264
+
261 265
   register unsigned int bit_buffer;
262 266
   register unsigned char bits_left;
263 267
 
... ...
@@ -288,6 +292,11 @@ int qtmd_decompress(struct qtmd_stream *qtm, off_t out_bytes) {
288 288
 
289 289
   /* while we do not have enough decoded bytes in reserve: */
290 290
   while ((qtm->o_end - qtm->o_ptr) < out_bytes) {
291
+    prev_o_ptr = qtm->o_ptr;
292
+    prev_o_end = qtm->o_end;
293
+    prev_out_bytes = out_bytes;
294
+    prev_i = i;
295
+
291 296
     /* read header if necessary. Initialises H, L and C */
292 297
     if (!qtm->header_read) {
293 298
       H = 0xFFFF; L = 0; READ_BITS(C, 16);
... ...
@@ -456,6 +465,15 @@ int qtmd_decompress(struct qtmd_stream *qtm, off_t out_bytes) {
456 456
       window_posn = 0;
457 457
    }
458 458
 
459
+    if ((prev_o_ptr == qtm->o_ptr) &&
460
+        (prev_o_end == qtm->o_end) &&
461
+        (prev_out_bytes == out_bytes) &&
462
+        (i == prev_i))
463
+    {
464
+      /* It appears that we've hit and infinite loop.  Bail out */
465
+      return qtm->error = MSPACK_ERR_DATAFORMAT;
466
+    }
467
+
459 468
   } /* while (more bytes needed) */
460 469
 
461 470
   if (out_bytes) {