Browse code

0.99.3 - regression fix - removing first pass offset check when extracting cab files compressed with lzx, improving debug output for LZX type decompression, warning on lzx file format issue instead of exiting decompression

Mickey Sola authored on 2017/11/04 03:42:24
Showing 2 changed files
... ...
@@ -1206,9 +1206,11 @@ static int cabd_extract(struct mscab_decompressor *base,
1206 1206
      *   and pass back MSPACK_ERR_READ
1207 1207
      */
1208 1208
     self->d->outfh = NULL;
1209
-    if ((bytes = file->offset - self->d->offset)) {
1210
-      error = self->d->decompress(self->d->state, bytes);
1211
-      self->error = (error == MSPACK_ERR_READ) ? self->read_error : error;
1209
+    if ((self->d->comp_type & cffoldCOMPTYPE_MASK) != cffoldCOMPTYPE_LZX) {
1210
+        if (bytes = file->offset - self->d->offset) {
1211
+            error = self->d->decompress(self->d->state, bytes);
1212
+            self->error = (error == MSPACK_ERR_READ) ? self->read_error : error;
1213
+        }
1212 1214
     }
1213 1215
 
1214 1216
     /* if getting to the correct offset was error free, unpack file */
... ...
@@ -1328,9 +1330,10 @@ static int cabd_sys_read(struct mspack_file *file, void *buffer, int bytes) {
1328 1328
       /* out of data, read a new block */
1329 1329
 
1330 1330
       /* check if we're out of input blocks, advance block counter */
1331
+        //sys->message(NULL, "block num: %d", self->d->block);
1332
+        //sys->message(NULL, "folder num of blocks: %d", self->d->folder->base.num_blocks);
1331 1333
       if (self->d->block++ >= self->d->folder->base.num_blocks) {
1332
-  sys->message(NULL, "Ran out of CAB input blocks prematurely");
1333
-	self->read_error = MSPACK_ERR_DATAFORMAT;
1334
+	sys->message(NULL, "Ran out of CAB input blocks prematurely");
1334 1335
 	break;
1335 1336
       }
1336 1337
 
... ...
@@ -294,6 +294,7 @@ struct lzxd_stream *lzxd_init(struct mspack_system *system,
294 294
    * regular LZX windows are between 2^15 (32KiB) and 2^21 (2MiB)
295 295
    */
296 296
   if (is_delta) {
297
+      system->message(NULL, "Detected LZX Compression Type: DELTA");
297 298
       if (window_bits < 17 || window_bits > 25) return NULL;
298 299
   }
299 300
   else {
... ...
@@ -393,7 +394,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
393 393
   register unsigned short sym;
394 394
 
395 395
   int match_length, length_footer, extra, verbatim_bits, bytes_todo;
396
-  int this_run, main_element, aligned_bits, j;
396
+  int this_run, main_element, aligned_bits, j, warned = 0;
397 397
   unsigned char *window, *runsrc, *rundest, buf[12];
398 398
   unsigned int frame_size=0, end_frame, match_offset, window_posn;
399 399
   unsigned int R0, R1, R2;
... ...
@@ -404,7 +405,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
404 404
 
405 405
   /* flush out any stored-up bytes before we begin */
406 406
   i = lzx->o_end - lzx->o_ptr;
407
-  if ((off_t) i > out_bytes) i = (int) out_bytes;
407
+  if (((off_t) i > out_bytes) && ((int) out_bytes >= 0)) i = (int) out_bytes;
408 408
   if (i) {
409 409
     if (lzx->sys->write(lzx->output, lzx->o_ptr, i) != i) {
410 410
       return lzx->error = MSPACK_ERR_WRITE;
... ...
@@ -424,13 +425,19 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
424 424
   R2 = lzx->R2;
425 425
 
426 426
   end_frame = (unsigned int)((lzx->offset + out_bytes) / LZX_FRAME_SIZE) + 1;
427
+  lzx->sys->message(NULL, "lzx_decompress: end_frame = %u", end_frame);
427 428
 
428 429
   while (lzx->frame < end_frame) {
430
+    lzx->sys->message(NULL, "lzx_decompress: current_frame = %u", lzx->frame);
429 431
     /* have we reached the reset interval? (if there is one?) */
430 432
     if (lzx->reset_interval && ((lzx->frame % lzx->reset_interval) == 0)) {
431 433
       if (lzx->block_remaining) {
432
-	D(("%d bytes remaining at reset interval", lzx->block_remaining))
433
-	return lzx->error = MSPACK_ERR_DECRUNCH;
434
+        /* this is a file format error, but we need to extract what we can and scan that */
435
+        lzx->sys->message(NULL, "lzx_decompress: bytes remaining at reset interval", lzx->block_remaining);
436
+        if (!warned) {
437
+            lzx->sys->message(NULL, "lzx_decompress: detected an invalid reset interval during decompresion");
438
+            warned++;
439
+        }
434 440
       }
435 441
 
436 442
       /* re-read the intel header and reset the huffman lengths */
... ...
@@ -520,7 +527,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
520 520
 	  break;
521 521
 
522 522
 	default:
523
-	  D(("bad block type"))
523
+	  lzx->sys->message(NULL, "lzx_decompress: bad block type");
524 524
 	  return lzx->error = MSPACK_ERR_DECRUNCH;
525 525
 	}
526 526
       }
... ...
@@ -552,7 +559,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
552 552
 	    match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
553 553
 	    if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
554 554
 	      if (lzx->LENGTH_empty) {
555
-                D(("LENGTH symbol needed but tree is empty"))
555
+                lzx->sys->message(NULL, "lzx_decompress: LENGTH symbol needed but tree is empty");
556 556
                 return lzx->error = MSPACK_ERR_DECRUNCH;
557 557
               }
558 558
 	      READ_HUFFSYM(LENGTH, length_footer);
... ...
@@ -599,7 +606,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
599 599
 	    }
600 600
 
601 601
 	    if ((window_posn + match_length) > lzx->window_size) {
602
-	      D(("match ran over window wrap"))
602
+	      lzx->sys->message(NULL, "lzx_decompress: match ran over window wrap");
603 603
 	      return lzx->error = MSPACK_ERR_DECRUNCH;
604 604
 	    }
605 605
 	    
... ...
@@ -611,13 +618,13 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
611 611
 	      if (match_offset > lzx->offset &&
612 612
 		  (match_offset - window_posn) > lzx->ref_data_size)
613 613
 	      {
614
-		D(("match offset beyond LZX stream"))
614
+		lzx->sys->message(NULL, "lzx_decompress: match offset beyond LZX stream");
615 615
 		return lzx->error = MSPACK_ERR_DECRUNCH;
616 616
 	      }
617 617
 	      /* j = length from match offset to end of window */
618 618
 	      j = match_offset - window_posn;
619 619
 	      if (j > (int) lzx->window_size) {
620
-		D(("match offset beyond window boundaries"))
620
+		lzx->sys->message(NULL, "lzx_decompress: match offset beyond window boundaries");
621 621
 		return lzx->error = MSPACK_ERR_DECRUNCH;
622 622
 	      }
623 623
 	      runsrc = &window[lzx->window_size - j];
... ...
@@ -655,7 +662,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
655 655
 	    match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
656 656
 	    if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
657 657
               if (lzx->LENGTH_empty) {
658
-                D(("LENGTH symbol needed but tree is empty"))
658
+                lzx->sys->message(NULL, "lzx_decompress: LENGTH symbol needed but tree is empty");
659 659
                 return lzx->error = MSPACK_ERR_DECRUNCH;
660 660
               } 
661 661
 	      READ_HUFFSYM(LENGTH, length_footer);
... ...
@@ -723,7 +730,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
723 723
 	    }
724 724
 
725 725
 	    if ((window_posn + match_length) > lzx->window_size) {
726
-	      D(("match ran over window wrap"))
726
+	      lzx->sys->message(NULL, "lzx_decompress: match ran over window wrap");
727 727
 	      return lzx->error = MSPACK_ERR_DECRUNCH;
728 728
 	    }
729 729
 
... ...
@@ -735,13 +742,13 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
735 735
 	      if (match_offset > lzx->offset &&
736 736
 		  (match_offset - window_posn) > lzx->ref_data_size)
737 737
 	      {
738
-		D(("match offset beyond LZX stream"))
738
+		lzx->sys->message(NULL, "lzx_decompress: match offset beyond LZX stream");
739 739
 		return lzx->error = MSPACK_ERR_DECRUNCH;
740 740
 	      }
741 741
 	      /* j = length from match offset to end of window */
742 742
 	      j = match_offset - window_posn;
743 743
 	      if (j > (int) lzx->window_size) {
744
-		D(("match offset beyond window boundaries"))
744
+		lzx->sys->message(NULL, "lzx_decompress: match offset beyond window boundaries");
745 745
 		return lzx->error = MSPACK_ERR_DECRUNCH;
746 746
 	      }
747 747
 	      runsrc = &window[lzx->window_size - j];
... ...
@@ -767,7 +774,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
767 767
 	/* as this_run is limited not to wrap a frame, this also means it
768 768
 	 * won't wrap the window (as the window is a multiple of 32k) */
769 769
         if (window_posn + this_run > lzx->window_size) {
770
-                D(("match ran over window boundary"))
770
+                lzx->sys->message(NULL, "lzx_decompress: match ran over window boundary");
771 771
                 return lzx->error = MSPACK_ERR_DECRUNCH;
772 772
         }
773 773
 	rundest = &window[window_posn];
... ...
@@ -794,8 +801,8 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
794 794
       /* did the final match overrun our desired this_run length? */
795 795
       if (this_run < 0) {
796 796
 	if ((unsigned int)(-this_run) > lzx->block_remaining) {
797
-	  D(("overrun went past end of block by %d (%d remaining)",
798
-	     -this_run, lzx->block_remaining ))
797
+	  lzx->sys->message(NULL, "lzx_decompress: overrun went past end of block by %d (%d remaining)",
798
+	     -this_run, lzx->block_remaining );
799 799
 	  return lzx->error = MSPACK_ERR_DECRUNCH;
800 800
 	}
801 801
 	lzx->block_remaining -= -this_run;
... ...
@@ -804,8 +811,8 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
804 804
 
805 805
     /* streams don't extend over frame boundaries */
806 806
     if ((window_posn - lzx->frame_posn) != frame_size) {
807
-      D(("decode beyond output frame limits! %d != %d",
808
-	 window_posn - lzx->frame_posn, frame_size))
807
+      lzx->sys->message(NULL, "lzx_decompress: decode beyond output frame limits! %d != %d",
808
+	 window_posn - lzx->frame_posn, frame_size);
809 809
       return lzx->error = MSPACK_ERR_DECRUNCH;
810 810
     }
811 811
 
... ...
@@ -815,8 +822,8 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
815 815
 
816 816
     /* check that we've used all of the previous frame first */
817 817
     if (lzx->o_ptr != lzx->o_end) {
818
-      D(("%ld avail bytes, new %d frame",
819
-          (long)(lzx->o_end - lzx->o_ptr), frame_size))
818
+       lzx->sys->message(NULL, "lzx_decompress: %ld avail bytes, new %d frame",
819
+          (long)(lzx->o_end - lzx->o_ptr), frame_size);
820 820
       return lzx->error = MSPACK_ERR_DECRUNCH;
821 821
     }
822 822
 
... ...
@@ -875,7 +882,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
875 875
   } /* while (lzx->frame < end_frame) */
876 876
 
877 877
   if (out_bytes) {
878
-    D(("bytes left to output"))
878
+    lzx->sys->message(NULL, "lzx_decompress: bytes left to output");
879 879
     return lzx->error = MSPACK_ERR_DECRUNCH;
880 880
   }
881 881