From 31c42eb7ea210277e0848c0547dfaa3c4f4de9d6 Mon Sep 17 00:00:00 2001 From: Trog Date: Wed, 17 Mar 2004 09:26:29 +0000 Subject: [PATCH] Add support for MacOffice98 documents git-svn: trunk@405 --- clamav-devel/ChangeLog | 4 ++ clamav-devel/libclamav/vba_extract.c | 101 ++++++++++++++++----------- 2 files changed, 66 insertions(+), 39 deletions(-) diff --git a/clamav-devel/ChangeLog b/clamav-devel/ChangeLog index 46ca225c1..4387a2ae3 100644 --- a/clamav-devel/ChangeLog +++ b/clamav-devel/ChangeLog @@ -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 diff --git a/clamav-devel/libclamav/vba_extract.c b/clamav-devel/libclamav/vba_extract.c index 4f7600bbb..d0030de1c 100644 --- a/clamav-devel/libclamav/vba_extract.c +++ b/clamav-devel/libclamav/vba_extract.c @@ -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) {