Browse code

fix collisions in ole2/vba

git-svn: trunk@4068

aCaB authored on 2008/08/03 23:30:33
Showing 12 changed files
... ...
@@ -1,3 +1,7 @@
1
+Sun Aug  3 16:12:17 CEST 2008 (acab)
2
+------------------------------------
3
+  * libclamav: use md5 based lookup for ole2/vba instead of hashtab (bb#1071)
4
+
1 5
 Fri Aug  1 21:29:33 CEST 2008 (tk)
2 6
 ----------------------------------
3 7
   * clamconf: handle multiple select options
... ...
@@ -198,7 +198,9 @@ libclamav_la_SOURCES = \
198 198
 	jsparse/js-norm.c \
199 199
 	jsparse/js-norm.h \
200 200
 	jsparse/lexglobal.h \
201
-	jsparse/textbuf.h
201
+	jsparse/textbuf.h \
202
+	uniq.c \
203
+	uniq.h
202 204
 
203 205
 libclamav_internal_utils_la_SOURCES=str.c \
204 206
 				    str.h \
... ...
@@ -90,7 +90,7 @@ am_libclamav_la_OBJECTS = matcher-ac.lo matcher-bm.lo matcher.lo \
90 90
 	uuencode.lo phishcheck.lo phish_domaincheck_db.lo \
91 91
 	phish_whitelist.lo regex_list.lo regex_suffix.lo mspack.lo \
92 92
 	cab.lo entconv.lo hashtab.lo dconf.lo lzma_iface.lo explode.lo \
93
-	textnorm.lo dlp.lo js-norm.lo
93
+	textnorm.lo dlp.lo js-norm.lo uniq.lo
94 94
 libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS)
95 95
 libclamav_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
96 96
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
... ...
@@ -440,7 +440,9 @@ libclamav_la_SOURCES = \
440 440
 	jsparse/js-norm.c \
441 441
 	jsparse/js-norm.h \
442 442
 	jsparse/lexglobal.h \
443
-	jsparse/textbuf.h
443
+	jsparse/textbuf.h \
444
+	uniq.c \
445
+	uniq.h
444 446
 
445 447
 libclamav_internal_utils_la_SOURCES = str.c \
446 448
 				    str.h \
... ...
@@ -606,6 +608,7 @@ distclean-compile:
606 606
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/textnorm.Plo@am__quote@
607 607
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnef.Plo@am__quote@
608 608
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unarj.Plo@am__quote@
609
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uniq.Plo@am__quote@
609 610
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unsp.Plo@am__quote@
610 611
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/untar.Plo@am__quote@
611 612
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unzip.Plo@am__quote@
... ...
@@ -567,31 +567,3 @@ ssize_t hashset_toarray(const struct hashset* hs, uint32_t** array)
567 567
 	}
568 568
 	return j;
569 569
 }
570
-
571
-struct uniq *uniq_init(uint32_t count) {
572
-	struct uniq *U;
573
-	if(!count) return NULL;
574
-	count = count <= 256 ? 256 : count + (count*20/100);
575
-	U = cli_malloc(sizeof(*U));
576
-	if(!U) return NULL;
577
-	U->uniques = cli_calloc(count, sizeof(uint32_t));
578
-	if(!U->uniques) {
579
-		free(U);
580
-		return NULL;
581
-	}
582
-	U->count = count;
583
-	return U;
584
-}
585
-
586
-uint32_t uniq_add(struct uniq *U, const char *key, uint32_t key_len, uint32_t *rhash) {
587
-	uint32_t h = hash((const unsigned char *)key, key_len, U->count);
588
-	if(rhash) *rhash = h;
589
-	return U->uniques[h]++;
590
-}
591
-
592
-uint32_t uniq_get(struct uniq *U, const char *key, uint32_t key_len, uint32_t *rhash) {
593
-	uint32_t h = hash((const unsigned char *)key, key_len, U->count);
594
-	if(rhash) *rhash = h;
595
-	return U->uniques[h];
596
-}
597
-
... ...
@@ -104,18 +104,5 @@ int hashset_contains(const struct hashset* hs, const uint32_t key);
104 104
 int hashset_clear(struct hashset* hs);
105 105
 void hashset_destroy(struct hashset* hs);
