Mercurial > libpst
annotate src/lzfu.c @ 146:0695de3b5a98 stable-0-6-29
fix for 64bit on Fedora 11
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Tue, 24 Feb 2009 15:32:56 -0800 |
parents | e35fd42bac05 |
children | 6954d315aaa8 |
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 | |
122
bdb38b434c0a
more changes from Fridrich Strba to avoid installing our config.h
Carl Byington <carl@five-ten-sg.com>
parents:
120
diff
changeset
|
12 #include "define.h" |
120
6395ced2b8b2
disable building pst2dii on cygwin
Carl Byington <carl@five-ten-sg.com>
parents:
85
diff
changeset
|
13 #include "lzfu.h" |
48 | 14 |
16 | 15 |
36 | 16 #define LZFU_COMPRESSED 0x75465a4c |
17 #define LZFU_UNCOMPRESSED 0x414c454d | |
16 | 18 |
19 // initital dictionary | |
36 | 20 #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
|
21 "{\\f0\\fnil \\froman \\fswiss \\fmodern \\fscrip" \ |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
22 "t \\fdecor MS Sans SerifSymbolArialTimes Ne" \ |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
23 "w RomanCourier{\\colortbl\\red0\\green0\\blue0" \ |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
24 "\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
|
25 "\\tx" |
16 | 26 // initial length of dictionary |
27 #define LZFU_INITLENGTH 207 | |
28 | |
29 // header for compressed rtf | |
30 typedef struct _lzfuheader { | |
43 | 31 uint32_t cbSize; |
32 uint32_t cbRawSize; | |
33 uint32_t dwMagic; | |
34 uint32_t dwCRC; | |
16 | 35 } lzfuheader; |
36 | |
37 | |
79
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
78
diff
changeset
|
38 char* lzfu_decompress(char* rtfcomp, uint32_t compsize, size_t *size) { |
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
78
diff
changeset
|
39 unsigned char dict[4096]; // the dictionary buffer |
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
78
diff
changeset
|
40 unsigned int dict_length = 0; // the dictionary pointer |
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
78
diff
changeset
|
41 lzfuheader lzfuhdr; // the header of the lzfu block |
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
78
diff
changeset
|
42 unsigned char flags; // 8 bits of flags (1=2byte block pointer into the dict, 0=1 byte literal) |
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
78
diff
changeset
|
43 unsigned char flag_mask; // look at one flag bit each time thru the loop |
43 | 44 uint32_t i; |
79
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
78
diff
changeset
|
45 char *out_buf; |
43 | 46 uint32_t out_ptr = 0; |
47 uint32_t out_size; | |
48 uint32_t in_ptr; | |
49 uint32_t in_size; | |
16 | 50 |
36 | 51 memcpy(dict, LZFU_INITDICT, LZFU_INITLENGTH); |
79
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
78
diff
changeset
|
52 memset(dict + LZFU_INITLENGTH, 0, sizeof(dict) - LZFU_INITLENGTH); |
36 | 53 dict_length = LZFU_INITLENGTH; |
79
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
78
diff
changeset
|
54 |
36 | 55 memcpy(&lzfuhdr, rtfcomp, sizeof(lzfuhdr)); |
37 | 56 LE32_CPU(lzfuhdr.cbSize); |
57 LE32_CPU(lzfuhdr.cbRawSize); | |
58 LE32_CPU(lzfuhdr.dwMagic); | |
59 LE32_CPU(lzfuhdr.dwCRC); | |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
60 //printf("total size: %d\n", lzfuhdr.cbSize+4); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
61 //printf("raw size : %d\n", lzfuhdr.cbRawSize); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
62 //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
|
63 //printf("CRC : %#x\n", lzfuhdr.dwCRC); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
64 //printf("\n"); |
78
535075b4d261
Patch from Joachim Metz for debian packaging, and fix for incorrect length on lz decompression.
Carl Byington <carl@five-ten-sg.com>
parents:
73
diff
changeset
|
65 out_size = lzfuhdr.cbRawSize; |
73
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
66 out_buf = (char*)xmalloc(out_size); |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
67 in_ptr = sizeof(lzfuhdr); |
78
535075b4d261
Patch from Joachim Metz for debian packaging, and fix for incorrect length on lz decompression.
Carl Byington <carl@five-ten-sg.com>
parents:
73
diff
changeset
|
68 // Make sure to correct lzfuhdr.cbSize with 4 bytes before comparing |
535075b4d261
Patch from Joachim Metz for debian packaging, and fix for incorrect length on lz decompression.
Carl Byington <carl@five-ten-sg.com>
parents:
73
diff
changeset
|
69 // to compsize |
535075b4d261
Patch from Joachim Metz for debian packaging, and fix for incorrect length on lz decompression.
Carl Byington <carl@five-ten-sg.com>
parents:
73
diff
changeset
|
70 in_size = (lzfuhdr.cbSize + 4 < compsize) ? lzfuhdr.cbSize + 4 : compsize; |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
71 while (in_ptr < in_size) { |
73
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
72 flags = (unsigned char)(rtfcomp[in_ptr++]); |
36 | 73 flag_mask = 1; |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
74 while (flag_mask) { |
36 | 75 if (flag_mask & flags) { |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
76 // two bytes available? |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
77 if (in_ptr+1 < in_size) { |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
78 // read 2 bytes from input |
130
e35fd42bac05
more cleanup of include files
Carl Byington <carl@five-ten-sg.com>
parents:
129
diff
changeset
|
79 uint16_t blkhdr, offset, length; |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
80 memcpy(&blkhdr, rtfcomp+in_ptr, 2); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
81 LE16_CPU(blkhdr); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
82 in_ptr += 2; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
83 /* swap the upper and lower bytes of blkhdr */ |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
84 blkhdr = (((blkhdr&0xFF00)>>8)+ |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
85 ((blkhdr&0x00FF)<<8)); |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
86 /* 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
|
87 offset = (blkhdr&0xFFF0)>>4; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
88 /* 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
|
89 length = (blkhdr&0x000F)+2; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
90 // 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
|
91 for (i=0; i < length; i++) { |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
92 unsigned char c1; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
93 c1 = dict[(offset+i)%4096]; |
79
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
78
diff
changeset
|
94 dict[dict_length] = c1; |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
95 dict_length = (dict_length+1) % 4096; |
73
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
96 if (out_ptr < out_size) out_buf[out_ptr++] = (char)c1; |
78
535075b4d261
Patch from Joachim Metz for debian packaging, and fix for incorrect length on lz decompression.
Carl Byington <carl@five-ten-sg.com>
parents:
73
diff
changeset
|
97 // required for dictionary wrap around |
535075b4d261
Patch from Joachim Metz for debian packaging, and fix for incorrect length on lz decompression.
Carl Byington <carl@five-ten-sg.com>
parents:
73
diff
changeset
|
98 // otherwise 0 byte values are referenced incorrectly |
535075b4d261
Patch from Joachim Metz for debian packaging, and fix for incorrect length on lz decompression.
Carl Byington <carl@five-ten-sg.com>
parents:
73
diff
changeset
|
99 dict[dict_length] = 0; |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
100 } |
36 | 101 } |
102 } else { | |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
103 // one byte available? |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
104 if (in_ptr < in_size) { |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
105 // uncompressed chunk (single byte) |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
106 char c1 = rtfcomp[in_ptr++]; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
107 dict[dict_length] = c1; |
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
37
diff
changeset
|
108 dict_length = (dict_length+1)%4096; |
73
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
109 if (out_ptr < out_size) out_buf[out_ptr++] = (char)c1; |
78
535075b4d261
Patch from Joachim Metz for debian packaging, and fix for incorrect length on lz decompression.
Carl Byington <carl@five-ten-sg.com>
parents:
73
diff
changeset
|
110 // required for dictionary wrap around |
535075b4d261
Patch from Joachim Metz for debian packaging, and fix for incorrect length on lz decompression.
Carl Byington <carl@five-ten-sg.com>
parents:
73
diff
changeset
|
111 // otherwise 0 byte values are referenced incorrect |
535075b4d261
Patch from Joachim Metz for debian packaging, and fix for incorrect length on lz decompression.
Carl Byington <carl@five-ten-sg.com>
parents:
73
diff
changeset
|
112 dict[dict_length] = 0; |
41
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 } |
85
582e927756d3
Patch from Robert Simpson for file handle leak in error case.
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
118 *size = out_ptr; |
36 | 119 return out_buf; |
16 | 120 } |