View | Details | Raw Unified
Collapse All | Expand All

(-) ChangeLog (+10 lines)
 Lines 1-3    Link Here 
Mon Apr 14 21:35:11 CEST 2008 (tk)
----------------------------------
  * Check in 0.93 patches:
    - libclamunrar: bb#541 (RAR - Version required to extract - Evasion)
    - libclamav/spin.c: bb#876 (PeSpin Heap Overflow Vulnerability)
    - libclamav/pe.c: bb#878 (Upack Buffer Overflow Vulnerability)
    - libclamav/message.c: bb#881 (message.c: read beyond allocated region)
    - libclamav/unarj.c: bb#897 (ARJ: Sample from CERT-FI hangs clamav)
    - libclamunrar: bb#898 (RAR crashes on some fuzzed files from CERT-FI)
Mon Apr 14 13:19:17 CEST 2008 (tk)
Mon Apr 14 13:19:17 CEST 2008 (tk)
----------------------------------
----------------------------------
  * test: add clam-aspack.exe, clam-pespin.exe and clam-upx.exe (bb#902)
  * test: add clam-aspack.exe, clam-pespin.exe and clam-upx.exe (bb#902)
(-) libclamav/others.c (-1 / +1 lines)
 Lines 87-93    Link Here 
#define       P_tmpdir        "C:\\WINDOWS\\TEMP"
#define       P_tmpdir        "C:\\WINDOWS\\TEMP"
#endif
#endif
#define CL_FLEVEL 28 /* don't touch it */
#define CL_FLEVEL 29 /* don't touch it */
uint8_t cli_debug_flag = 0, cli_leavetemps_flag = 0;
uint8_t cli_debug_flag = 0, cli_leavetemps_flag = 0;
(-) libclamav/message.c (+1 lines)
 Lines 2563-2568    Link Here 
						in++;
						in++;
						continue;
						continue;
					}
					}
					*p = '\0';
					break;
					break;
				case '=':
				case '=':
					/*strcpy(p, in);*/
					/*strcpy(p, in);*/
(-) libclamav/pe.c (-1 / +1 lines)
 Lines 1261-1267    Link Here 
	    CLI_UNPSIZELIMITS("Upack", MAX(MAX(dsize, ssize), exe_sections[1].ursz));
	    CLI_UNPSIZELIMITS("Upack", MAX(MAX(dsize, ssize), exe_sections[1].ursz));
	    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) {
	    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) {
	        cli_dbgmsg("Upack: probably malformed pe-header, skipping to next unpacker\n");
	        cli_dbgmsg("Upack: probably malformed pe-header, skipping to next unpacker\n");
		break;
		break;
	    }
	    }
