Mercurial > libpst
annotate src/lzfu.c @ 60:97b7706bdda2
Work around bogus 7c.b5 blocks in some messages that have been read.
They appear to have attachments, but of some unknown format.
Before the message was read, it did not have any attachments.
Use autoscan to cleanup our autoconf system.
Use autoconf to detect when we need to use our XGetopt files
and other header files.
More fields, including BCC.
Fix missing LE32_CPU byte swapping for FILETIME types.
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Sat, 16 Feb 2008 12:26:35 -0800 |
parents | f66078abed38 |
children | 3cb02cb1e6cd |
rev | line source |
---|---|
16 | 1 /* |
36 | 2 This program is free software; you can redistribute it and/or modify |
3 it under the terms of the GNU General Public License as published by | |
4 the Free Software Foundation; either version 2 of the License, or | |
5 (at your option) any later version. | |
16 | 6 |
36 | 7 You should have received a copy of the GNU General Public License |
8 along with this program; if not, write to the Free Software Foundation, | |
9 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | |
16 | 10 */ |
11 | |
12 #include "define.h" | |
13 #include "libpst.h" | |
48 | 14 |
16 | 15 #include <sys/types.h> |
16 #include <string.h> | |
17 #include <stdio.h> | |
18 | |
19 #include "lzfu.h" | |
20 | |
36 | 21 #define LZFU_COMPRESSED 0x75465a4c |
22 #define LZFU_UNCOMPRESSED 0x414c454d | |
16 | 23 |
24 // initital dictionary | |
36 | 25 #define LZFU_INITDICT "{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}" \ |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
26 "{\\f0\\fnil \\froman \\fswiss \\fmodern \\fscrip" \ |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
27 "t \\fdecor MS Sans SerifSymbolArialTimes Ne" \ |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
28 "w RomanCourier{\\colortbl\\red0\\green0\\blue0" \ |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
29 "\r\n\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab" \ |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
30 "\\tx" |
16 | 31 // initial length of dictionary |
32 #define LZFU_INITLENGTH 207 | |
33 | |
34 // header for compressed rtf | |
35 typedef struct _lzfuheader { | |
43 | 36 uint32_t cbSize; |
37 uint32_t cbRawSize; | |
38 uint32_t dwMagic; | |
39 uint32_t dwCRC; | |
16 | 40 } lzfuheader; |
41 | |
42 | |
43 | 43 unsigned char* lzfu_decompress (unsigned char* rtfcomp, uint32_t compsize, size_t *size) { |
36 | 44 // the dictionary buffer |
45 unsigned char dict[4096]; | |
46 // the dictionary pointer | |
47 unsigned int dict_length=0; | |
48 // the header of the lzfu block | |
49 lzfuheader lzfuhdr; | |
50 // container for the data blocks | |
51 unsigned char flags; | |
52 // temp value for determining the bits in the flag | |
53 unsigned char flag_mask; | |
43 | 54 uint32_t i; |
36 | 55 unsigned char *out_buf; |
43 | 56 uint32_t out_ptr = 0; |
57 uint32_t out_size; | |
58 uint32_t in_ptr; | |
59 uint32_t in_size; | |
16 | 60 |
36 | 61 memcpy(dict, LZFU_INITDICT, LZFU_INITLENGTH); |
62 dict_length = LZFU_INITLENGTH; | |
63 memcpy(&lzfuhdr, rtfcomp, sizeof(lzfuhdr)); | |
37 | 64 LE32_CPU(lzfuhdr.cbSize); |
65 LE32_CPU(lzfuhdr.cbRawSize); | |
66 LE32_CPU(lzfuhdr.dwMagic); | |
67 LE32_CPU(lzfuhdr.dwCRC); | |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
68 //printf("total size: %d\n", lzfuhdr.cbSize+4); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
69 //printf("raw size : %d\n", lzfuhdr.cbRawSize); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
70 //printf("compressed: %s\n", (lzfuhdr.dwMagic == LZFU_COMPRESSED ? "yes" : "no")); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
71 //printf("CRC : %#x\n", lzfuhdr.dwCRC); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
72 //printf("\n"); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
73 out_size = lzfuhdr.cbRawSize + 3; // two braces and a null terminator |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
74 out_buf = (unsigned char*)xmalloc(out_size); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
75 in_ptr = sizeof(lzfuhdr); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
76 in_size = (lzfuhdr.cbSize < compsize) ? lzfuhdr.cbSize : compsize; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
77 while (in_ptr < in_size) { |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
78 flags = rtfcomp[in_ptr++]; |
36 | 79 flag_mask = 1; |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
80 while (flag_mask) { |
36 | 81 if (flag_mask & flags) { |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
82 // two bytes available? |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
83 if (in_ptr+1 < in_size) { |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
84 // read 2 bytes from input |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
85 unsigned short int blkhdr, offset, length; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
86 memcpy(&blkhdr, rtfcomp+in_ptr, 2); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
87 LE16_CPU(blkhdr); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
88 in_ptr += 2; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
89 /* swap the upper and lower bytes of blkhdr */ |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
90 blkhdr = (((blkhdr&0xFF00)>>8)+ |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
91 ((blkhdr&0x00FF)<<8)); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
92 /* the offset is the first 12 bits of the 16 bit value */ |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
93 offset = (blkhdr&0xFFF0)>>4; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
94 /* the length of the dict entry are the last 4 bits */ |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
95 length = (blkhdr&0x000F)+2; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
96 // add the value we are about to print to the dictionary |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
97 for (i=0; i < length; i++) { |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
98 unsigned char c1; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
99 c1 = dict[(offset+i)%4096]; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
100 dict[dict_length]=c1; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
101 dict_length = (dict_length+1) % 4096; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
102 if (out_ptr < out_size) out_buf[out_ptr++] = c1; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
103 } |
36 | 104 } |
105 } else { | |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
106 // one byte available? |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
107 if (in_ptr < in_size) { |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
108 // uncompressed chunk (single byte) |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
109 char c1 = rtfcomp[in_ptr++]; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
110 dict[dict_length] = c1; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
111 dict_length = (dict_length+1)%4096; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
112 if (out_ptr < out_size) out_buf[out_ptr++] = c1; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
113 } |
36 | 114 } |
115 flag_mask <<= 1; | |
116 } | |
16 | 117 } |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
118 // the compressed version doesn't appear to drop the closing |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
119 // braces onto the doc, so we do that here. |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
120 if (out_ptr < out_size) out_buf[out_ptr++] = '}'; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
121 if (out_ptr < out_size) out_buf[out_ptr++] = '}'; |
37 | 122 *size = out_ptr; |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
123 if (out_ptr < out_size) out_buf[out_ptr++] = '\0'; |
36 | 124 return out_buf; |
16 | 125 } |