Browse code

check in 0.93 patches

git-svn: trunk@3788

Tomasz Kojm authored on 2008/04/15 05:13:05
Showing 71 changed files
... ...
@@ -1,3 +1,13 @@
1
+Mon Apr 14 21:35:11 CEST 2008 (tk)
2
+----------------------------------
3
+  * Check in 0.93 patches:
4
+    - libclamunrar: bb#541 (RAR - Version required to extract - Evasion)
5
+    - libclamav/spin.c: bb#876 (PeSpin Heap Overflow Vulnerability)
6
+    - libclamav/pe.c: bb#878 (Upack Buffer Overflow Vulnerability)
7
+    - libclamav/message.c: bb#881 (message.c: read beyond allocated region)
8
+    - libclamav/unarj.c: bb#897 (ARJ: Sample from CERT-FI hangs clamav)
9
+    - libclamunrar: bb#898 (RAR crashes on some fuzzed files from CERT-FI)
10
+
1 11
 Mon Apr 14 13:19:17 CEST 2008 (tk)
2 12
 ----------------------------------
3 13
   * test: add clam-aspack.exe, clam-pespin.exe and clam-upx.exe (bb#902)
... ...
@@ -1,5 +1,5 @@
1
-0.93rc1
1
+0.93
2
+----
2 3
 
3 4
 This release introduces many new features and engine enhancements, please
4 5
 see the notes below for the list of major changes. The most visible one
... ...
@@ -2,8 +2,8 @@ Note: This README/NEWS file refers to the source tarball. Some things described
2 2
 here may not be available in binary packages.
3 3
 --
4 4
 
5
-0.93rc1
5
+0.93
6
+----
6 7
 
7 8
 This release introduces many new features and engine enhancements, please
8 9
 see the notes below for the list of major changes. The most visible one
... ...
@@ -45,7 +45,7 @@ dnl VERSION="0.93rc1"
45 45
 AC_DEFINE_UNQUOTED([VERSION],"$VERSION",[Version number of package])
46 46
 
47 47
 LC_CURRENT=4
48
-LC_REVISION=0
48
+LC_REVISION=1
49 49
 LC_AGE=0
50 50
 LIBCLAMAV_VERSION="$LC_CURRENT":"$LC_REVISION":"$LC_AGE"
51 51
 AC_SUBST([LIBCLAMAV_VERSION])
52 52
Binary files a/docs/clamdoc.pdf and b/docs/clamdoc.pdf differ
... ...
@@ -71,7 +71,7 @@
71 71
     \vspace{3cm}
72 72
     \begin{flushright}
73 73
 	\rule[-1ex]{8cm}{3pt}\\
74
-	\huge Clam AntiVirus 0.93rc1\\
74
+	\huge Clam AntiVirus 0.93\\
75 75
 	\huge \emph{User Manual}\\
76 76
     \end{flushright}
77 77
 
... ...
@@ -56,7 +56,7 @@ original version by:  Nikos Drakos, CBLU, University of Leeds
56 56
 <BR>
57 57
 <BR>
58 58
     <DIV ALIGN="RIGHT">
59
-<BR>	<BIG CLASS="HUGE">Clam AntiVirus 0.93rc1
59
+<BR>	<BIG CLASS="HUGE">Clam AntiVirus 0.93
60 60
 <BR>	<BIG CLASS="HUGE"><SPAN  CLASS="textit">User Manual</SPAN>
61 61
 <BR>    
62 62
 </BIG></BIG></DIV>
... ...
@@ -209,7 +209,7 @@ original version by:  Nikos Drakos, CBLU, University of Leeds
209 209
 <BR><HR>
210 210
 <ADDRESS>
211 211
 Tomasz Kojm
212
-2008-03-18
212
+2008-04-09
213 213
 </ADDRESS>
214 214
 </BODY>
215 215
 </HTML>
... ...
@@ -56,7 +56,7 @@ original version by:  Nikos Drakos, CBLU, University of Leeds
56 56
 <BR>
57 57
 <BR>
58 58
     <DIV ALIGN="RIGHT">
59
-<BR>	<BIG CLASS="HUGE">Clam AntiVirus 0.93rc1
59
+<BR>	<BIG CLASS="HUGE">Clam AntiVirus 0.93
60 60
 <BR>	<BIG CLASS="HUGE"><SPAN  CLASS="textit">User Manual</SPAN>
61 61
 <BR>    
62 62
 </BIG></BIG></DIV>
... ...
@@ -209,7 +209,7 @@ original version by:  Nikos Drakos, CBLU, University of Leeds
209 209
 <BR><HR>
210 210
 <ADDRESS>
211 211
 Tomasz Kojm
212
-2008-03-18
212
+2008-04-09
213 213
 </ADDRESS>
214 214
 </BODY>
215 215
 </HTML>
... ...
@@ -179,7 +179,7 @@ ClamAV and Clam AntiVirus are trademarks of Sourcefire, Inc.
179 179
 <BR><HR>
180 180
 <ADDRESS>
181 181
 Tomasz Kojm
182
-2008-03-18
182
+2008-04-09
183 183
 </ADDRESS>
184 184
 </BODY>
185 185
 </HTML>
... ...
@@ -96,7 +96,7 @@ A note for Solaris/SPARC users: you must set the <SPAN  CLASS="textit">ABI</SPAN
96 96
 <BR><HR>
97 97
 <ADDRESS>
98 98
 Tomasz Kojm
99
-2008-03-18
99
+2008-04-09
100 100
 </ADDRESS>
101 101
 </BODY>
102 102
 </HTML>
... ...
@@ -75,7 +75,7 @@ Installing on shell account</A>
75 75
 <BR><HR>
76 76
 <ADDRESS>
77 77
 Tomasz Kojm
78
-2008-03-18
78
+2008-04-09
79 79
 </ADDRESS>
80 80
 </BODY>
81 81
 </HTML>
... ...
@@ -69,7 +69,7 @@ Adding new system user and group</A>
69 69
 <BR><HR>
70 70
 <ADDRESS>
71 71
 Tomasz Kojm
72
-2008-03-18
72
+2008-04-09
73 73
 </ADDRESS>
74 74
 </BODY>
75 75
 </HTML>
... ...
@@ -75,7 +75,7 @@ Compilation of base package</A>
75 75
 <BR><HR>
76 76
 <ADDRESS>
77 77
 Tomasz Kojm
78
-2008-03-18
78
+2008-04-09
79 79
 </ADDRESS>
80 80
 </BODY>
81 81
 </HTML>
... ...
@@ -64,7 +64,7 @@ Compilation with clamav-milter enabled</A>
64 64
 <BR><HR>
65 65
 <ADDRESS>
66 66
 Tomasz Kojm
67
-2008-03-18
67
+2008-04-09
68 68
 </ADDRESS>
69 69
 </BODY>
70 70
 </HTML>
... ...
@@ -83,7 +83,7 @@ Configuration</A>
83 83
 <BR><HR>
84 84
 <ADDRESS>
85 85
 Tomasz Kojm
86
-2008-03-18
86
+2008-04-09
87 87
 </ADDRESS>
88 88
 </BODY>
89 89
 </HTML>
... ...
@@ -79,7 +79,7 @@ clamd</A>
79 79
 <BR><HR>
80 80
 <ADDRESS>
81 81
 Tomasz Kojm
82
-2008-03-18
82
+2008-04-09
83 83
 </ADDRESS>
84 84
 </BODY>
85 85
 </HTML>
... ...
@@ -90,7 +90,7 @@ On-access scanning</A>
90 90
 <BR><HR>
91 91
 <ADDRESS>
92 92
 Tomasz Kojm
93
-2008-03-18
93
+2008-04-09
94 94
 </ADDRESS>
95 95
 </BODY>
96 96
 </HTML>
... ...
@@ -81,7 +81,7 @@ define(`confINPUT_MAIL_FILTERS', `clmilter')
81 81
 <BR><HR>
82 82
 <ADDRESS>
83 83
 Tomasz Kojm
84
-2008-03-18
84
+2008-04-09
85 85
 </ADDRESS>
86 86
 </BODY>
87 87
 </HTML>
... ...
@@ -75,7 +75,7 @@ Testing</A>
75 75
 <BR><HR>
76 76
 <ADDRESS>
77 77
 Tomasz Kojm
78
-2008-03-18
78
+2008-04-09
79 79
 </ADDRESS>
80 80
 </BODY>
81 81
 </HTML>
... ...
@@ -79,7 +79,7 @@ Introduction</A>
79 79
 <BR><HR>
80 80
 <ADDRESS>
81 81
 Tomasz Kojm
82
-2008-03-18
82
+2008-04-09
83 83
 </ADDRESS>
84 84
 </BODY>
85 85
 </HTML>
... ...
@@ -139,7 +139,7 @@ N * * * *	/usr/local/bin/freshclam --quiet
139 139
 <!--End of Navigation Panel-->
140 140
 <ADDRESS>
141 141
 Tomasz Kojm
142
-2008-03-18
142
+2008-04-09
143 143
 </ADDRESS>
144 144
 </BODY>
145 145
 </HTML>
... ...
@@ -77,7 +77,7 @@ Closest mirrors</A>
77 77
 <BR><HR>
78 78
 <ADDRESS>
79 79
 Tomasz Kojm
80
-2008-03-18
80
+2008-04-09
81 81
 </ADDRESS>
82 82
 </BODY>
83 83
 </HTML>
... ...
@@ -80,7 +80,7 @@ Usage</A>
80 80
 <BR><HR>
81 81
 <ADDRESS>
82 82
 Tomasz Kojm
83
-2008-03-18
83
+2008-04-09
84 84
 </ADDRESS>
85 85
 </BODY>
86 86
 </HTML>
... ...
@@ -160,7 +160,7 @@ Start/end a <code>clamd</code> session - you can do multiple commands
160 160
 <!--End of Navigation Panel-->
161 161
 <ADDRESS>
162 162
 Tomasz Kojm
163
-2008-03-18
163
+2008-04-09
164 164
 </ADDRESS>
165 165
 </BODY>
166 166
 </HTML>
... ...
@@ -76,7 +76,7 @@ Clam<SPAN  CLASS="textbf">d</SPAN>scan</A>
76 76
 <BR><HR>
77 77
 <ADDRESS>
78 78
 Tomasz Kojm
79
-2008-03-18
79
+2008-04-09
80 80
 </ADDRESS>
81 81
 </BODY>
82 82
 </HTML>
... ...
@@ -92,7 +92,7 @@ SIGTERM signal. In other case you can lose access
92 92
 <BR><HR>
93 93
 <ADDRESS>
94 94
 Tomasz Kojm
95
-2008-03-18
95
+2008-04-09
96 96
 </ADDRESS>
97 97
 </BODY>
98 98
 </HTML>
... ...
@@ -70,7 +70,7 @@ Output format</A>
70 70
 <BR><HR>
71 71
 <ADDRESS>
72 72
 Tomasz Kojm
73
-2008-03-18
73
+2008-04-09
74 74
 </ADDRESS>
75 75
 </BODY>
76 76
 </HTML>
... ...
@@ -94,7 +94,7 @@ clamscan</A>
94 94
 <BR><HR>
95 95
 <ADDRESS>
96 96
 Tomasz Kojm
97
-2008-03-18
97
+2008-04-09
98 98
 </ADDRESS>
99 99
 </BODY>
100 100
 </HTML>
... ...
@@ -83,7 +83,7 @@ Error messages are printed in the following format:
83 83
 <BR><HR>
84 84
 <ADDRESS>
85 85
 Tomasz Kojm
86
-2008-03-18
86
+2008-04-09
87 87
 </ADDRESS>
88 88
 </BODY>
89 89
 </HTML>
... ...
@@ -124,7 +124,7 @@ LibClamAV</A>
124 124
 <BR><HR>
125 125
 <ADDRESS>
126 126
 Tomasz Kojm
127
-2008-03-18
127
+2008-04-09
128 128
 </ADDRESS>
129 129
 </BODY>
130 130
 </HTML>
... ...
@@ -183,7 +183,7 @@ Features</A>
183 183
 <!--End of Navigation Panel-->
184 184
 <ADDRESS>
185 185
 Tomasz Kojm
186
-2008-03-18
186
+2008-04-09
187 187
 </ADDRESS>
188 188
 </BODY>
189 189
 </HTML>
... ...
@@ -65,7 +65,7 @@ Licence</A>
65 65
 <BR><HR>
66 66
 <ADDRESS>
67 67
 Tomasz Kojm
68
-2008-03-18
68
+2008-04-09
69 69
 </ADDRESS>
70 70
 </BODY>
71 71
 </HTML>
... ...
@@ -77,7 +77,7 @@ Supported formats</A>
77 77
 <BR><HR>
78 78
 <ADDRESS>
79 79
 Tomasz Kojm
80
-2008-03-18
80
+2008-04-09
81 81
 </ADDRESS>
82 82
 </BODY>
83 83
 </HTML>
... ...
@@ -87,7 +87,7 @@ Executables</A>
87 87
 <BR><HR>
88 88
 <ADDRESS>
89 89
 Tomasz Kojm
90
-2008-03-18
90
+2008-04-09
91 91
 </ADDRESS>
92 92
 </BODY>
93 93
 </HTML>
... ...
@@ -62,7 +62,7 @@ Mail files</A>
62 62
 <BR><HR>
63 63
 <ADDRESS>
64 64
 Tomasz Kojm
65
-2008-03-18
65
+2008-04-09
66 66
 </ADDRESS>
67 67
 </BODY>
68 68
 </HTML>
... ...
@@ -90,7 +90,7 @@ Archives and compressed files</A>
90 90
 <BR><HR>
91 91
 <ADDRESS>
92 92
 Tomasz Kojm
93
-2008-03-18
93
+2008-04-09
94 94
 </ADDRESS>
95 95
 </BODY>
96 96
 </HTML>
... ...
@@ -73,7 +73,7 @@ Documents</A>
73 73
 <BR><HR>
74 74
 <ADDRESS>
75 75
 Tomasz Kojm
76
-2008-03-18
76
+2008-04-09
77 77
 </ADDRESS>
78 78
 </BODY>
79 79
 </HTML>
... ...
@@ -75,7 +75,7 @@ Others</A>
75 75
 <BR><HR>
76 76
 <ADDRESS>
77 77
 Tomasz Kojm
78
-2008-03-18
78
+2008-04-09
79 79
 </ADDRESS>
80 80
 </BODY>
81 81
 </HTML>
... ...
@@ -75,7 +75,7 @@ API</A>
75 75
 <BR><HR>
76 76
 <ADDRESS>
77 77
 Tomasz Kojm
78
-2008-03-18
78
+2008-04-09
79 79
 </ADDRESS>
80 80
 </BODY>
81 81
 </HTML>
... ...
@@ -64,7 +64,7 @@ Header file</A>
64 64
 <BR><HR>
65 65
 <ADDRESS>
66 66
 Tomasz Kojm
67
-2008-03-18
67
+2008-04-09
68 68
 </ADDRESS>
69 69
 </BODY>
70 70
 </HTML>
... ...
@@ -111,7 +111,7 @@ Load CVD files directly without unpacking them into a temporary
111 111
 <BR><HR>
112 112
 <ADDRESS>
113 113
 Tomasz Kojm
114
-2008-03-18
114
+2008-04-09
115 115
 </ADDRESS>
116 116
 </BODY>
117 117
 </HTML>
... ...
@@ -86,7 +86,7 @@ Alternatively you can try asking on the <code>#clamav</code> IRC channel - launc
86 86
 <BR><HR>
87 87
 <ADDRESS>
88 88
 Tomasz Kojm
89
-2008-03-18
89
+2008-04-09
90 90
 </ADDRESS>
91 91
 </BODY>
92 92
 </HTML>
... ...
@@ -68,7 +68,7 @@ Error handling</A>
68 68
 <BR><HR>
69 69
 <ADDRESS>
70 70
 Tomasz Kojm
71
-2008-03-18
71
+2008-04-09
72 72
 </ADDRESS>
73 73
 </BODY>
74 74
 </HTML>
... ...
@@ -74,7 +74,7 @@ Engine structure</A>
74 74
 <BR><HR>
75 75
 <ADDRESS>
76 76
 Tomasz Kojm
77
-2008-03-18
77
+2008-04-09
78 78
 </ADDRESS>
79 79
 </BODY>
80 80
 </HTML>
... ...
@@ -101,7 +101,7 @@ Database reloading</A>
101 101
 <BR><HR>
102 102
 <ADDRESS>
103 103
 Tomasz Kojm
104
-2008-03-18
104
+2008-04-09
105 105
 </ADDRESS>
106 106
 </BODY>
107 107
 </HTML>
... ...
@@ -214,7 +214,7 @@ Phishing module: always block cloaked URLs.
214 214
 <!--End of Navigation Panel-->
215 215
 <ADDRESS>
216 216
 Tomasz Kojm
217
-2008-03-18
217
+2008-04-09
218 218
 </ADDRESS>
219 219
 </BODY>
220 220
 </HTML>
... ...
@@ -62,7 +62,7 @@ Memory</A>
62 62
 <BR><HR>
63 63
 <ADDRESS>
64 64
 Tomasz Kojm
65
-2008-03-18
65
+2008-04-09
66 66
 </ADDRESS>
67 67
 </BODY>
68 68
 </HTML>
... ...
@@ -67,7 +67,7 @@ clamav-config</A>
67 67
 <BR><HR>
68 68
 <ADDRESS>
69 69
 Tomasz Kojm
70
-2008-03-18
70
+2008-04-09
71 71
 </ADDRESS>
72 72
 </BODY>
73 73
 </HTML>
... ...
@@ -65,7 +65,7 @@ Example</A>
65 65
 <BR><HR>
66 66
 <ADDRESS>
67 67
 Tomasz Kojm
68
-2008-03-18
68
+2008-04-09
69 69
 </ADDRESS>
70 70
 </BODY>
71 71
 </HTML>
... ...
@@ -82,7 +82,7 @@ Verification OK.
82 82
 <BR><HR>
83 83
 <ADDRESS>
84 84
 Tomasz Kojm
85
-2008-03-18
85
+2008-04-09
86 86
 </ADDRESS>
87 87
 </BODY>
88 88
 </HTML>
... ...
@@ -613,7 +613,7 @@ Contributors</A>
613 613
 <!--End of Navigation Panel-->
614 614
 <ADDRESS>
615 615
 Tomasz Kojm
616
-2008-03-18
616
+2008-04-09
617 617
 </ADDRESS>
618 618
 </BODY>
619 619
 </HTML>
... ...
@@ -459,7 +459,7 @@ Donors</A>
459 459
 <!--End of Navigation Panel-->
460 460
 <ADDRESS>
461 461
 Tomasz Kojm
462
-2008-03-18
462
+2008-04-09
463 463
 </ADDRESS>
464 464
 </BODY>
465 465
 </HTML>
... ...
@@ -65,7 +65,7 @@ Virus submitting</A>
65 65
 <BR><HR>
66 66
 <ADDRESS>
67 67
 Tomasz Kojm
68
-2008-03-18
68
+2008-04-09
69 69
 </ADDRESS>
70 70
 </BODY>
71 71
 </HTML>
... ...
@@ -63,7 +63,7 @@ Graphics</A>
63 63
 <BR><HR>
64 64
 <ADDRESS>
65 65
 Tomasz Kojm
66
-2008-03-18
66
+2008-04-09
67 67
 </ADDRESS>
68 68
 </BODY>
69 69
 </HTML>
... ...
@@ -62,7 +62,7 @@ OpenAntiVirus</A>
62 62
 <BR><HR>
63 63
 <ADDRESS>
64 64
 Tomasz Kojm
65
-2008-03-18
65
+2008-04-09
66 66
 </ADDRESS>
67 67
 </BODY>
68 68
 </HTML>
... ...
@@ -134,7 +134,7 @@ Role: coder
134 134
 <BR><HR>
135 135
 <ADDRESS>
136 136
 Tomasz Kojm
137
-2008-03-18
137
+2008-04-09
138 138
 </ADDRESS>
139 139
 </BODY>
140 140
 </HTML>
... ...
@@ -64,11 +64,11 @@ Mathematics Department, Macquarie University, Sydney.
64 64
 The command line arguments were: <BR>
65 65
  <STRONG>latex2html</STRONG> <TT>-local_icons clamdoc.tex</TT>
66 66
 <P>
67
-The translation was initiated by Tomasz Kojm on 2008-03-18
67
+The translation was initiated by Tomasz Kojm on 2008-04-09
68 68
 <BR><HR>
69 69
 <ADDRESS>
70 70
 Tomasz Kojm
71
-2008-03-18
71
+2008-04-09
72 72
 </ADDRESS>
73 73
 </BODY>
74 74
 </HTML>
... ...
@@ -71,7 +71,7 @@ Base package</A>
71 71
 <BR><HR>
72 72
 <ADDRESS>
73 73
 Tomasz Kojm
74
-2008-03-18
74
+2008-04-09
75 75
 </ADDRESS>
76 76
 </BODY>
77 77
 </HTML>
... ...
@@ -80,7 +80,7 @@ Supported platforms</A>
80 80
 <BR><HR>
81 81
 <ADDRESS>
82 82
 Tomasz Kojm
83
-2008-03-18
83
+2008-04-09
84 84
 </ADDRESS>
85 85
 </BODY>
86 86
 </HTML>
... ...
@@ -61,7 +61,7 @@ Binary packages</A>
61 61
 <BR><HR>
62 62
 <ADDRESS>
63 63
 Tomasz Kojm
64
-2008-03-18
64
+2008-04-09
65 65
 </ADDRESS>
66 66
 </BODY>
67 67
 </HTML>
... ...
@@ -77,7 +77,7 @@ Installation</A>
77 77
 <BR><HR>
78 78
 <ADDRESS>
79 79
 Tomasz Kojm
80
-2008-03-18
80
+2008-04-09
81 81
 </ADDRESS>
82 82
 </BODY>
83 83
 </HTML>
... ...
@@ -2563,6 +2563,7 @@ rfc2231(const char *in)
2563 2563
 						in++;
2564 2564
 						continue;
2565 2565
 					}
2566
+					*p = '\0';
2566 2567
 					break;
2567 2568
 				case '=':
2568 2569
 					/*strcpy(p, in);*/
... ...
@@ -87,7 +87,7 @@ static pthread_mutex_t cli_ctime_mutex = PTHREAD_MUTEX_INITIALIZER;
87 87
 #define       P_tmpdir        "C:\\WINDOWS\\TEMP"
88 88
 #endif
89 89
 
90
-#define CL_FLEVEL 28 /* don't touch it */
90
+#define CL_FLEVEL 29 /* don't touch it */
91 91
 
92 92
 uint8_t cli_debug_flag = 0, cli_leavetemps_flag = 0;
93 93
 
... ...
@@ -1261,7 +1261,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1261 1261
 
1262 1262
 	    CLI_UNPSIZELIMITS("Upack", MAX(MAX(dsize, ssize), exe_sections[1].ursz));
1263 1263
 
1264
-	    if (exe_sections[1].rva - off > dsize || exe_sections[1].rva - off > dsize - exe_sections[1].ursz || (upack && (exe_sections[2].rva - exe_sections[0].rva > dsize || exe_sections[2].rva - exe_sections[0].rva > dsize - ssize)) || ssize > dsize) {
1264
+	    if (!CLI_ISCONTAINED(0, dsize, exe_sections[1].rva - off, exe_sections[1].ursz) || (upack && !CLI_ISCONTAINED(0, dsize, exe_sections[2].rva - exe_sections[0].rva, ssize)) || ssize > dsize) {
1265 1265
 	        cli_dbgmsg("Upack: probably malformed pe-header, skipping to next unpacker\n");
1266 1266
 		break;
1267 1267
 	    }
... ...
@@ -435,7 +435,7 @@ int unspin(char *src, int ssize, struct cli_exe_section *sections, int sectcnt,
435 435
     /*    len = cli_readint32(ep+0x2fc8); -- Using vsizes instead */
436 436
 
437 437
     for (j=0; j<sectcnt; j++) {
438
-      if (sections[j].rva <= key32 && sections[j].rva+sections[j].rsz > key32)
438
+      if (sections[j].rva <= key32 && key32-sections[j].rva < sections[j].vsz && CLI_ISCONTAINED(src + sections[j].raw, sections[j].rsz, src + sections[j].raw, key32 - sections[j].rva))
439 439
 	break;
440 440
     }
441 441
 
... ...
@@ -162,6 +162,7 @@ typedef struct arj_decode_tag {
162 162
 	unsigned char pt_len[NPT];
163 163
 	unsigned char sub_bit_buf;
164 164
 	uint16_t pt_table[PTABLESIZE];
165
+	int status;
165 166
 } arj_decode_t;
166 167
 
167 168
 static int fill_buf(arj_decode_t *decode_data, int n)
... ...
@@ -172,6 +173,7 @@ static int fill_buf(arj_decode_t *decode_data, int n)
172 172
 		if (decode_data->comp_size != 0) {
173 173
 			decode_data->comp_size--;
174 174
 			if (cli_readn(decode_data->fd, &decode_data->sub_bit_buf, 1) != 1) {
175
+				decode_data->status = CL_EIO;
175 176
 				return CL_EIO;
176 177
 			}
177 178
 		} else {
... ...
@@ -230,6 +232,7 @@ static int make_table(arj_decode_t *decode_data, int nchar, unsigned char *bitle
230 230
 	for (i = 0; (int)i < nchar; i++) {
231 231
 		if (bitlen[i] >= 17) {
232 232
 			cli_dbgmsg("UNARJ: bounds exceeded\n");
233
+			decode_data->status = CL_EARJ;
233 234
 			return CL_EARJ;
234 235
 		}
235 236
 		count[bitlen[i]]++;
... ...
@@ -240,12 +243,14 @@ static int make_table(arj_decode_t *decode_data, int nchar, unsigned char *bitle
240 240
 		start[i+1] = start[i] + (count[i] << (16 - i));
241 241
 	}
242 242
 	if (start[17] != (unsigned short) (1 << 16)) {
243
+		decode_data->status = CL_EARJ;
243 244
 		return CL_EARJ;
244 245
 	}
245 246
 	
246 247
 	jutbits = 16 - tablebits;
247 248
 	if (tablebits >= 17) {
248 249
 		cli_dbgmsg("UNARJ: bounds exceeded\n");
250
+		decode_data->status = CL_EARJ;
249 251
 		return CL_EARJ;
250 252
 	}
251 253
 	for (i = 1; (int)i <= tablebits; i++) {
... ...
@@ -263,6 +268,7 @@ static int make_table(arj_decode_t *decode_data, int nchar, unsigned char *bitle
263 263
 		while (i != k) {
264 264
 			if (i >= tablesize) {
265 265
 				cli_dbgmsg("UNARJ: bounds exceeded\n");
266
+				decode_data->status = CL_EARJ;
266 267
 				return CL_EARJ;
267 268
 			}
268 269
 			table[i++] = 0;
... ...
@@ -277,12 +283,14 @@ static int make_table(arj_decode_t *decode_data, int nchar, unsigned char *bitle
277 277
 		}
278 278
 		if (len >= 17) {
279 279
 			cli_dbgmsg("UNARJ: bounds exceeded\n");
280
+			decode_data->status = CL_EARJ;
280 281
 			return CL_EARJ;
281 282
 		}
282 283
 		k = start[len];
283 284
 		nextcode = k + weight[len];
284 285
 		if ((int)len <= tablebits) {
285 286
 			if (nextcode > (unsigned int) tablesize) {
287
+				decode_data->status = CL_EARJ;
286 288
 				return CL_EARJ;
287 289
 			}
288 290
 			for (i = start[len]; i < nextcode; i++) {
... ...
@@ -295,6 +303,7 @@ static int make_table(arj_decode_t *decode_data, int nchar, unsigned char *bitle
295 295
 				if (*p == 0) {
296 296
 					if (avail >= (2 * NC - 1)) {
297 297
 						cli_dbgmsg("UNARJ: bounds exceeded\n");
298
+						decode_data->status = CL_EARJ;
298 299
 						return CL_EARJ;
299 300
 					}
300 301
 					decode_data->right[avail] = decode_data->left[avail] = 0;
... ...
@@ -302,6 +311,7 @@ static int make_table(arj_decode_t *decode_data, int nchar, unsigned char *bitle
302 302
 				}
303 303
 				if (*p >= (2 * NC - 1)) {
304 304
 					cli_dbgmsg("UNARJ: bounds exceeded\n");
305
+					decode_data->status = CL_EARJ;
305 306
 					return CL_EARJ;
306 307
 				}
307 308
 				if (k & mask) {
... ...
@@ -319,7 +329,7 @@ static int make_table(arj_decode_t *decode_data, int nchar, unsigned char *bitle
319 319
 	return CL_SUCCESS;
320 320
 }
321 321
 
322
-static void read_pt_len(arj_decode_t *decode_data, int nn, int nbit, int i_special)
322
+static int read_pt_len(arj_decode_t *decode_data, int nn, int nbit, int i_special)
323 323
 {
324 324
 	int i, n;
325 325
 	short c;
... ...
@@ -329,7 +339,8 @@ static void read_pt_len(arj_decode_t *decode_data, int nn, int nbit, int i_speci
329 329
 	if (n == 0) {
330 330
 		if (nn > NPT) {
331 331
 			cli_dbgmsg("UNARJ: bounds exceeded\n");
332
-			return;
332
+			decode_data->status = CL_EARJ;
333
+			return CL_EARJ;
333 334
 		}
334 335
 		c = arj_getbits(decode_data, nbit);
335 336
 		for (i = 0; i < nn; i++) {
... ...
@@ -350,9 +361,15 @@ static void read_pt_len(arj_decode_t *decode_data, int nn, int nbit, int i_speci
350 350
 				}
351 351
 			}
352 352
 			fill_buf(decode_data, (c < 7) ? 3 : (int)(c - 3));
353
+			if (decode_data->status != CL_SUCCESS) {
354
+				return decode_data->status;
355
+			}
353 356
 			decode_data->pt_len[i++] = (unsigned char) c;
354 357
 			if (i == i_special) {
355 358
 				c = arj_getbits(decode_data, 2);
359
+				if (decode_data->status != CL_SUCCESS) {
360
+					return decode_data->status;
361
+				}
356 362
 				while ((--c >= 0) && (i < NPT)) {
357 363
 					decode_data->pt_len[i++] = 0;
358 364
 				}
... ...
@@ -361,8 +378,11 @@ static void read_pt_len(arj_decode_t *decode_data, int nn, int nbit, int i_speci
361 361
 		while ((i < nn) && (i < NPT)) {
362 362
 			decode_data->pt_len[i++] = 0;
363 363
 		}
364
-		make_table(decode_data, nn, decode_data->pt_len, 8, decode_data->pt_table, PTABLESIZE);
364
+		if (make_table(decode_data, nn, decode_data->pt_len, 8, decode_data->pt_table, PTABLESIZE) != CL_SUCCESS) {
365
+			return CL_EARJ;
366
+		}
365 367
 	}
368
+	return CL_SUCCESS;
366 369
 }
367 370
 
368 371
 static int read_c_len(arj_decode_t *decode_data)
... ...
@@ -371,8 +391,14 @@ static int read_c_len(arj_decode_t *decode_data)
371 371
 	unsigned short mask;
372 372
 	
373 373
 	n = arj_getbits(decode_data, CBIT);
374
+	if (decode_data->status != CL_SUCCESS) {
375
+		return decode_data->status;
376
+	}
374 377
 	if (n == 0) {
375 378
 		c = arj_getbits(decode_data, CBIT);
379
+		if (decode_data->status != CL_SUCCESS) {
380
+			return decode_data->status;
381
+		}
376 382
 		for (i = 0; i < NC; i++) {
377 383
 			decode_data->c_len[i] = 0;
378 384
 		}
... ...
@@ -388,6 +414,7 @@ static int read_c_len(arj_decode_t *decode_data)
388 388
 				do {
389 389
 					if (c >= (2 * NC - 1)) {
390 390
 						cli_warnmsg("ERROR: bounds exceeded\n");
391
+						decode_data->status = CL_EFORMAT;
391 392
 						return CL_EFORMAT;
392 393
 					}
393 394
 					if (decode_data->bit_buf & mask) {
... ...
@@ -400,9 +427,13 @@ static int read_c_len(arj_decode_t *decode_data)
400 400
 			}
401 401
 			if (c >= 19) {
402 402
 				cli_dbgmsg("UNARJ: bounds exceeded\n");
403
+				decode_data->status = CL_EARJ;
403 404
 				return CL_EARJ;
404 405
 			}
405 406
 			fill_buf(decode_data, (int)(decode_data->pt_len[c]));
407
+			if (decode_data->status != CL_SUCCESS) {
408
+				return decode_data->status;
409
+			}	
406 410
 			if (c <= 2) {
407 411
 				if (c == 0) {
408 412
 					c = 1;
... ...
@@ -411,9 +442,13 @@ static int read_c_len(arj_decode_t *decode_data)
411 411
 				} else {
412 412
 					c = arj_getbits(decode_data, CBIT) + 20;
413 413
 				}
414
+				if (decode_data->status != CL_SUCCESS) {
415
+					return decode_data->status;
416
+				}		
414 417
 				while (--c >= 0) {
415 418
 					if (i >= NC) {
416 419
 						cli_warnmsg("ERROR: bounds exceeded\n");
420
+						decode_data->status = CL_EFORMAT;
417 421
 						return CL_EFORMAT;
418 422
 					}
419 423
 					decode_data->c_len[i++] = 0;
... ...
@@ -421,6 +456,7 @@ static int read_c_len(arj_decode_t *decode_data)
421 421
 			} else {
422 422
 				if (i >= NC) {
423 423
 					cli_warnmsg("ERROR: bounds exceeded\n");
424
+					decode_data->status = CL_EFORMAT;
424 425
 					return CL_EFORMAT;
425 426
 				}
426 427
 				decode_data->c_len[i++] = (unsigned char) (c - 2);
... ...
@@ -429,7 +465,9 @@ static int read_c_len(arj_decode_t *decode_data)
429 429
 		while (i < NC) {
430 430
 			decode_data->c_len[i++] = 0;
431 431
 		}
432
-		make_table(decode_data, NC, decode_data->c_len, 12, decode_data->c_table, CTABLESIZE);
432
+		if (make_table(decode_data, NC, decode_data->c_len, 12, decode_data->c_table, CTABLESIZE) != CL_SUCCESS) {
433
+			return CL_EARJ;
434
+		}
433 435
 	}
434 436
 	return CL_SUCCESS;
435 437
 }
... ...
@@ -452,6 +490,7 @@ static uint16_t decode_c(arj_decode_t *decode_data)
452 452
 		do {
453 453
 			if (j >= (2 * NC - 1)) {
454 454
 				cli_warnmsg("ERROR: bounds exceeded\n");
455
+				decode_data->status = CL_EARJ;
455 456
 				return 0;
456 457
 			}
457 458
 			if (decode_data->bit_buf & mask) {
... ...
@@ -476,6 +515,7 @@ static uint16_t decode_p(arj_decode_t *decode_data)
476 476
 		do {
477 477
 			if (j >= (2 * NC - 1)) {
478 478
 				cli_warnmsg("ERROR: bounds exceeded\n");
479
+				decode_data->status = CL_EARJ;
479 480
 				return 0;
480 481
 			}
481 482
 			if (decode_data->bit_buf & mask) {
... ...
@@ -510,8 +550,10 @@ static int decode(int fd, arj_metadata_t *metadata)
510 510
 	decode_data.comp_size = metadata->comp_size;
511 511
 	ret = decode_start(&decode_data);
512 512
 	if (ret != CL_SUCCESS) {
513
+		free(decode_data.text);
513 514
 		return ret;
514 515
 	}
516
+	decode_data.status = CL_SUCCESS;
515 517
 
516 518
 	while (count < metadata->orig_size) {
517 519
 		if ((chr = decode_c(&decode_data)) <= UCHAR_MAX) {
... ...
@@ -519,7 +561,10 @@ static int decode(int fd, arj_metadata_t *metadata)
519 519
 			count++;
520 520
 			if (++out_ptr >= DDICSIZ) {
521 521
 				out_ptr = 0;
522
-				write_text(metadata->ofd, decode_data.text, DDICSIZ);
522
+				if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) {
523
+					free(decode_data.text);
524
+					return CL_EIO;
525
+				}
523 526
 			}
524 527
 		} else {
525 528
 			j = chr - (UCHAR_MAX + 1 - THRESHOLD);
... ...
@@ -541,7 +586,10 @@ static int decode(int fd, arj_metadata_t *metadata)
541 541
 					decode_data.text[out_ptr] = decode_data.text[i];
542 542
 					if (++out_ptr >= DDICSIZ) {
543 543
 						out_ptr = 0;
544
-						write_text(metadata->ofd, decode_data.text, DDICSIZ);
544
+						if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) {
545
+							free(decode_data.text);
546
+							return CL_EIO;
547
+						}
545 548
 					}
546 549
 					if (++i >= DDICSIZ) {
547 550
 						i = 0;
... ...
@@ -549,6 +597,10 @@ static int decode(int fd, arj_metadata_t *metadata)
549 549
 				}
550 550
 			}
551 551
 		}
552
+		if (decode_data.status != CL_SUCCESS) {
553
+			free(decode_data.text);
554
+			return decode_data.status;
555
+		}
552 556
 	}
553 557
 	if (out_ptr != 0) {
554 558
 		write_text(metadata->ofd, decode_data.text, out_ptr);
... ...
@@ -625,21 +677,37 @@ static int decode_f(int fd, arj_metadata_t *metadata)
625 625
 		return ret;
626 626
 	}
627 627
     	decode_data.getlen = decode_data.getbuf = 0;
628
-
628
+	decode_data.status = CL_SUCCESS;
629
+	
629 630
 	while (count < metadata->orig_size) {
630 631
 		chr = decode_len(&decode_data);
632
+		if (decode_data.status != CL_SUCCESS) {
633
+			free(decode_data.text);
634
+			return decode_data.status;
635
+		}		
631 636
 		if (chr == 0) {
632 637
 			ARJ_GETBITS(dd, chr, CHAR_BIT);
638
+			if (decode_data.status != CL_SUCCESS) {
639
+				free(decode_data.text);
640
+				return decode_data.status;
641
+			}
633 642
 			decode_data.text[out_ptr] = (unsigned char) chr;
634 643
 			count++;
635 644
 			if (++out_ptr >= DDICSIZ) {
636 645
 				out_ptr = 0;
637
-				write_text(metadata->ofd, decode_data.text, DDICSIZ);
646
+				if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) {
647
+					free(decode_data.text);
648
+					return CL_EIO;
649
+				}
638 650
 			}
639 651
 		} else {
640 652
 			j = chr - 1 + THRESHOLD;
641 653
 			count += j;
642 654
 			pos = decode_ptr(&decode_data);
655
+			if (decode_data.status != CL_SUCCESS) {
656
+				free(decode_data.text);
657
+				return decode_data.status;
658
+			}
643 659
 			if ((i = out_ptr - pos - 1) < 0) {
644 660
 				i += DDICSIZ;
645 661
 			}
... ...
@@ -651,7 +719,10 @@ static int decode_f(int fd, arj_metadata_t *metadata)
651 651
 				decode_data.text[out_ptr] = decode_data.text[i];
652 652
 				if (++out_ptr >= DDICSIZ) {
653 653
 					out_ptr = 0;
654
-					write_text(metadata->ofd, decode_data.text, DDICSIZ);
654
+					if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) {
655
+						free(decode_data.text);
656
+						return CL_EIO;
657
+					}
655 658
 				}
656 659
 				if (++i >= DDICSIZ) {
657 660
 					i = 0;
... ...
@@ -1012,10 +1083,10 @@ int cli_unarj_extract_file(int fd, const char *dirname, arj_metadata_t *metadata
1012 1012
 		case 1:
1013 1013
 		case 2:
1014 1014
 		case 3:
1015
-			decode(fd, metadata);
1015
+			ret = decode(fd, metadata);
1016 1016
 			break;
1017 1017
 		case 4:
1018
-			decode_f(fd, metadata);
1018
+			ret = decode_f(fd, metadata);
1019 1019
 			break;
1020 1020
 		default:
1021 1021
 			ret = CL_EFORMAT;
... ...
@@ -886,18 +886,23 @@ void rar_unpack_init_data(int solid, unpack_data_t *unpack_data)
886 886
 		memset(unpack_data->old_dist, 0, sizeof(unpack_data->old_dist));
887 887
 		unpack_data->old_dist_ptr= 0;
888 888
 		memset(unpack_data->unp_old_table, 0, sizeof(unpack_data->unp_old_table));
889
+		memset(&unpack_data->LD, 0, sizeof(unpack_data->LD));
890
+		memset(&unpack_data->DD, 0, sizeof(unpack_data->DD));
891
+		memset(&unpack_data->LDD, 0, sizeof(unpack_data->LDD));
892
+		memset(&unpack_data->RD, 0, sizeof(unpack_data->RD));
893
+		memset(&unpack_data->BD, 0, sizeof(unpack_data->BD));
889 894
 		unpack_data->last_dist= 0;
890 895
 		unpack_data->last_length=0;
891 896
 		unpack_data->ppm_esc_char = 2;
892 897
 		unpack_data->unp_ptr = 0;
893 898
 		unpack_data->wr_ptr = 0;
899
+		unpack_data->unp_block_type = BLOCK_LZ;
894 900
 		rar_init_filters(unpack_data);
895 901
 	}
896 902
 	unpack_data->in_bit = 0;
897 903
 	unpack_data->in_addr = 0;
898 904
 	unpack_data->read_top = 0;
899
-	unpack_data->ppm_error = FALSE;
900
-	
905
+	unpack_data->read_border = 0;
901 906
 	unpack_data->written_size = 0;
902 907
 	rarvm_init(&unpack_data->rarvm_data);
903 908
 	unpack_data->unp_crc = 0xffffffff;
... ...
@@ -958,8 +963,9 @@ static int rar_unpack29(int fd, int solid, unpack_data_t *unpack_data)
958 958
 			ch = ppm_decode_char(&unpack_data->ppm_data, fd, unpack_data);
959 959
 			rar_dbgmsg("PPM char: %d\n", ch);
960 960
 			if (ch == -1) {
961
+				ppm_cleanup(&unpack_data->ppm_data);
962
+				unpack_data->unp_block_type = BLOCK_LZ;
961 963
 				retval = FALSE;
962
-				unpack_data->ppm_error = TRUE;
963 964
 				break;
964 965
 			}
965 966
 			if (ch == unpack_data->ppm_esc_char) {
... ...
@@ -968,7 +974,6 @@ static int rar_unpack29(int fd, int solid, unpack_data_t *unpack_data)
968 968
 				rar_dbgmsg("PPM next char: %d\n", next_ch);
969 969
 				if (next_ch == -1) {
970 970
 					retval = FALSE;
971
-					unpack_data->ppm_error = TRUE;
972 971
 					break;
973 972
 				}
974 973
 				if (next_ch == 0) {
... ...
@@ -1158,6 +1163,12 @@ int rar_unpack(int fd, int method, int solid, unpack_data_t *unpack_data)
1158 1158
 		retval = rar_unpack29(fd, solid, unpack_data);
1159 1159
 		break;
1160 1160
 	default:
1161
+		retval = rar_unpack29(fd, solid, unpack_data);
1162
+		if(retval == FALSE) {
1163
+		    retval = rar_unpack20(fd, solid, unpack_data);
1164
+		    if(retval == FALSE)
1165
+			retval = rar_unpack15(fd, solid, unpack_data);
1166
+		}
1161 1167
 		break;
1162 1168
 	}
1163 1169
 	return retval;
... ...
@@ -212,7 +212,6 @@ typedef struct unpack_data_tag
212 212
 	unsigned int last_length;
213 213
 	ppm_data_t ppm_data;
214 214
 	int ppm_esc_char;
215
-	int ppm_error;
216 215
 	rar_filter_array_t Filters;
217 216
 	rar_filter_array_t PrgStack;
218 217
 	int *old_filter_lengths;
... ...
@@ -32,9 +32,11 @@ void unpack_init_data20(int solid, unpack_data_t *unpack_data)
32 32
 	if (!solid) {
33 33
 		unpack_data->unp_channel_delta = 0;
34 34
 		unpack_data->unp_cur_channel = 0;
35
+		unpack_data->unp_audio_block = 0;
35 36
 		unpack_data->unp_channels = 1;
36 37
 		memset(unpack_data->audv, 0, sizeof(unpack_data->audv));
37 38
 		memset(unpack_data->unp_old_table20, 0, sizeof(unpack_data->unp_old_table20));
39
+		memset(unpack_data->MD, 0, sizeof(unpack_data->MD));
38 40
 	}
39 41
 }
40 42
 
... ...
@@ -604,6 +604,9 @@ NO_LOOP:
604 604
 		if ((p=pc->con_ut.u.stats)->symbol != up_state.symbol) {
605 605
 			do {
606 606
 				p++;
607
+				if ((void *)p > (void *) ppm_data->sub_alloc.heap_end) {
608
+					return NULL;
609
+				}
607 610
 			} while (p->symbol != up_state.symbol);
608 611
 		}
609 612
 		cf = p->freq - 1;
... ...
@@ -926,6 +929,13 @@ void ppm_destructor(ppm_data_t *ppm_data)
926 926
 	sub_allocator_stop_sub_allocator(&ppm_data->sub_alloc);
927 927
 }
928 928
 
929
+void ppm_cleanup(ppm_data_t *ppm_data)
930
+{
931
+	sub_allocator_stop_sub_allocator(&ppm_data->sub_alloc);
932
+	sub_allocator_start_sub_allocator(&ppm_data->sub_alloc, 1);
933
+	start_model_rare(ppm_data, 2);
934
+}
935
+
929 936
 int ppm_decode_init(ppm_data_t *ppm_data, int fd, unpack_data_t *unpack_data, int *EscChar)
930 937
 {
931 938
 	int max_order, Reset, MaxMB;
... ...
@@ -111,6 +111,7 @@ typedef struct ppm_data_tag
111 111
 
112 112
 } ppm_data_t;
113 113
 
114
+void ppm_cleanup(ppm_data_t *ppm_data);
114 115
 int ppm_decode_init(ppm_data_t *ppm_data, int fd, struct unpack_data_tag *unpack_data, int *EscChar);
115 116
 int ppm_decode_char(ppm_data_t *ppm_data, int fd, struct unpack_data_tag *unpack_data);
116 117
 void ppm_constructor(ppm_data_t *ppm_data);