106 106
 ssize_t hashset_toarray(const struct hashset* hs, uint32_t** array);
107
-
108
-
109
-/* A basic storage for unique IDs */
110
-struct uniq {
111
-	uint32_t count;
112
-        uint32_t *uniques;
113
-};
114
-
115
-struct uniq *uniq_init(uint32_t);
116
-#define uniq_free(X) do { if(X) free(X->uniques); free(X); } while (0)
117
-uint32_t uniq_add(struct uniq *, const char *, uint32_t, uint32_t *);
118
-uint32_t uniq_get(struct uniq *, const char *, uint32_t, uint32_t *);
119
-
120 107
 #endif
121 108
 
... ...
@@ -625,7 +625,8 @@ static int handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const
625 625
 	int32_t current_block, ofd, len, offset;
626 626
 	char *name, newname[1024];
627 627
 	bitset_t *blk_bitset;
628
-	uint32_t hash, cnt;
628
+	char *hash;
629
+	uint32_t cnt;
629 630
 
630 631
 	if (prop->type != 2) {
631 632
 		/* Not a file */
... ...
@@ -640,7 +641,7 @@ static int handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const
640 640
 	name = get_property_name2(prop->name, prop->name_size);
641 641
 	if (name) cnt = uniq_add(hdr->U, name, strlen(name), &hash);
642 642
 	else cnt = uniq_add(hdr->U, NULL, 0, &hash);
643
-	snprintf(newname, sizeof(newname), "%s/%u_%u", dir, hash, cnt);
643
+	snprintf(newname, sizeof(newname), "%s/%s_%u", dir, hash, cnt);
644 644
 	newname[sizeof(newname)-1]='\0';
645 645
 	cli_dbgmsg("OLE2 [handler_writefile]: Dumping '%s' to '%s'\n", name ? name : "<empty>", newname);
646 646
 	if (name) free(name);
... ...
@@ -24,7 +24,7 @@
24 24
 #define __OLE2_EXTRACT_H
25 25
 
26 26
 #include "others.h"
27
-#include "hashtab.h"
27
+#include "uniq.h"
28 28
 
29 29
 int cli_ole2_extract(int fd, const char *dirname, cli_ctx *ctx, struct uniq **);
30 30
 
... ...
@@ -735,7 +735,7 @@ static int cli_scanmscab(int desc, cli_ctx *ctx, off_t sfx_offset)
735 735
 
736 736
 static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
737 737
 {
738
-    int ret = CL_CLEAN, i, j, fd, ofd, data_len;
738
+    int ret = CL_CLEAN, i, j, fd, data_len;
739 739
 	vba_project_t *vba_project;
740 740
 	DIR *dd;
741 741
 	struct dirent *dent;
... ...
@@ -748,7 +748,8 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
748 748
 	struct stat statbuf;
749 749
 	char *fullname, vbaname[1024];
750 750
 	unsigned char *data;
751
-	uint32_t hash, hashcnt;
751
+	char *hash;
752
+	uint32_t hashcnt;
752 753
 
753 754
 
754 755
     cli_dbgmsg("VBADir: %s\n", dirname);
... ...
@@ -757,17 +758,17 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
757 757
 	if(!(vba_project = (vba_project_t *)cli_vba_readdir(dirname, U, hashcnt))) continue;
758 758
 
759 759
 	for(i = 0; i < vba_project->count; i++) {
760
-	    for(j = 0; j < vba_project->colls[i]; j++) {
761
-		snprintf(vbaname, 1024, "%s/%u_%u", vba_project->dir, vba_project->name[i], j);
760
+	    for(j = 0; (unsigned int)j < vba_project->colls[i]; j++) {
761
+		snprintf(vbaname, 1024, "%s/%s_%u", vba_project->dir, vba_project->name[i], j);
762 762
 		vbaname[sizeof(vbaname)-1] = '\0';
763 763
 		fd = open(vbaname, O_RDONLY|O_BINARY);
764 764
 		if(fd == -1) continue;
765
-		cli_dbgmsg("VBADir: Decompress VBA project '%u_%u'\n", vba_project->name[i], j);
765
+		cli_dbgmsg("VBADir: Decompress VBA project '%s_%u'\n", vba_project->name[i], j);
766 766
 		data = (unsigned char *)cli_vba_inflate(fd, vba_project->offset[i], &data_len);
767 767
 		close(fd);
768 768
 
769 769
 		if(!data) {
770
-		    cli_dbgmsg("VBADir: WARNING: VBA project '%u_%u' decompressed to NULL\n", vba_project->name[i], j);
770
+		    cli_dbgmsg("VBADir: WARNING: VBA project '%s_%u' decompressed to NULL\n", vba_project->name[i], j);
771 771
 		} else {
772 772
 		    /* cli_dbgmsg("Project content:\n%s", data); */
773 773
 		    if(ctx->scanned)
... ...
@@ -792,7 +793,7 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
792 792
 
793 793
     if(ret == CL_CLEAN && (hashcnt = uniq_get(U, "powerpoint document", 19, &hash))) {
794 794
 	while(hashcnt--) {
795
-	    snprintf(vbaname, 1024, "%s/%u_%u", dirname, hash, hashcnt);
795
+	    snprintf(vbaname, 1024, "%s/%s_%u", dirname, hash, hashcnt);
796 796
 	    vbaname[sizeof(vbaname)-1] = '\0';
797 797
 	    fd = open(vbaname, O_RDONLY|O_BINARY);
798 798
 	    if (fd == -1) continue;
... ...
@@ -810,7 +811,7 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
810 810
 
811 811
     if (ret == CL_CLEAN && (hashcnt = uniq_get(U, "worddocument", 12, &hash))) {
812 812
 	while(hashcnt--) {
813
-	    snprintf(vbaname, sizeof(vbaname), "%s/%u_%u", dirname, hash, hashcnt);
813
+	    snprintf(vbaname, sizeof(vbaname), "%s/%s_%u", dirname, hash, hashcnt);
814 814
 	    vbaname[sizeof(vbaname)-1] = '\0';
815 815
 	    fd = open(vbaname, O_RDONLY|O_BINARY);
816 816
 	    if (fd == -1) continue;
... ...
@@ -857,7 +858,7 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
857 857
     /* Check directory for embedded OLE objects */
858 858
     hashcnt = uniq_get(U, "_1_ole10native", 14, &hash);
859 859
     while(hashcnt--) {
860
-	snprintf(vbaname, sizeof(vbaname), "%s/%u_%u", dirname, hash, hashcnt);
860
+	snprintf(vbaname, sizeof(vbaname), "%s/%s_%u", dirname, hash, hashcnt);
861 861
 	vbaname[sizeof(vbaname)-1] = '\0';
862 862
 
863 863
 	fd = open(vbaname, O_RDONLY|O_BINARY);
864 864
new file mode 100644
... ...
@@ -0,0 +1,205 @@
0
+/*
1
+ *  md5 based hashtab
2
+ *
3
+ *  Copyright (C) 2008 Sourcefire, Inc.
4
+ *
5
+ *  Authors: aCaB <acab@clamav.net>
6
+ *
7
+ *  This program is free software; you can redistribute it and/or modify
8
+ *  it under the terms of the GNU General Public License version 2 as
9
+ *  published by the Free Software Foundation.
10
+ *
11
+ *  This program is distributed in the hope that it will be useful,
12
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ *  GNU General Public License for more details.
15
+ *
16
+ *  You should have received a copy of the GNU General Public License
17
+ *  along with this program; if not, write to the Free Software
18
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
+ *  MA 02110-1301, USA.
20
+ */
21
+
22
+#if HAVE_CONFIG_H
23
+#include "clamav-config.h"
24
+#endif
25
+
26
+#include "uniq.h"
27
+#include "md5.h"
28
+
29
+#if 0
30
+struct uniq *uniq_init(uint32_t count) {
31
+  struct uniq *U;
32
+  uint32_t i;
33
+
34
+  if(!count) return NULL;
35
+  U = cli_calloc(1, sizeof(*U));
36
+  if(!U) return NULL;
37
+  if(cli_ac_init(&U->matcher, 16, 16)) {
38
+    uniq_free(U);
39
+    return NULL;
40
+  }
41
+  U->custs = cli_calloc(count, sizeof(U->custs));
42
+  if(!U->custs) {
43
+    uniq_free(U);
44
+    return NULL;
45
+  }
46
+  U->patts = cli_calloc(count, sizeof(U->patts));
47
+  if(!U->patts) {
48
+    uniq_free(U);
49
+    return NULL;
50
+  }
51
+  U->md5s = cli_malloc(count*sizeof(U->md5s));
52
+  if(!U->md5s) {
53
+    uniq_free(U);
54
+    return NULL;
55
+  }
56
+
57
+  U->entries = count;
58
+
59
+  for(i=0; i<count; i++) {
60
+    U->patts[i].pattern = U->md5s[i].md5;
61
+    U->patts[i].length = 16;
62
+    U->patts[i].ch[0] = U->patts[i].ch[1] |= CLI_MATCH_IGNORE;
63
+    U->patts[i].customdata = &U->custs[i];
64
+  }
65
+
66
+  return U;
67
+}
68
+
69
+void uniq_free(struct uniq *U) {
70
+  uint32_t i;
71
+  U->matcher.ac_patterns = 0; /* don't free my arrays! */
72
+  cli_ac_free(&U->matcher);
73
+  if(U->custs) free(U->custs);
74
+  if(U->patts) free(U->patts);
75
+  if(U->md5s) free(U->md5s);
76
+  free(U);
77
+}
78
+
79
+
80
+uint32_t uniq_add(struct uniq *U, const char *key, uint32_t key_len, char **rhash) {
81
+  uint8_t digest[16];
82
+  struct UNIQCUST *cust;
83
+  struct cli_ac_data mdata;
84
+
85
+  cli_md5_ctx md5;
86
+  cli_md5_init(&md5);
87
+  cli_md5_update(&md5, key, key_len);
88
+  cli_md5_final(digest, &md5);
89
+
90
+  cli_ac_initdata(&mdata, 0, 0, AC_DEFAULT_TRACKLEN); /* This can't fail as we don't have parts or lsigs */
91
+  if (cli_ac_scanbuff(digest,16, NULL, (void *)&cust, NULL, &U->matcher, &mdata,0,0,-1,NULL,AC_SCAN_VIR,NULL)!=CL_VIRUS) {
92
+    int i;
93
+    char HEX[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
94
+    struct cli_ac_patt *patt = &U->patts[U->matcher.ac_patterns];
95
+
96
+    cust = patt->customdata;
97
+    for(i = 0; i < 16; i++) {
98
+      cust->name[i*2] = HEX[digest[i]>>4 & 0xf];
99
+      cust->name[i*2+1] = HEX[digest[i] & 0xf];
100
+      patt->pattern[i] = digest[i];
101
+    }
102
+    cli_ac_addpatt(&U->matcher,patt); /* FIXME this can fail */
103
+    cli_ac_buildtrie(&U->matcher);
104
+  }
105
+
106
+  cust->count++;
107
+  if(rhash) *rhash = cust->name;
108
+  return cust->count;
109
+}
110
+
111
+uint32_t uniq_get(struct uniq *U, const char *key, uint32_t key_len, char **rhash) {
112
+  uint8_t digest[16];
113
+  struct UNIQCUST *cust;
114
+  struct cli_ac_data mdata;
115
+
116
+  cli_md5_ctx md5;
117
+  cli_md5_init(&md5);
118
+  cli_md5_update(&md5, key, key_len);
119
+  cli_md5_final(digest, &md5);
120
+
121
+  cli_ac_initdata(&mdata, 0, 0, AC_DEFAULT_TRACKLEN); /* This can't fail as we don't have parts or lsigs */
122
+  if (cli_ac_scanbuff(digest,16, NULL, (void *)&cust, NULL, &U->matcher, &mdata,0,0,-1,NULL,AC_SCAN_VIR,NULL)!=CL_VIRUS)
123
+    return 0;
124
+
125
+  if(rhash) *rhash = cust->name;
126
+  return cust->count;
127
+}
128
+
129
+#else
130
+#include <string.h>
131
+
132
+struct uniq *uniq_init(uint32_t count) {
133
+  struct uniq *U;
134
+  
135
+  if(!count) return NULL;
136
+  U = cli_malloc(sizeof(*U));
137
+  if(!U) return NULL;
138
+
139
+  U->md5s = cli_malloc(count * sizeof(*U->md5s));
140
+  if(!U->md5s) {
141
+    uniq_free(U);
142
+    return NULL;
143
+  }
144
+
145
+  U->items = 0;
146
+  return U;
147
+}
148
+
149
+void uniq_free(struct uniq *U) {
150
+  free(U->md5s);
151
+  free(U);
152
+}
153
+
154
+uint32_t uniq_add(struct uniq *U, const char *key, uint32_t key_len, char **rhash) {
155
+  unsigned int i;
156
+  uint8_t digest[16];
157
+  cli_md5_ctx md5;
158
+  struct UNIQMD5 *m;
159
+
160
+  cli_md5_init(&md5);
161
+  cli_md5_update(&md5, key, key_len);
162
+  cli_md5_final(digest, &md5);
163
+
164
+  for(i=0; i<U->items; i++) {
165
+    if(memcmp(digest, U->md5s[i].md5, 16)) continue;
166
+    m = &U->md5s[i];
167
+    break;
168
+  }
169
+  
170
+  if(i==U->items) {
171
+    char HEX[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
172
+    m = &U->md5s[i];
173
+    m->count = 0;
174
+    for(i = 0; i < 16; i++) {
175
+      m->name[i*2] = HEX[digest[i]>>4 & 0xf];
176
+      m->name[i*2+1] = HEX[digest[i] & 0xf];
177
+      m->md5[i] = digest[i]; 
178
+    }
179
+    m->name[32] = '\0';
180
+  }
181
+  
182
+  U->items++;
183
+  if(rhash) *rhash = m->name;
184
+  return m->count++;
185
+}
186
+
187
+uint32_t uniq_get(struct uniq *U, const char *key, uint32_t key_len, char **rhash) {
188
+  unsigned int i;
189
+  uint8_t digest[16];
190
+  cli_md5_ctx md5;
191
+
192
+  cli_md5_init(&md5);
193
+  cli_md5_update(&md5, key, key_len);
194
+  cli_md5_final(digest, &md5);
195
+
196
+  for(i=0; i<U->items; i++) {
197
+    if(memcmp(digest, U->md5s[i].md5, 16)) continue;
198
+    if(rhash) *rhash = U->md5s[i].name;
199
+    return U->md5s[i].count;
200
+  }
201
+
202
+  return 0;
203
+}
204
+#endif
0 205
new file mode 100644
... ...
@@ -0,0 +1,68 @@
0
+/*
1
+ *  md5 based hashtab
2
+ *
3
+ *  Copyright (C) 2008 Sourcefire, Inc.
4
+ *
5
+ *  Authors: aCaB <acab@clamav.net>
6
+ *
7
+ *  This program is free software; you can redistribute it and/or modify
8
+ *  it under the terms of the GNU General Public License version 2 as
9
+ *  published by the Free Software Foundation.
10
+ *
11
+ *  This program is distributed in the hope that it will be useful,
12
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ *  GNU General Public License for more details.
15
+ *
16
+ *  You should have received a copy of the GNU General Public License
17
+ *  along with this program; if not, write to the Free Software
18
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
+ *  MA 02110-1301, USA.
20
+ */
21
+
22
+#ifndef _UNIQ_H
23
+#define _UNIQ_H
24
+
25
+#include "matcher.h"
26
+#include "cltypes.h"
27
+
28
+#if 0
29
+struct UNIQCUST {
30
+  char name[33];
31
+  uint32_t count;
32
+};
33
+
34
+struct UNIQMD5 {
35
+  uint16_t md5[16];
36
+};
37
+
38
+/* A basic storage for unique IDs */
39
+struct uniq {
40
+  struct cli_matcher matcher;
41
+  struct cli_ac_patt *patts;
42
+  struct UNIQMD5 *md5s;
43
+  struct UNIQCUST *custs;
44
+  uint32_t entries;
45
+};
46
+
47
+#else
48
+
49
+struct UNIQMD5 {
50
+  uint32_t count;
51
+  uint8_t md5[16];
52
+  char name[33];
53
+};
54
+
55
+struct uniq {
56
+  uint32_t items;
57
+  struct UNIQMD5 *md5s;
58
+};
59
+
60
+#endif
61
+
62
+struct uniq *uniq_init(uint32_t);
63
+void uniq_free(struct uniq *);
64
+uint32_t uniq_add(struct uniq *, const char *, uint32_t, char **);
65
+uint32_t uniq_get(struct uniq *, const char *, uint32_t, char **);
66
+
67
+#endif
... ...
@@ -251,13 +251,12 @@ cli_vba_readdir(const char *dir, struct uniq *U, uint32_t which)
251 251
 	unsigned char *buf;
252 252
 	const unsigned char vba56_signature[] = { 0xcc, 0x61 };
253 253
 	uint16_t record_count, buflen, ffff, byte_count;
254
-	uint32_t offset, sig, hash, colls;
254
+	uint32_t offset;
255 255
 	int i, j, fd, big_endian = FALSE;
256 256
 	vba_project_t *vba_project;
257
-	const vba_version_t *v;
258 257
 	struct vba56_header v56h;
259 258
 	off_t seekback;
260
-	char fullname[1024];
259
+	char fullname[1024], *hash;
261 260
 
262 261
 	cli_dbgmsg("in cli_vba_readdir()\n");
263 262
 
... ...
@@ -270,7 +269,7 @@ cli_vba_readdir(const char *dir, struct uniq *U, uint32_t which)
270 270
 	
271 271
 	if (!uniq_get(U, "_vba_project", 12, &hash))
272 272
 		return NULL;
273
-	snprintf(fullname, sizeof(fullname), "%s/%u_%u", dir, hash, which);
273
+	snprintf(fullname, sizeof(fullname), "%s/%s_%u", dir, hash, which);
274 274
 	fullname[sizeof(fullname)-1] = '\0';
275 275
 	fd = open(fullname, O_RDONLY|O_BINARY);
276 276
 
... ...
@@ -388,10 +387,10 @@ cli_vba_readdir(const char *dir, struct uniq *U, uint32_t which)
388 388
 		ptr = get_unicode_name((const char *)buf, length, big_endian);
389 389
 		if(ptr == NULL) break;
390 390
 		if (!(vba_project->colls[i]=uniq_get(U, ptr, strlen(ptr), &hash))) {
391
-			cli_dbgmsg("vba_readdir: cannot find project %s (%u)\n", ptr, hash);
391
+			cli_dbgmsg("vba_readdir: cannot find project %s (%s)\n", ptr, hash);
392 392
 			break;
393 393
 		}
394
-		cli_dbgmsg("vba_readdir: project name: %s (%u)\n", ptr, hash);
394
+		cli_dbgmsg("vba_readdir: project name: %s (%s)\n", ptr, hash);
395 395
 		free(ptr);
396 396
 		vba_project->name[i] = hash;
397 397
 		if(!read_uint16(fd, &length, big_endian))
... ...
@@ -1039,9 +1038,6 @@ cli_wm_readdir(int fd)
1039 1039
 	macro_info_t macro_info;
1040 1040
 	vba_project_t *vba_project;
1041 1041
 	mso_fib_t fib;
1042
-	uint32_t hash, hashcnt;
1043
-	char fullname[1024];
1044
-
1045 1042
 
1046 1043
 	if (!word_read_fib(fd, &fib))
1047 1044
 		return NULL;
... ...
@@ -1240,7 +1236,7 @@ create_vba_project(int record_count, const char *dir, struct uniq *U)
1240 1240
 	if(ret == NULL)
1241 1241
 		return NULL;
1242 1242
 
1243
-	ret->name = (uint32_t *)cli_malloc(sizeof(uint32_t) * record_count);
1243
+	ret->name = (char **)cli_malloc(sizeof(char *) * record_count);
1244 1244
 	ret->colls = (uint32_t *)cli_malloc(sizeof(uint32_t) * record_count);
1245 1245
 	ret->dir = cli_strdup(dir);
1246 1246
 	ret->offset = (uint32_t *)cli_malloc (sizeof(uint32_t) * record_count);
... ...
@@ -25,10 +25,10 @@
25 25
 
26 26
 #include "others.h"
27 27
 #include "cltypes.h"
28
-#include "hashtab.h"
28
+#include "uniq.h"
29 29
 
30 30
 typedef struct vba_project_tag {
31
-	uint32_t *name;
31
+	char **name;
32 32
 	uint32_t *colls;
33 33
 	uint32_t *offset;
34 34
 	uint32_t *length;	/* for Word 6 macros */