Browse code

improve handling of SFX CAB archives

git-svn: trunk@3131

Tomasz Kojm authored on 2007/07/11 07:01:30
Showing 3 changed files
... ...
@@ -1,3 +1,7 @@
1
+Tue Jul 10 23:06:14 CEST 2007 (tk)
2
+----------------------------------
3
+  * libclamav: improve handling of SFX CAB archives
4
+
1 5
 Tue Jul 10 22:36:35 CEST 2007 (tk)
2 6
 ----------------------------------
3 7
   * libclamav/ole2_extract.c: faster handling of corrupted files (bb#561)
... ...
@@ -636,8 +636,19 @@ int cab_extract(struct cab_file *file, const char *name)
636 636
 	    }
637 637
 	    if(file->offset > 0) {
638 638
 		((struct mszip_stream *) file->state->stream)->wflag = 0;
639
-		mszip_decompress(file->state->stream, file->offset);
639
+		ret = mszip_decompress(file->state->stream, file->offset);
640 640
 		((struct mszip_stream *) file->state->stream)->wflag = 1;
641
+		if(ret < 0) {
642
+		    mszip_free(file->state->stream);
643
+		    memset(file->state, 0, sizeof(struct cab_state));
644
+		    file->state->stream = (struct mszip_stream *) mszip_init(file->fd, file->ofd, 4096, 1, file, &cab_read);
645
+		    if(!file->state->stream) {
646
+			free(file->state);
647
+			close(file->ofd);
648
+			return CL_EMSCAB;
649
+		    }
650
+                    lseek(file->fd, file->folder->offset, SEEK_SET);
651
+		}
641 652
 	    }
642 653
 	    ret = mszip_decompress(file->state->stream, file->length);
643 654
 	    mszip_free(file->state->stream);
... ...
@@ -670,8 +681,19 @@ int cab_extract(struct cab_file *file, const char *name)
670 670
 	    }
671 671
 	    if(file->offset > 0) {
672 672
 		((struct lzx_stream *) file->state->stream)->wflag = 0;
673
-		lzx_decompress(file->state->stream, file->offset);
673
+		ret = lzx_decompress(file->state->stream, file->offset);
674 674
 		((struct lzx_stream *) file->state->stream)->wflag = 1;
675
+		if(ret < 0) {
676
+		    lzx_free(file->state->stream);
677
+		    memset(file->state, 0, sizeof(struct cab_state));
678
+		    file->state->stream = (struct lzx_stream *) lzx_init(file->fd, file->ofd, (int) (file->folder->cmethod >> 8) & 0x1f, 0, 4096, 0, file, &cab_read);
679
+		    if(!file->state->stream) {
680
+			free(file->state);
681
+			close(file->ofd);
682
+			return CL_EMSCAB;
683
+		    }
684
+                    lseek(file->fd, file->folder->offset, SEEK_SET);
685
+		}
675 686
 	    }
676 687
 	    ret = lzx_decompress(file->state->stream, file->length);
677 688
 	    lzx_free(file->state->stream);
... ...
@@ -271,8 +271,13 @@ static int mszip_make_decode_table(unsigned int nsyms, unsigned int nbits,
271 271
         cli_dbgmsg("zip_inflate: out of bits in huffman decode\n");	\
272 272
         return INF_ERR_HUFFSYM;                                         \
273 273
       }                                                                 \
274
+      sym = (sym << 1) | ((bit_buffer >> i) & 1);			\
275
+      if(sym >= MSZIP_##tbl##_TABLESIZE) {				\
276
+	cli_dbgmsg("zip_inflate: index out of table\n");		\
277
+        return INF_ERR_HUFFSYM;                                         \
278
+      }									\
274 279
       /* double node index and add 0 (left branch) or 1 (right) */	\
275
-      sym = zip->tbl##_table[(sym << 1) | ((bit_buffer >> i) & 1)];	\
280
+      sym = zip->tbl##_table[sym];					\
276 281
       /* while we are still in node indicies, not decoded symbols */    \
277 282
     } while (sym >= MSZIP_##tbl##_MAXSYMBOLS);                          \
278 283
   }                                                                     \
... ...
@@ -798,7 +803,11 @@ static int lzx_read_input(struct lzx_stream *lzx) {
798 798
       /* double node index and add 0 (left branch) or 1 (right) */      \
799 799
       sym <<= 1; sym |= (bit_buffer & i) ? 1 : 0;                       \
800 800
       /* hop to next node index / decoded symbol */                     \
801
-      sym = lzx->tbl##_table[sym];                                      \
801
+      if(sym >= (1 << LZX_##tbl##_TABLEBITS) + (LZX_##tbl##_MAXSYMBOLS * 2)) { \
802
+	cli_dbgmsg("lzx: index out of table\n");			\
803
+	return lzx->error = CL_EFORMAT;					\
804
+      }									\
805
+      sym = lzx->tbl##_table[sym];                                    \
802 806
       /* while we are still in node indicies, not decoded symbols */    \
803 807
     } while (sym >= LZX_##tbl##_MAXSYMBOLS);                            \
804 808
   }                                                                     \