(-) libclamav/unarj.c (-11 / +82 lines)
 Lines 162-167    Link Here 
	unsigned char pt_len[NPT];
	unsigned char pt_len[NPT];
	unsigned char sub_bit_buf;
	unsigned char sub_bit_buf;
	uint16_t pt_table[PTABLESIZE];
	uint16_t pt_table[PTABLESIZE];
	int status;
} arj_decode_t;
} arj_decode_t;
static int fill_buf(arj_decode_t *decode_data, int n)
static int fill_buf(arj_decode_t *decode_data, int n)
 Lines 172-177    Link Here 
		if (decode_data->comp_size != 0) {
		if (decode_data->comp_size != 0) {
			decode_data->comp_size--;
			decode_data->comp_size--;
			if (cli_readn(decode_data->fd, &decode_data->sub_bit_buf, 1) != 1) {
			if (cli_readn(decode_data->fd, &decode_data->sub_bit_buf, 1) != 1) {
				decode_data->status = CL_EIO;
				return CL_EIO;
				return CL_EIO;
			}
			}
		} else {
		} else {
 Lines 230-235    Link Here 
	for (i = 0; (int)i < nchar; i++) {
	for (i = 0; (int)i < nchar; i++) {
		if (bitlen[i] >= 17) {
		if (bitlen[i] >= 17) {
			cli_dbgmsg("UNARJ: bounds exceeded\n");
			cli_dbgmsg("UNARJ: bounds exceeded\n");
			decode_data->status = CL_EARJ;
			return CL_EARJ;
			return CL_EARJ;
		}
		}
		count[bitlen[i]]++;
		count[bitlen[i]]++;
 Lines 240-251    Link Here 
		start[i+1] = start[i] + (count[i] << (16 - i));
		start[i+1] = start[i] + (count[i] << (16 - i));
	}
	}
	if (start[17] != (unsigned short) (1 << 16)) {
	if (start[17] != (unsigned short) (1 << 16)) {
		decode_data->status = CL_EARJ;
		return CL_EARJ;
		return CL_EARJ;
	}
	}
	
	
	jutbits = 16 - tablebits;
	jutbits = 16 - tablebits;
	if (tablebits >= 17) {
	if (tablebits >= 17) {
		cli_dbgmsg("UNARJ: bounds exceeded\n");
		cli_dbgmsg("UNARJ: bounds exceeded\n");
		decode_data->status = CL_EARJ;
		return CL_EARJ;
		return CL_EARJ;
	}
	}
	for (i = 1; (int)i <= tablebits; i++) {
	for (i = 1; (int)i <= tablebits; i++) {
 Lines 263-268    Link Here 
		while (i != k) {
		while (i != k) {
			if (i >= tablesize) {
			if (i >= tablesize) {
				cli_dbgmsg("UNARJ: bounds exceeded\n");
				cli_dbgmsg("UNARJ: bounds exceeded\n");
				decode_data->status = CL_EARJ;
				return CL_EARJ;
				return CL_EARJ;
			}
			}
			table[i++] = 0;
			table[i++] = 0;
 Lines 277-288    Link Here 
		}
		}
		if (len >= 17) {
		if (len >= 17) {
			cli_dbgmsg("UNARJ: bounds exceeded\n");
			cli_dbgmsg("UNARJ: bounds exceeded\n");
			decode_data->status = CL_EARJ;
			return CL_EARJ;
			return CL_EARJ;
		}
		}
		k = start[len];
		k = start[len];
		nextcode = k + weight[len];
		nextcode = k + weight[len];
		if ((int)len <= tablebits) {
		if ((int)len <= tablebits) {
			if (nextcode > (unsigned int) tablesize) {
			if (nextcode > (unsigned int) tablesize) {
				decode_data->status = CL_EARJ;
				return CL_EARJ;
				return CL_EARJ;
			}
			}
			for (i = start[len]; i < nextcode; i++) {
			for (i = start[len]; i < nextcode; i++) {
 Lines 295-300    Link Here 
				if (*p == 0) {
				if (*p == 0) {
					if (avail >= (2 * NC - 1)) {
					if (avail >= (2 * NC - 1)) {
						cli_dbgmsg("UNARJ: bounds exceeded\n");
						cli_dbgmsg("UNARJ: bounds exceeded\n");
						decode_data->status = CL_EARJ;
						return CL_EARJ;
						return CL_EARJ;
					}
					}
					decode_data->right[avail] = decode_data->left[avail] = 0;
					decode_data->right[avail] = decode_data->left[avail] = 0;
 Lines 302-307    Link Here 
				}
				}
				if (*p >= (2 * NC - 1)) {
				if (*p >= (2 * NC - 1)) {
					cli_dbgmsg("UNARJ: bounds exceeded\n");
					cli_dbgmsg("UNARJ: bounds exceeded\n");
					decode_data->status = CL_EARJ;
					return CL_EARJ;
					return CL_EARJ;
				}
				}
				if (k & mask) {
				if (k & mask) {
 Lines 319-325    Link Here 
	return CL_SUCCESS;
	return CL_SUCCESS;
}
}
static void read_pt_len(arj_decode_t *decode_data, int nn, int nbit, int i_special)
static int read_pt_len(arj_decode_t *decode_data, int nn, int nbit, int i_special)
{
{
	int i, n;
	int i, n;
	short c;
	short c;
 Lines 329-335    Link Here 
	if (n == 0) {
	if (n == 0) {
		if (nn > NPT) {
		if (nn > NPT) {
			cli_dbgmsg("UNARJ: bounds exceeded\n");
			cli_dbgmsg("UNARJ: bounds exceeded\n");
			return;
			decode_data->status = CL_EARJ;
			return CL_EARJ;
		}
		}
		c = arj_getbits(decode_data, nbit);
		c = arj_getbits(decode_data, nbit);
		for (i = 0; i < nn; i++) {
		for (i = 0; i < nn; i++) {
 Lines 350-358    Link Here 
				}
				}
			}
			}
			fill_buf(decode_data, (c < 7) ? 3 : (int)(c - 3));
			fill_buf(decode_data, (c < 7) ? 3 : (int)(c - 3));
			if (decode_data->status != CL_SUCCESS) {
				return decode_data->status;
			}
			decode_data->pt_len[i++] = (unsigned char) c;
			decode_data->pt_len[i++] = (unsigned char) c;
			if (i == i_special) {
			if (i == i_special) {
				c = arj_getbits(decode_data, 2);
				c = arj_getbits(decode_data, 2);
				if (decode_data->status != CL_SUCCESS) {
					return decode_data->status;
				}
				while ((--c >= 0) && (i < NPT)) {
				while ((--c >= 0) && (i < NPT)) {
					decode_data->pt_len[i++] = 0;
					decode_data->pt_len[i++] = 0;
				}
				}
 Lines 361-368    Link Here 
		while ((i < nn) && (i < NPT)) {
		while ((i < nn) && (i < NPT)) {
			decode_data->pt_len[i++] = 0;
			decode_data->pt_len[i++] = 0;
		}
		}
		make_table(decode_data, nn, decode_data->pt_len, 8, decode_data->pt_table, PTABLESIZE);
		if (make_table(decode_data, nn, decode_data->pt_len, 8, decode_data->pt_table, PTABLESIZE) != CL_SUCCESS) {
			return CL_EARJ;
		}
	}
	}
	return CL_SUCCESS;
}
}
static int read_c_len(arj_decode_t *decode_data)
static int read_c_len(arj_decode_t *decode_data)
 Lines 371-378    Link Here 
	unsigned short mask;
	unsigned short mask;
	
	
	n = arj_getbits(decode_data, CBIT);
	n = arj_getbits(decode_data, CBIT);
	if (decode_data->status != CL_SUCCESS) {
		return decode_data->status;
	}
	if (n == 0) {
	if (n == 0) {
		c = arj_getbits(decode_data, CBIT);
		c = arj_getbits(decode_data, CBIT);
		if (decode_data->status != CL_SUCCESS) {
			return decode_data->status;
		}
		for (i = 0; i < NC; i++) {
		for (i = 0; i < NC; i++) {
			decode_data->c_len[i] = 0;
			decode_data->c_len[i] = 0;
		}
		}
 Lines 388-393    Link Here 
				do {
				do {
					if (c >= (2 * NC - 1)) {
					if (c >= (2 * NC - 1)) {
						cli_warnmsg("ERROR: bounds exceeded\n");
						cli_warnmsg("ERROR: bounds exceeded\n");
						decode_data->status = CL_EFORMAT;
						return CL_EFORMAT;
						return CL_EFORMAT;
					}
					}
					if (decode_data->bit_buf & mask) {
					if (decode_data->bit_buf & mask) {
 Lines 400-408    Link Here 
			}
			}
			if (c >= 19) {
			if (c >= 19) {
				cli_dbgmsg("UNARJ: bounds exceeded\n");
				cli_dbgmsg("UNARJ: bounds exceeded\n");
				decode_data->status = CL_EARJ;
				return CL_EARJ;
				return CL_EARJ;
			}
			}
			fill_buf(decode_data, (int)(decode_data->pt_len[c]));
			fill_buf(decode_data, (int)(decode_data->pt_len[c]));
			if (decode_data->status != CL_SUCCESS) {
				return decode_data->status;
			}	
			if (c <= 2) {
			if (c <= 2) {
				if (c == 0) {
				if (c == 0) {
					c = 1;
					c = 1;
 Lines 411-419    Link Here 
				} else {
				} else {
					c = arj_getbits(decode_data, CBIT) + 20;
					c = arj_getbits(decode_data, CBIT) + 20;
				}
				}
				if (decode_data->status != CL_SUCCESS) {
					return decode_data->status;
				}		
				while (--c >= 0) {
				while (--c >= 0) {
					if (i >= NC) {
					if (i >= NC) {
						cli_warnmsg("ERROR: bounds exceeded\n");
						cli_warnmsg("ERROR: bounds exceeded\n");
						decode_data->status = CL_EFORMAT;
						return CL_EFORMAT;
						return CL_EFORMAT;
					}
					}
					decode_data->c_len[i++] = 0;
					decode_data->c_len[i++] = 0;
 Lines 421-426    Link Here 
			} else {
			} else {
				if (i >= NC) {
				if (i >= NC) {
					cli_warnmsg("ERROR: bounds exceeded\n");
					cli_warnmsg("ERROR: bounds exceeded\n");
					decode_data->status = CL_EFORMAT;
					return CL_EFORMAT;
					return CL_EFORMAT;
				}
				}
				decode_data->c_len[i++] = (unsigned char) (c - 2);
				decode_data->c_len[i++] = (unsigned char) (c - 2);
 Lines 429-435    Link Here 
		while (i < NC) {
		while (i < NC) {
			decode_data->c_len[i++] = 0;
			decode_data->c_len[i++] = 0;
		}
		}
		make_table(decode_data, NC, decode_data->c_len, 12, decode_data->c_table, CTABLESIZE);
		if (make_table(decode_data, NC, decode_data->c_len, 12, decode_data->c_table, CTABLESIZE) != CL_SUCCESS) {
			return CL_EARJ;
		}
	}
	}
	return CL_SUCCESS;
	return CL_SUCCESS;
}
}
 Lines 452-457    Link Here 
		do {
		do {
			if (j >= (2 * NC - 1)) {
			if (j >= (2 * NC - 1)) {
				cli_warnmsg("ERROR: bounds exceeded\n");
				cli_warnmsg("ERROR: bounds exceeded\n");
				decode_data->status = CL_EARJ;
				return 0;
				return 0;
			}
			}
			if (decode_data->bit_buf & mask) {
			if (decode_data->bit_buf & mask) {
 Lines 476-481    Link Here 
		do {
		do {
			if (j >= (2 * NC - 1)) {
			if (j >= (2 * NC - 1)) {
				cli_warnmsg("ERROR: bounds exceeded\n");
				cli_warnmsg("ERROR: bounds exceeded\n");
				decode_data->status = CL_EARJ;
				return 0;
				return 0;
			}
			}
			if (decode_data->bit_buf & mask) {
			if (decode_data->bit_buf & mask) {
 Lines 510-517    Link Here 
	decode_data.comp_size = metadata->comp_size;
	decode_data.comp_size = metadata->comp_size;
	ret = decode_start(&decode_data);
	ret = decode_start(&decode_data);
	if (ret != CL_SUCCESS) {
	if (ret != CL_SUCCESS) {
		free(decode_data.text);
		return ret;
		return ret;
	}
	}
	decode_data.status = CL_SUCCESS;
	while (count < metadata->orig_size) {
	while (count < metadata->orig_size) {
		if ((chr = decode_c(&decode_data)) <= UCHAR_MAX) {
		if ((chr = decode_c(&decode_data)) <= UCHAR_MAX) {
 Lines 519-525    Link Here 
			count++;
			count++;
			if (++out_ptr >= DDICSIZ) {
			if (++out_ptr >= DDICSIZ) {
				out_ptr = 0;
				out_ptr = 0;
				write_text(metadata->ofd, decode_data.text, DDICSIZ);
				if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) {
					free(decode_data.text);
					return CL_EIO;
				}
			}
			}
		} else {
		} else {
			j = chr - (UCHAR_MAX + 1 - THRESHOLD);
			j = chr - (UCHAR_MAX + 1 - THRESHOLD);
 Lines 541-547    Link Here 
					decode_data.text[out_ptr] = decode_data.text[i];
					decode_data.text[out_ptr] = decode_data.text[i];
					if (++out_ptr >= DDICSIZ) {
					if (++out_ptr >= DDICSIZ) {
						out_ptr = 0;
						out_ptr = 0;
						write_text(metadata->ofd, decode_data.text, DDICSIZ);
						if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) {
							free(decode_data.text);
							return CL_EIO;
						}
					}
					}
					if (++i >= DDICSIZ) {
					if (++i >= DDICSIZ) {
						i = 0;
						i = 0;
 Lines 549-554    Link Here 
				}
				}
			}
			}
		}
		}
		if (decode_data.status != CL_SUCCESS) {
			free(decode_data.text);
			return decode_data.status;
		}
	}
	}
	if (out_ptr != 0) {
	if (out_ptr != 0) {
		write_text(metadata->ofd, decode_data.text, out_ptr);
		write_text(metadata->ofd, decode_data.text, out_ptr);
 Lines 625-645    Link Here 
		return ret;
		return ret;
	}
	}
    	decode_data.getlen = decode_data.getbuf = 0;
    	decode_data.getlen = decode_data.getbuf = 0;
	decode_data.status = CL_SUCCESS;
	
	while (count < metadata->orig_size) {
	while (count < metadata->orig_size) {
		chr = decode_len(&decode_data);
		chr = decode_len(&decode_data);
		if (decode_data.status != CL_SUCCESS) {
			free(decode_data.text);
			return decode_data.status;
		}		
		if (chr == 0) {
		if (chr == 0) {
			ARJ_GETBITS(dd, chr, CHAR_BIT);
			ARJ_GETBITS(dd, chr, CHAR_BIT);
			if (decode_data.status != CL_SUCCESS) {
				free(decode_data.text);
				return decode_data.status;
			}
			decode_data.text[out_ptr] = (unsigned char) chr;
			decode_data.text[out_ptr] = (unsigned char) chr;
			count++;
			count++;
			if (++out_ptr >= DDICSIZ) {
			if (++out_ptr >= DDICSIZ) {
				out_ptr = 0;
				out_ptr = 0;
				write_text(metadata->ofd, decode_data.text, DDICSIZ);
				if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) {
					free(decode_data.text);
					return CL_EIO;
				}
			}
			}
		} else {
		} else {
			j = chr - 1 + THRESHOLD;
			j = chr - 1 + THRESHOLD;
			count += j;
			count += j;
			pos = decode_ptr(&decode_data);
			pos = decode_ptr(&decode_data);
			if (decode_data.status != CL_SUCCESS) {
				free(decode_data.text);
				return decode_data.status;
			}
			if ((i = out_ptr - pos - 1) < 0) {
			if ((i = out_ptr - pos - 1) < 0) {
				i += DDICSIZ;
				i += DDICSIZ;
			}
			}
 Lines 651-657    Link Here 
				decode_data.text[out_ptr] = decode_data.text[i];
				decode_data.text[out_ptr] = decode_data.text[i];
				if (++out_ptr >= DDICSIZ) {
				if (++out_ptr >= DDICSIZ) {
					out_ptr = 0;
					out_ptr = 0;
					write_text(metadata->ofd, decode_data.text, DDICSIZ);
					if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) {
						free(decode_data.text);
						return CL_EIO;
					}
				}
				}
				if (++i >= DDICSIZ) {
				if (++i >= DDICSIZ) {
					i = 0;
					i = 0;
 Lines 1012-1021    Link Here 
		case 1:
		case 1:
		case 2:
		case 2:
		case 3:
		case 3:
			decode(fd, metadata);
			ret = decode(fd, metadata);
			break;
			break;
		case 4:
		case 4:
			decode_f(fd, metadata);
			ret = decode_f(fd, metadata);
			break;
			break;
		default:
		default:
			ret = CL_EFORMAT;
			ret = CL_EFORMAT;
(-) libclamav/spin.c (-1 / +1 lines)
 Lines 435-441    Link Here 
    /*    len = cli_readint32(ep+0x2fc8); -- Using vsizes instead */
    /*    len = cli_readint32(ep+0x2fc8); -- Using vsizes instead */
    for (j=0; j<sectcnt; j++) {
    for (j=0; j<sectcnt; j++) {
      if (sections[j].rva <= key32 && sections[j].rva+sections[j].rsz > key32)
      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))
	break;
	break;
    }
    }
(-) libclamunrar/unrarppm.c (+10 lines)
 Lines 604-609    Link Here 
		if ((p=pc->con_ut.u.stats)->symbol != up_state.symbol) {
		if ((p=pc->con_ut.u.stats)->symbol != up_state.symbol) {
			do {
			do {
				p++;
				p++;
				if ((void *)p > (void *) ppm_data->sub_alloc.heap_end) {
					return NULL;
				}
			} while (p->symbol != up_state.symbol);
			} while (p->symbol != up_state.symbol);
		}
		}
		cf = p->freq - 1;
		cf = p->freq - 1;
 Lines 926-931    Link Here 
	sub_allocator_stop_sub_allocator(&ppm_data->sub_alloc);
	sub_allocator_stop_sub_allocator(&ppm_data->sub_alloc);
}
}
void ppm_cleanup(ppm_data_t *ppm_data)
{
	sub_allocator_stop_sub_allocator(&ppm_data->sub_alloc);
	sub_allocator_start_sub_allocator(&ppm_data->sub_alloc, 1);
	start_model_rare(ppm_data, 2);
}
int ppm_decode_init(ppm_data_t *ppm_data, int fd, unpack_data_t *unpack_data, int *EscChar)
int ppm_decode_init(ppm_data_t *ppm_data, int fd, unpack_data_t *unpack_data, int *EscChar)
{
{
	int max_order, Reset, MaxMB;
	int max_order, Reset, MaxMB;
(-) libclamunrar/unrarppm.h (+1 lines)
 Lines 111-116    Link Here 
} ppm_data_t;
} ppm_data_t;
void ppm_cleanup(ppm_data_t *ppm_data);
int ppm_decode_init(ppm_data_t *ppm_data, int fd, struct unpack_data_tag *unpack_data, int *EscChar);
int ppm_decode_init(ppm_data_t *ppm_data, int fd, struct unpack_data_tag *unpack_data, int *EscChar);
int ppm_decode_char(ppm_data_t *ppm_data, int fd, struct unpack_data_tag *unpack_data);
int ppm_decode_char(ppm_data_t *ppm_data, int fd, struct unpack_data_tag *unpack_data);
void ppm_constructor(ppm_data_t *ppm_data);
void ppm_constructor(ppm_data_t *ppm_data);
(-) libclamunrar/unrar.c (-4 / +15 lines)
 Lines 886-903    Link Here 
		memset(unpack_data->old_dist, 0, sizeof(unpack_data->old_dist));
		memset(unpack_data->old_dist, 0, sizeof(unpack_data->old_dist));
		unpack_data->old_dist_ptr= 0;
		unpack_data->old_dist_ptr= 0;
		memset(unpack_data->unp_old_table, 0, sizeof(unpack_data->unp_old_table));
		memset(unpack_data->unp_old_table, 0, sizeof(unpack_data->unp_old_table));
		memset(&unpack_data->LD, 0, sizeof(unpack_data->LD));
		memset(&unpack_data->DD, 0, sizeof(unpack_data->DD));
		memset(&unpack_data->LDD, 0, sizeof(unpack_data->LDD));
		memset(&unpack_data->RD, 0, sizeof(unpack_data->RD));
		memset(&unpack_data->BD, 0, sizeof(unpack_data->BD));
		unpack_data->last_dist= 0;
		unpack_data->last_dist= 0;
		unpack_data->last_length=0;
		unpack_data->last_length=0;
		unpack_data->ppm_esc_char = 2;
		unpack_data->ppm_esc_char = 2;
		unpack_data->unp_ptr = 0;
		unpack_data->unp_ptr = 0;
		unpack_data->wr_ptr = 0;
		unpack_data->wr_ptr = 0;
		unpack_data->unp_block_type = BLOCK_LZ;
		rar_init_filters(unpack_data);
		rar_init_filters(unpack_data);
	}
	}
	unpack_data->in_bit = 0;
	unpack_data->in_bit = 0;
	unpack_data->in_addr = 0;
	unpack_data->in_addr = 0;
	unpack_data->read_top = 0;
	unpack_data->read_top = 0;
	unpack_data->ppm_error = FALSE;
	unpack_data->read_border = 0;
	
	unpack_data->written_size = 0;
	unpack_data->written_size = 0;
	rarvm_init(&unpack_data->rarvm_data);
	rarvm_init(&unpack_data->rarvm_data);
	unpack_data->unp_crc = 0xffffffff;
	unpack_data->unp_crc = 0xffffffff;
 Lines 958-965    Link Here 
			ch = ppm_decode_char(&unpack_data->ppm_data, fd, unpack_data);
			ch = ppm_decode_char(&unpack_data->ppm_data, fd, unpack_data);
			rar_dbgmsg("PPM char: %d\n", ch);
			rar_dbgmsg("PPM char: %d\n", ch);
			if (ch == -1) {
			if (ch == -1) {
				ppm_cleanup(&unpack_data->ppm_data);
				unpack_data->unp_block_type = BLOCK_LZ;
				retval = FALSE;
				retval = FALSE;
				unpack_data->ppm_error = TRUE;
				break;
				break;
			}
			}
			if (ch == unpack_data->ppm_esc_char) {
			if (ch == unpack_data->ppm_esc_char) {
 Lines 968-974    Link Here 
				rar_dbgmsg("PPM next char: %d\n", next_ch);
				rar_dbgmsg("PPM next char: %d\n", next_ch);
				if (next_ch == -1) {
				if (next_ch == -1) {
					retval = FALSE;
					retval = FALSE;
					unpack_data->ppm_error = TRUE;
					break;
					break;
				}
				}
				if (next_ch == 0) {
				if (next_ch == 0) {
 Lines 1158-1163    Link Here 
		retval = rar_unpack29(fd, solid, unpack_data);
		retval = rar_unpack29(fd, solid, unpack_data);
		break;
		break;
	default:
	default:
		retval = rar_unpack29(fd, solid, unpack_data);
		if(retval == FALSE) {
		    retval = rar_unpack20(fd, solid, unpack_data);
		    if(retval == FALSE)
			retval = rar_unpack15(fd, solid, unpack_data);
		}
		break;
		break;
	}
	}
	return retval;
	return retval;
(-) libclamunrar/unrar20.c (+2 lines)
 Lines 32-40    Link Here 
	if (!solid) {
	if (!solid) {
		unpack_data->unp_channel_delta = 0;
		unpack_data->unp_channel_delta = 0;
		unpack_data->unp_cur_channel = 0;
		unpack_data->unp_cur_channel = 0;
		unpack_data->unp_audio_block = 0;
		unpack_data->unp_channels = 1;
		unpack_data->unp_channels = 1;
		memset(unpack_data->audv, 0, sizeof(unpack_data->audv));
		memset(unpack_data->audv, 0, sizeof(unpack_data->audv));
		memset(unpack_data->unp_old_table20, 0, sizeof(unpack_data->unp_old_table20));
		memset(unpack_data->unp_old_table20, 0, sizeof(unpack_data->unp_old_table20));
		memset(unpack_data->MD, 0, sizeof(unpack_data->MD));
	}
	}
}
}
(-) libclamunrar/unrar.h (-1 lines)
 Lines 212-218    Link Here 
	unsigned int last_length;
	unsigned int last_length;
	ppm_data_t ppm_data;
	ppm_data_t ppm_data;
	int ppm_esc_char;
	int ppm_esc_char;
	int ppm_error;
	rar_filter_array_t Filters;
	rar_filter_array_t Filters;
	rar_filter_array_t PrgStack;
	rar_filter_array_t PrgStack;
	int *old_filter_lengths;
	int *old_filter_lengths;