Add support for MacOffice98 documents

git-svn: trunk@405
remotes/push_mirror/metadata
Trog 21 years ago
parent 7761c6eb6e
commit 31c42eb7ea
  1. 4
      clamav-devel/ChangeLog
  2. 101
      clamav-devel/libclamav/vba_extract.c

@ -1,3 +1,7 @@
Wed Mar 17 09:32:45 GMT 2004 (trog)
-----------------------------------
* libclamav/vba_extract.c: Add support for MacOffice98 documents
Tue Mar 16 20:43:20 CET 2004 (tk)
---------------------------------
* libclamav: unrarlib: don't use UnstoreFile() because it causes memory

@ -47,24 +47,41 @@ typedef struct vba_version_tag {
} vba_version_t;
uint16_t vba_endian_convert_16(uint16_t value, int is_mac)
{
if (is_mac) {
#if WORDS_BIGENDIAN == 0
#define vba_endian_convert_16(v) (v)
return ((value >> 8) + (value << 8));;
#else
static uint16_t vba_endian_convert_16(uint16_t v)
{
return ((v >> 8) + (v << 8));
}
return value;
#endif
} else {
#if WORDS_BIGENDIAN == 0
#define vba_endian_convert_32(v) (v)
return value;
#else
static uint32_t vba_endian_convert_32(uint32_t v)
{
return ((v >> 24) | ((v & 0x00FF0000) >> 8) |
((v & 0x0000FF00) << 8) | (v << 24));
return ((value >> 8) + (value << 8));
#endif
}
}
uint32_t vba_endian_convert_32(uint32_t value, int is_mac)
{
if (is_mac) {
#if WORDS_BIGENDIAN == 0
return ((value >> 24) | ((value & 0x00FF0000) >> 8) |
((value & 0x0000FF00) << 8) | (value << 24));
#else
return value;
#endif
} else {
#if WORDS_BIGENDIAN == 0
return value;
#else
return ((value >> 24) | ((value & 0x00FF0000) >> 8) |
((value & 0x0000FF00) << 8) | (value << 24));
#endif
}
}
typedef struct byte_array_tag {
unsigned int length;
@ -144,12 +161,12 @@ int vba_writen(int fd, void *buff, unsigned int count)
return count;
}
char *get_unicode_name(char *name, int size)
char *get_unicode_name(char *name, int size, int is_mac)
{
int i, j;
char *newname;
if (*name == 0 || size == 0) {
if (*name == 0 || size <= 0) {
return NULL;
}
@ -158,7 +175,7 @@ char *get_unicode_name(char *name, int size)
return NULL;
}
j=0;
for (i=0 ; i < size; i+=2) {
for (i=0 ; i < size; i += (is_mac ? 1 : 2) ) {
if (isprint(name[i])) {
newname[j++] = name[i];
} else {
@ -208,7 +225,7 @@ static void vba56_test_end(int fd)
if (memcmp(test_end, end_str, 20) != 0) {
lseek(fd, -20, SEEK_CUR);
}
}
return;
}
@ -219,7 +236,7 @@ vba_project_t *vba56_dir_read(const char *dir)
unsigned char version[4];
unsigned char *buff, *name;
unsigned char vba56_signature[] = { 0xcc, 0x61 };
int16_t record_count, length;
uint16_t record_count, length;
uint16_t ooff;
uint8_t byte_count;
uint32_t offset;
@ -232,7 +249,7 @@ vba_project_t *vba56_dir_read(const char *dir)
uint16_t LenB;
uint16_t LenC;
uint16_t LenD;
int i, j, fd;
int i, j, fd, is_mac;
vba_project_t *vba_project;
char *fullname;
@ -280,6 +297,12 @@ vba_project_t *vba56_dir_read(const char *dir)
cli_dbgmsg("VBA Project: %s, VBA Version=%d\n", vba_version[i].name,
vba_version[i].vba_version);
if (i == 9) {
cli_dbgmsg("MacOffice2001 not currently supported\n");
close(fd);
return NULL;
}
is_mac = vba_version[i].is_mac;
/*****************************************/
@ -330,13 +353,13 @@ vba_project_t *vba56_dir_read(const char *dir)
return NULL;
}
LidA = vba_endian_convert_32(LidA);
LidB = vba_endian_convert_32(LidB);
CharSet = vba_endian_convert_16(CharSet);
LenA = vba_endian_convert_16(LenA);
LenB = vba_endian_convert_16(LenB);
LenC = vba_endian_convert_16(LenC);
LenD = vba_endian_convert_16(LenD);
LidA = vba_endian_convert_32(LidA, is_mac);
LidB = vba_endian_convert_32(LidB, is_mac);
CharSet = vba_endian_convert_16(CharSet, is_mac);
LenA = vba_endian_convert_16(LenA, is_mac);
LenB = vba_endian_convert_16(LenB, is_mac);
LenC = vba_endian_convert_16(LenC, is_mac);
LenD = vba_endian_convert_16(LenD, is_mac);
cli_dbgmsg(" LidA: %d\n LidB: %d\n CharSet: %d\n", LidA, LidB, CharSet);
cli_dbgmsg(" LenA: %d\n UnknownB: %d\n UnknownC: %d\n", LenA, UnknownB, UnknownC);
@ -370,7 +393,7 @@ vba_project_t *vba56_dir_read(const char *dir)
if (vba_readn(fd, &length, 2) != 2) {
return NULL;
}
length = vba_endian_convert_16(length);
length = vba_endian_convert_16(length, is_mac);
if (length < 6) {
lseek(fd, -2, SEEK_CUR);
break;
@ -387,7 +410,7 @@ vba_project_t *vba56_dir_read(const char *dir)
close(fd);
return NULL;
}
name = get_unicode_name(buff, length);
name = get_unicode_name(buff, length, is_mac);
cli_dbgmsg("name: %s\n", name);
free(buff);
@ -395,7 +418,7 @@ vba_project_t *vba56_dir_read(const char *dir)
Type 'C' entries come in pairs, the second also
having a 12 byte trailer */
/* TODO: Need to check if types H(same as G) and D(same as C) exist */
if (!strncmp ("*\\G", name, 3)) {
if (!strncmp ("*\\G", name, 3) || !strncmp ("*\\H", name, 3)) {
buff = (unsigned char *) cli_malloc(12);
if (vba_readn(fd, buff, 12) != 12) {
cli_errmsg("failed to read blob\n");
@ -405,7 +428,7 @@ vba_project_t *vba56_dir_read(const char *dir)
return NULL;
}
free(buff);
} else if (!strncmp("*\\C", name, 3)) {
} else if (!strncmp("*\\C", name, 3) || !strncmp("*\\D", name, 3)) {
if (i == 1) {
buff = (unsigned char *) cli_malloc(12);
if (vba_readn(fd, buff, 12) != 12) {
@ -438,7 +461,7 @@ vba_project_t *vba56_dir_read(const char *dir)
close(fd);
return NULL;
}
record_count = vba_endian_convert_16(record_count);
record_count = vba_endian_convert_16(record_count, is_mac);
cli_dbgmsg("\nVBA Record count: %d\n", record_count);
/*if (record_count <= 0) {
close(fd);
@ -482,7 +505,7 @@ vba_project_t *vba56_dir_read(const char *dir)
/* no idea what this stuff is */
if (ooff != 0xFFFF) {
ooff = vba_endian_convert_16(ooff);
ooff = vba_endian_convert_16(ooff, is_mac);
lseek(fd, ooff, SEEK_CUR);
}
if (vba_readn(fd, &ooff, 2) != 2) {
@ -490,7 +513,7 @@ vba_project_t *vba56_dir_read(const char *dir)
return NULL;
}
if (ooff != 0xFFFF) {
ooff = vba_endian_convert_16(ooff);
ooff = vba_endian_convert_16(ooff, is_mac);
lseek(fd, ooff, SEEK_CUR);
}
lseek(fd, 100, SEEK_CUR);
@ -499,7 +522,7 @@ vba_project_t *vba56_dir_read(const char *dir)
close(fd);
return NULL;
}
record_count = vba_endian_convert_16(record_count);
record_count = vba_endian_convert_16(record_count, is_mac);
cli_dbgmsg("\nVBA Record count: %d\n", record_count);
vba_project = (vba_project_t *) cli_malloc(sizeof(struct vba_project_tag));
@ -512,7 +535,7 @@ vba_project_t *vba56_dir_read(const char *dir)
if (vba_readn(fd, &length, 2) != 2) {
goto out_error;
}
length = vba_endian_convert_16(length);
length = vba_endian_convert_16(length, is_mac);
buff = (unsigned char *) cli_malloc(length);
if (!buff) {
cli_dbgmsg("cli_malloc failed\n");
@ -523,7 +546,7 @@ vba_project_t *vba56_dir_read(const char *dir)
free(buff);
goto out_error;
}
vba_project->name[i] = get_unicode_name(buff, length);
vba_project->name[i] = get_unicode_name(buff, length, is_mac);
cli_dbgmsg("project name: %s, ", vba_project->name[i]);
free(buff);
@ -532,7 +555,7 @@ vba_project_t *vba56_dir_read(const char *dir)
free(vba_project->name[i]);
goto out_error;
}
length = vba_endian_convert_16(length);
length = vba_endian_convert_16(length, is_mac);
lseek(fd, length, SEEK_CUR);
/* unknown stuff */
@ -540,14 +563,14 @@ vba_project_t *vba56_dir_read(const char *dir)
free(vba_project->name[i]);
goto out_error;
}
ooff = vba_endian_convert_16(ooff);
ooff = vba_endian_convert_16(ooff, is_mac);
if (ooff == 0xFFFF) {
lseek(fd, 2, SEEK_CUR);
if (vba_readn(fd, &ooff, 2) != 2) {
free(vba_project->name[i]);
goto out_error;
}
ooff = vba_endian_convert_16(ooff);
ooff = vba_endian_convert_16(ooff, is_mac);
lseek(fd, ooff, SEEK_CUR);
} else {
lseek(fd, 2 + ooff, SEEK_CUR);
@ -566,7 +589,7 @@ vba_project_t *vba56_dir_read(const char *dir)
free(vba_project->name[i]);
goto out_error;
}
offset = vba_endian_convert_32(offset);
offset = vba_endian_convert_32(offset, is_mac);
vba_project->offset[i] = offset;
cli_dbgmsg("offset:%d\n", offset);
lseek(fd, 2, SEEK_CUR);
@ -637,7 +660,7 @@ unsigned char *vba_decompress(int fd, uint32_t offset, int *size)
}
return NULL;
}
token = vba_endian_convert_16(token);
token = vba_endian_convert_16(token, FALSE);
win_pos = pos % VBA_COMPRESSION_WINDOW;
if (win_pos <= 0x80) {
if (win_pos <= 0x20) {

Loading…
Cancel
Save