git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@234 77e5149b-7576-45b1-b177-96237e5ba77b
Nigel Horne authored on 2004/02/03 23:38:03... | ... |
@@ -1,3 +1,9 @@ |
1 |
+Tue Feb 3 14:38:04 GMT 2004 (njh) |
|
2 |
+---------------------------------- |
|
3 |
+ * libclamav: Speeded up binhex decoding using table look up |
|
4 |
+ Fixed possible infinite loop when decoding compressed binhex |
|
5 |
+ Both fixes thanks to Thomas Lamy <Thomas.Lamy@in-online.net> |
|
6 |
+ |
|
1 | 7 |
Tue Feb 3 02:31:55 CET 2004 (tk) |
2 | 8 |
--------------------------------- |
3 | 9 |
* libclamav: + don't report errors when archive limits are reached |
... | ... |
@@ -17,6 +17,9 @@ |
17 | 17 |
* |
18 | 18 |
* Change History: |
19 | 19 |
* $Log: message.c,v $ |
20 |
+ * Revision 1.21 2004/02/03 14:35:37 nigelhorne |
|
21 |
+ * Fixed an infinite loop on binhex |
|
22 |
+ * |
|
20 | 23 |
* Revision 1.20 2004/02/02 17:10:04 nigelhorne |
21 | 24 |
* Scan a rare form of bounce message |
22 | 25 |
* |
... | ... |
@@ -57,7 +60,7 @@ |
57 | 57 |
* uuencodebegin() no longer static |
58 | 58 |
* |
59 | 59 |
*/ |
60 |
-static char const rcsid[] = "$Id: message.c,v 1.20 2004/02/02 17:10:04 nigelhorne Exp $"; |
|
60 |
+static char const rcsid[] = "$Id: message.c,v 1.21 2004/02/03 14:35:37 nigelhorne Exp $"; |
|
61 | 61 |
|
62 | 62 |
#ifndef CL_DEBUG |
63 | 63 |
/*#define NDEBUG /* map CLAMAV debug onto standard */ |
... | ... |
@@ -661,39 +664,41 @@ messageToBlob(const message *m) |
661 | 661 |
*/ |
662 | 662 |
if(data[0] == ':') { |
663 | 663 |
char *ptr; |
664 |
- unsigned long newlen = 0L; |
|
665 | 664 |
int bytenumber = 0; |
665 |
+ unsigned long newlen = 0L; |
|
666 |
+ const unsigned char hqxtbl[] = { |
|
667 |
+ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f */ |
|
668 |
+ /* 00-0f */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
|
669 |
+ /* 10-1f */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
|
670 |
+ /* 20-2f */ 0xff,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0xff,0xff, |
|
671 |
+ /* 30-3f */ 0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0xff,0x14,0x15,0xff,0xff,0xff,0xff,0xff,0xff, |
|
672 |
+ /* 40-4f */ 0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0xff, |
|
673 |
+ /* 50-5f */ 0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0xff,0x2c,0x2d,0x2e,0x2f,0xff,0xff,0xff,0xff, |
|
674 |
+ /* 60-6f */ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0xff,0x37,0x38,0x39,0x3a,0x3b,0x3c,0xff,0xff, |
|
675 |
+ /* 70-7f */ 0x3d,0x3e,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
|
676 |
+ }; |
|
666 | 677 |
|
667 | 678 |
/* |
668 | 679 |
* Convert 7 bit data into 8 bit |
669 | 680 |
*/ |
670 |
- cli_dbgmsg("decode HQX7 message"); |
|
681 |
+ cli_dbgmsg("decode HQX7 message (%d bytes)\n", len); |
|
671 | 682 |
|
672 | 683 |
ptr = cli_malloc(len); |
673 | 684 |
memcpy(ptr, data, len); |
674 | 685 |
|
675 | 686 |
for(l = 1; l < len; l++) { |
676 | 687 |
unsigned char c = ptr[l]; |
677 |
- const unsigned char *tptr; |
|
678 |
- |
|
679 |
- /* TODO: table look up would be quicker */ |
|
680 |
- const unsigned char table[] = |
|
681 |
- "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr"; |
|
682 | 688 |
|
683 | 689 |
if((c == '\n') || (c == '\r')) |
684 | 690 |
continue; |
685 | 691 |
if(c == ':') |
686 | 692 |
break; |
687 |
- /* |
|
688 |
- * TODO: at least post a sentinal! |
|
689 |
- */ |
|
690 |
- for(tptr = table; (*tptr != c) && (*tptr != '\0'); tptr++) |
|
691 |
- ; |
|
692 |
- if(*tptr == '\0') { |
|
693 |
- cli_warnmsg("Invalid HQX7 character '%c'\n", c); |
|
693 |
+ |
|
694 |
+ if((c < 0x20) || (c > 0x7f) || (hqxtbl[c] == 0xff)) { |
|
695 |
+ cli_warnmsg("Invalid HQX7 character '%c' (0x%02x)\n", c, c); |
|
694 | 696 |
break; |
695 | 697 |
} |
696 |
- c = (unsigned char)(tptr - table); |
|
698 |
+ c = hqxtbl[c]; |
|
697 | 699 |
assert(c <= 63); |
698 | 700 |
|
699 | 701 |
/* |
... | ... |
@@ -721,6 +726,7 @@ messageToBlob(const message *m) |
721 | 721 |
break; |
722 | 722 |
} |
723 | 723 |
} |
724 |
+ cli_dbgmsg("decoded HQX7 message (now %d bytes)\n", newlen); |
|
724 | 725 |
free(ptr); |
725 | 726 |
} else { |
726 | 727 |
/* |
... | ... |
@@ -747,6 +753,10 @@ messageToBlob(const message *m) |
747 | 747 |
* skip over length, filename, version, type, creator and flags |
748 | 748 |
*/ |
749 | 749 |
byte = 1 + byte + 1 + 4 + 4 + 2; |
750 |
+ |
|
751 |
+ /* |
|
752 |
+ * Set len to be the data fork length |
|
753 |
+ */ |
|
750 | 754 |
len = (data[byte] << 24) + (data[byte + 1] << 16) + (data[byte + 2] << 8) + data[byte + 3]; |
751 | 755 |
|
752 | 756 |
/* |
... | ... |
@@ -756,11 +766,14 @@ messageToBlob(const message *m) |
756 | 756 |
data = &data[byte]; |
757 | 757 |
|
758 | 758 |
/* |
759 |
- * Check for compression of repetitive characters |
|
759 |
+ * Check for compression of repetitive characters in |
|
760 |
+ * the data fork |
|
760 | 761 |
*/ |
761 | 762 |
if(memchr(data, 0x90, len)) |
762 | 763 |
/* |
763 | 764 |
* Includes compression |
765 |
+ * TODO: sections of data that are not compressed |
|
766 |
+ * can be added to the blob all at once |
|
764 | 767 |
*/ |
765 | 768 |
for(l = 0; l < len; l++) { |
766 | 769 |
unsigned char c = data[l]; |
... | ... |
@@ -773,19 +786,22 @@ messageToBlob(const message *m) |
773 | 773 |
|
774 | 774 |
l += 2; |
775 | 775 |
count = data[l]; |
776 |
+ cli_dbgmsg("uncompress HQX7 at 0x%06x: %d repetitive bytes\n", l, count); |
|
776 | 777 |
|
777 | 778 |
if(count == 0) { |
778 | 779 |
c = 0x90; |
779 | 780 |
blobAddData(b, &c, 1); |
780 |
- } else while(--l > 0) |
|
781 |
+ } else while(--count > 0) |
|
781 | 782 |
blobAddData(b, &c, 1); |
782 | 783 |
} |
783 | 784 |
} |
784 |
- else |
|
785 |
+ else { |
|
785 | 786 |
/* |
786 | 787 |
* No compression - quickly copy all across |
787 | 788 |
*/ |
789 |
+ cli_dbgmsg("HQX7 message is not compressed...\n"); |
|
788 | 790 |
blobAddData(b, data, len); |
791 |
+ } |
|
789 | 792 |
|
790 | 793 |
blobDestroy(tmp); |
791 | 794 |
|