Browse code

make some cleanups and add support for nibble matching

git-svn: trunk@2992

Tomasz Kojm authored on 2007/03/29 06:38:07
Showing 20 changed files
... ...
@@ -1,3 +1,7 @@
1
+Wed Mar 28 21:45:12 CEST 2007 (tk)
2
+----------------------------------
3
+  * libclamav: make some cleanups and add support for nibble matching
4
+
1 5
 Tue Mar 27 22:05:28 BST 2007 (njh)
2 6
 ----------------------------------
3 7
   * clamav-milter.c:	Added IPv6 support, based on a patch by
... ...
@@ -50,7 +50,6 @@
50 50
 #include <sys/stat.h>
51 51
 #include <errno.h>
52 52
 
53
-#include "defaults.h"
54 53
 #include "manager.h"
55 54
 #include "notify.h"
56 55
 #include "dns.h"
... ...
@@ -47,7 +47,6 @@ libclamav_la_SOURCES = \
47 47
 	dsig.h \
48 48
         str.c \
49 49
 	str.h \
50
-	defaults.h \
51 50
 	scanners.c \
52 51
 	scanners.h \
53 52
 	filetypes.c \
... ...
@@ -260,7 +260,6 @@ libclamav_la_SOURCES = \
260 260
 	dsig.h \
261 261
         str.c \
262 262
 	str.h \
263
-	defaults.h \
264 263
 	scanners.c \
265 264
 	scanners.h \
266 265
 	filetypes.c \
... ...
@@ -109,32 +109,6 @@ extern "C"
109 109
 #define cl_perror	cl_strerror
110 110
 
111 111
 /* internal structures */
112
-struct cli_bm_patt {
113
-    unsigned char *pattern;
114
-    char *virname, *offset;
115
-    const char *viralias;
116
-    unsigned int length;
117
-    unsigned short target;
118
-    struct cli_bm_patt *next;
119
-};
120
-
121
-struct cli_ac_patt {
122
-    short int *pattern, *prefix;
123
-    unsigned int length, mindist, maxdist, prefix_length;
124
-    char *virname, *offset;
125
-    const char *viralias;
126
-    unsigned short int sigid, parts, partno, alt, *altn, alt_pattern;
127
-    unsigned short type, target;
128
-    unsigned char **altc;
129
-    struct cli_ac_patt *next;
130
-};
131
-
132
-struct cli_ac_node {
133
-    unsigned char islast;
134
-    struct cli_ac_patt *list;
135
-    struct cli_ac_node *trans[256], *fail;
136
-};
137
-
138 112
 struct cli_md5_node {
139 113
     char *virname, *viralias;
140 114
     unsigned char *md5;
... ...
@@ -150,20 +124,6 @@ struct cli_meta_node {
150 150
     struct cli_meta_node *next;
151 151
 };
152 152
 
153
-struct cli_matcher {
154
-    unsigned int maxpatlen; /* maximal length of pattern in db */
155
-    unsigned short ac_only;
156
-
157
-    /* Extended Boyer-Moore */
158
-    int *bm_shift;
159
-    struct cli_bm_patt **bm_suffix;
160
-
161
-    /* Extended Aho-Corasick */
162
-    unsigned int ac_depth;
163
-    struct cli_ac_node *ac_root, **ac_nodetable;
164
-    unsigned int ac_partsigs, ac_nodes;
165
-};
166
-
167 153
 struct cl_engine {
168 154
     unsigned int refcount; /* reference counter */
169 155
     unsigned short ncore;
... ...
@@ -171,7 +131,7 @@ struct cl_engine {
171 171
     unsigned int dboptions;
172 172
 
173 173
     /* Roots table */
174
-    struct cli_matcher **root;
174
+    void **root;
175 175
 
176 176
     /* MD5 */
177 177
     struct cli_md5_node **md5_hlist;
178 178
deleted file mode 100644
... ...
@@ -1,25 +0,0 @@
1
-/*
2
- *  Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
3
- *
4
- *  This program is free software; you can redistribute it and/or modify
5
- *  it under the terms of the GNU General Public License as published by
6
- *  the Free Software Foundation; either version 2 of the License, or
7
- *  (at your option) any later version.
8
- *
9
- *  This program is distributed in the hope that it will be useful,
10
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
- *  GNU General Public License for more details.
13
- *
14
- *  You should have received a copy of the GNU General Public License
15
- *  along with this program; if not, write to the Free Software
16
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17
- *  MA 02110-1301, USA.
18
- */
19
-
20
-#ifndef DATADIR
21
-# define DATADIR "/usr/local/share/clamav"
22
-#endif
23
-
24
-#define CLI_IGN -200
25
-#define CLI_ALT -201
... ...
@@ -382,13 +382,6 @@ int cli_addtypesigs(struct cl_engine *engine)
382 382
 	    return CL_EMEM;
383 383
 	}
384 384
 
385
-	if(engine->ncore) {
386
-	    /*
387
-	    cli_dbgmsg("cli_addtypesigs: AC depth 10 (ncore mode)\n");
388
-	    cli_ac_setdepth(10);
389
-	    */
390
-	}
391
-
392 385
 	root->ac_root =  (struct cli_ac_node *) cli_calloc(1, sizeof(struct cli_ac_node));
393 386
 	if(!root->ac_root) {
394 387
 	    cli_errmsg("cli_addtypesigs: Can't initialise AC pattern matcher\n");
... ...
@@ -4,7 +4,7 @@
4 4
  *  http://www-sr.informatik.uni-tuebingen.de/~buehler/AC/AC.html
5 5
  *  Thanks to Kurt Huwig for pointing me to this page.
6 6
  *
7
- *  Copyright (C) 2002 - 2006 Tomasz Kojm <tkojm@clamav.net>
7
+ *  Copyright (C) 2002 - 2007 Tomasz Kojm <tkojm@clamav.net>
8 8
  *
9 9
  *  This program is free software; you can redistribute it and/or modify
10 10
  *  it under the terms of the GNU General Public License as published by
... ...
@@ -37,7 +37,6 @@
37 37
 #include "others.h"
38 38
 #include "matcher.h"
39 39
 #include "matcher-ac.h"
40
-#include "defaults.h"
41 40
 #include "filetypes.h"
42 41
 #include "cltypes.h"
43 42
 
... ...
@@ -46,12 +45,12 @@ struct nodelist {
46 46
     struct nodelist *next;
47 47
 };
48 48
 
49
-unsigned short ac_depth = AC_DEFAULT_DEPTH;
49
+static uint8_t ac_depth = AC_DEFAULT_DEPTH;
50 50
 
51 51
 int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern)
52 52
 {
53 53
 	struct cli_ac_node *pos, *next;
54
-	int i;
54
+	uint8_t i;
55 55
 
56 56
     if(pattern->length < ac_depth)
57 57
 	return CL_EPATSHORT;
... ...
@@ -59,7 +58,7 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern)
59 59
     pos = root->ac_root;
60 60
 
61 61
     for(i = 0; i < ac_depth; i++) {
62
-	next = pos->trans[((unsigned char) pattern->pattern[i]) & 0xff]; 
62
+	next = pos->trans[(unsigned char) (pattern->pattern[i] & 0xff)]; 
63 63
 
64 64
 	if(!next) {
65 65
 	    next = (struct cli_ac_node *) cli_calloc(1, sizeof(struct cli_ac_node));
... ...
@@ -248,7 +247,7 @@ inline static int cli_findpos(const unsigned char *buffer, unsigned int depth, u
248 248
 	if(bufferpos == postfixend)
249 249
 	    return 0;
250 250
 
251
-	if(pattern->pattern[i] == CLI_ALT) {
251
+	if((pattern->pattern[i] & CLI_MATCH_WILDCARD) == CLI_MATCH_ALTERNATIVE) {
252 252
 	    found = 0;
253 253
 	    for(j = 0; j < pattern->altn[alt]; j++) {
254 254
 		if(pattern->altc[alt][j] == buffer[bufferpos]) {
... ...
@@ -261,7 +260,15 @@ inline static int cli_findpos(const unsigned char *buffer, unsigned int depth, u
261 261
 		return 0;
262 262
 	    alt++;
263 263
 
264
-	} else if(pattern->pattern[i] != CLI_IGN && (unsigned char) pattern->pattern[i] != buffer[bufferpos])
264
+	} else if((pattern->pattern[i] & CLI_MATCH_WILDCARD) == CLI_MATCH_NIBBLE_HIGH) {
265
+	    if((unsigned char) (pattern->pattern[i] & 0x00f0) != (buffer[bufferpos] & 0xf0))
266
+		return 0;
267
+
268
+	} else if((pattern->pattern[i] & CLI_MATCH_WILDCARD) == CLI_MATCH_NIBBLE_LOW) {
269
+	    if((unsigned char) (pattern->pattern[i] & 0x000f) != (buffer[bufferpos] & 0x0f))
270
+		return 0;
271
+
272
+	} else if((pattern->pattern[i] & CLI_MATCH_WILDCARD) != CLI_MATCH_IGNORE && (unsigned char) pattern->pattern[i] != buffer[bufferpos])
265 273
 	    return 0;
266 274
 
267 275
 	bufferpos++;
... ...
@@ -276,7 +283,7 @@ inline static int cli_findpos(const unsigned char *buffer, unsigned int depth, u
276 276
 
277 277
 	for(i = 0; i < pattern->prefix_length; i++) {
278 278
 
279
-	    if(pattern->prefix[i] == CLI_ALT) {
279
+	    if((pattern->prefix[i] & CLI_MATCH_WILDCARD) == CLI_MATCH_ALTERNATIVE) {
280 280
 		found = 0;
281 281
 		for(j = 0; j < pattern->altn[alt]; j++) {
282 282
 		    if(pattern->altc[alt][j] == buffer[bufferpos]) {
... ...
@@ -289,7 +296,15 @@ inline static int cli_findpos(const unsigned char *buffer, unsigned int depth, u
289 289
 		    return 0;
290 290
 		alt++;
291 291
 
292
-	    } else if(pattern->prefix[i] != CLI_IGN && (unsigned char) pattern->prefix[i] != buffer[bufferpos])
292
+	    } else if((pattern->prefix[i] & CLI_MATCH_WILDCARD) == CLI_MATCH_NIBBLE_HIGH) {
293
+		if((unsigned char) (pattern->prefix[i] & 0x00f0) != (buffer[bufferpos] & 0xf0))
294
+		    return 0;
295
+
296
+	    } else if((pattern->prefix[i] & CLI_MATCH_WILDCARD) == CLI_MATCH_NIBBLE_LOW) {
297
+		if((unsigned char) (pattern->prefix[i] & 0x000f) != (buffer[bufferpos] & 0x0f))
298
+		    return 0;
299
+
300
+	    } else if(!(pattern->prefix[i] & CLI_MATCH_IGNORE) && (unsigned char) pattern->prefix[i] != buffer[bufferpos])
293 301
 		return 0;
294 302
 
295 303
 	    bufferpos++;
... ...
@@ -299,7 +314,7 @@ inline static int cli_findpos(const unsigned char *buffer, unsigned int depth, u
299 299
     return 1;
300 300
 }
301 301
 
302
-int cli_ac_initdata(struct cli_ac_data *data, unsigned int partsigs, unsigned int tracklen)
302
+int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint8_t tracklen)
303 303
 {
304 304
 	unsigned int i, j;
305 305
 
... ...
@@ -321,7 +336,7 @@ int cli_ac_initdata(struct cli_ac_data *data, unsigned int partsigs, unsigned in
321 321
     }
322 322
     memset(data->inioff, -1, partsigs * sizeof(off_t));
323 323
 
324
-    data->partcnt = (unsigned int *) cli_calloc(partsigs, sizeof(unsigned int));
324
+    data->partcnt = (uint16_t *) cli_calloc(partsigs, sizeof(uint16_t));
325 325
 
326 326
     if(!data->partcnt) {
327 327
 	cli_errmsg("cli_ac_init(): unable to cli_calloc(%u, %u)\n", partsigs, sizeof(unsigned int));
... ...
@@ -348,7 +363,7 @@ int cli_ac_initdata(struct cli_ac_data *data, unsigned int partsigs, unsigned in
348 348
 	return CL_EMEM;
349 349
     }
350 350
 
351
-    data->maxshift = (int *) cli_malloc(partsigs * sizeof(int));
351
+    data->maxshift = (int32_t *) cli_malloc(partsigs * sizeof(int32_t));
352 352
 
353 353
     if(!data->maxshift) {
354 354
 	cli_errmsg("cli_ac_init(): unable to cli_malloc(%u)\n", partsigs * sizeof(int));
... ...
@@ -359,9 +374,9 @@ int cli_ac_initdata(struct cli_ac_data *data, unsigned int partsigs, unsigned in
359 359
 	return CL_EMEM;
360 360
     }
361 361
 
362
-    memset(data->maxshift, -1, partsigs * sizeof(int));
362
+    memset(data->maxshift, -1, partsigs * sizeof(int32_t));
363 363
 
364
-    data->partoff = (unsigned int **) cli_calloc(partsigs, sizeof(unsigned int *));
364
+    data->partoff = (uint32_t **) cli_calloc(partsigs, sizeof(uint32_t *));
365 365
 
366 366
     if(!data->partoff) {
367 367
 	cli_errmsg("cli_ac_init(): unable to cli_calloc(%u, %u)\n", partsigs, sizeof(unsigned int));
... ...
@@ -379,7 +394,7 @@ int cli_ac_initdata(struct cli_ac_data *data, unsigned int partsigs, unsigned in
379 379
      */
380 380
 
381 381
     for(i = 0; i < partsigs; i++) {
382
-	data->partoff[i] = (unsigned int *) cli_calloc(tracklen, sizeof(unsigned int));
382
+	data->partoff[i] = (uint32_t *) cli_calloc(tracklen, sizeof(uint32_t));
383 383
 
384 384
 	if(!data->partoff[i]) {
385 385
 	    for(j = 0; j < i; j++)
... ...
@@ -418,12 +433,12 @@ void cli_ac_freedata(struct cli_ac_data *data)
418 418
     }
419 419
 }
420 420
 
421
-int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char **virname, const struct cli_matcher *root, struct cli_ac_data *mdata, unsigned short otfrec, unsigned long int offset, cli_file_t ftype, int fd, struct cli_matched_type **ftoffset)
421
+int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, struct cli_ac_data *mdata, uint8_t otfrec, uint32_t offset, cli_file_t ftype, int fd, struct cli_matched_type **ftoffset)
422 422
 {
423 423
 	struct cli_ac_node *current;
424 424
 	struct cli_ac_patt *pt;
425 425
 	int type = CL_CLEAN, j;
426
-        unsigned int i, position, curroff;
426
+        uint32_t i, position, curroff;
427 427
 	uint8_t offnum, found;
428 428
 	struct cli_matched_type *tnode, *tnode_last = NULL;
429 429
 	struct cli_target_info info;
... ...
@@ -614,8 +629,3 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char
614 614
 
615 615
     return otfrec ? type : CL_CLEAN;
616 616
 }
617
-
618
-void cli_ac_setdepth(unsigned int depth)
619
-{
620
-    ac_depth = depth;
621
-}
... ...
@@ -1,5 +1,5 @@
1 1
 /*
2
- *  Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
2
+ *  Copyright (C) 2002 - 2007 Tomasz Kojm <tkojm@clamav.net>
3 3
  *
4 4
  *  This program is free software; you can redistribute it and/or modify
5 5
  *  it under the terms of the GNU General Public License as published by
... ...
@@ -22,8 +22,6 @@
22 22
 
23 23
 #include <sys/types.h>
24 24
 
25
-#include "clamav.h"
26
-#include "matcher.h"
27 25
 #include "filetypes.h"
28 26
 #include "cltypes.h"
29 27
 
... ...
@@ -31,21 +29,41 @@
31 31
 #define AC_DEFAULT_TRACKLEN 8
32 32
 
33 33
 struct cli_ac_data {
34
-    unsigned int partsigs;
34
+    uint32_t partsigs;
35 35
     off_t *inioff;
36
-    unsigned int *partcnt;
37
-    unsigned int **partoff;
36
+    uint16_t *partcnt;
37
+    uint32_t **partoff;
38 38
     uint8_t *offcnt;
39 39
     uint8_t *offidx;
40
-    int *maxshift;
40
+    int32_t *maxshift;
41
+};
42
+
43
+struct cli_ac_patt {
44
+    uint16_t *pattern, *prefix, length, prefix_length;
45
+    uint32_t mindist, maxdist;
46
+    char *virname, *offset;
47
+    const char *viralias;
48
+    uint32_t sigid;
49
+    uint16_t parts, partno, alt, *altn, alt_pattern;
50
+    uint8_t target;
51
+    uint16_t type;
52
+    unsigned char **altc;
53
+    struct cli_ac_patt *next;
41 54
 };
42 55
 
56
+struct cli_ac_node {
57
+    uint8_t islast;
58
+    struct cli_ac_patt *list;
59
+    struct cli_ac_node *trans[256], *fail;
60
+};
61
+
62
+#include "matcher.h"
63
+
43 64
 int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern);
44
-int cli_ac_initdata(struct cli_ac_data *data, unsigned int partsigs, unsigned int histlen);
65
+int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint8_t tracklen);
45 66
 void cli_ac_freedata(struct cli_ac_data *data);
46
-int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char **virname, const struct cli_matcher *root, struct cli_ac_data *mdata, unsigned short otfrec, unsigned long int offset, cli_file_t ftype, int fd, struct cli_matched_type **ftoffset);
67
+int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, struct cli_ac_data *mdata, uint8_t otfrec, uint32_t offset, cli_file_t ftype, int fd, struct cli_matched_type **ftoffset);
47 68
 int cli_ac_buildtrie(struct cli_matcher *root);
48 69
 void cli_ac_free(struct cli_matcher *root);
49
-void cli_ac_setdepth(unsigned int depth);
50 70
 
51 71
 #endif
... ...
@@ -17,6 +17,12 @@
17 17
  *  MA 02110-1301, USA.
18 18
  */
19 19
 
20
+#if HAVE_CONFIG_H
21
+#include "clamav-config.h"
22
+#endif
23
+
24
+#include <stdio.h>
25
+
20 26
 #include "clamav.h"
21 27
 #include "memory.h"
22 28
 #include "others.h"
... ...
@@ -129,7 +135,7 @@ void cli_bm_free(struct cli_matcher *root)
129 129
     }
130 130
 }
131 131
 
132
-int cli_bm_scanbuff(const unsigned char *buffer, unsigned int length, const char **virname, const struct cli_matcher *root, unsigned long int offset, cli_file_t ftype, int fd)
132
+int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, uint32_t offset, cli_file_t ftype, int fd)
133 133
 {
134 134
 	unsigned int i, j, shift, off, found = 0;
135 135
 	int idxtest;
... ...
@@ -20,14 +20,22 @@
20 20
 #ifndef __MATCHER_BM_H
21 21
 #define __MATCHER_BM_H
22 22
 
23
-#include "clamav.h"
24 23
 #include "matcher.h"
25
-#include "matcher-bm.h"
26 24
 #include "filetypes.h"
25
+#include "cltypes.h"
26
+
27
+struct cli_bm_patt {
28
+    unsigned char *pattern;
29
+    uint32_t length;
30
+    char *virname, *offset;
31
+    const char *viralias;
32
+    uint8_t target;
33
+    struct cli_bm_patt *next;
34
+};
27 35
 
28 36
 int cli_bm_addpatt(struct cli_matcher *root, struct cli_bm_patt *pattern);
29 37
 int cli_bm_init(struct cli_matcher *root);
30
-int cli_bm_scanbuff(const unsigned char *buffer, unsigned int length, const char **virname, const struct cli_matcher *root, unsigned long int offset, cli_file_t ftype, int fd);
38
+int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, uint32_t offset, cli_file_t ftype, int fd);
31 39
 void cli_bm_free(struct cli_matcher *root);
32 40
 
33 41
 #endif
... ...
@@ -41,6 +41,7 @@
41 41
 #include "execs.h"
42 42
 #include "special.h"
43 43
 #include "str.h"
44
+#include "cltypes.h"
44 45
 
45 46
 #ifdef HAVE_NCORE
46 47
 #include "matcher-ncore.h"
... ...
@@ -50,9 +51,10 @@ static cli_file_t targettab[CL_TARGET_TABLE_SIZE] = { 0, CL_TYPE_MSEXE, CL_TYPE_
50 50
 
51 51
 extern short cli_debug_flag;
52 52
 
53
-int cli_scanbuff(const unsigned char *buffer, unsigned int length, const char **virname, const struct cl_engine *engine, cli_file_t ftype)
53
+int cli_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cl_engine *engine, cli_file_t ftype)
54 54
 {
55
-	int ret = CL_CLEAN, i;
55
+	int ret = CL_CLEAN;
56
+	unsigned int i;
56 57
 	struct cli_ac_data mdata;
57 58
 	struct cli_matcher *groot, *troot = NULL;
58 59
 
... ...
@@ -285,12 +287,11 @@ int cli_validatesig(cli_file_t ftype, const char *offstr, off_t fileoff, struct
285 285
     return 1;
286 286
 }
287 287
 
288
-int cli_scandesc(int desc, cli_ctx *ctx, unsigned short otfrec, cli_file_t ftype, unsigned short ftonly, struct cli_matched_type **ftoffset)
288
+int cli_scandesc(int desc, cli_ctx *ctx, uint8_t otfrec, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset)
289 289
 {
290 290
  	unsigned char *buffer, *buff, *endbl, *upt;
291 291
 	int ret = CL_CLEAN, type = CL_CLEAN, i, bytes;
292
-	unsigned int buffersize, length, maxpatlen, shift = 0;
293
-	unsigned long int offset = 0;
292
+	uint32_t buffersize, length, maxpatlen, shift = 0, offset = 0;
294 293
 	struct cli_ac_data gdata, tdata;
295 294
 	cli_md5_ctx md5ctx;
296 295
 	unsigned char digest[16];
... ...
@@ -29,6 +29,29 @@
29 29
 #include "cltypes.h"
30 30
 #include "md5.h"
31 31
 
32
+#include "matcher-ac.h"
33
+#include "matcher-bm.h"
34
+
35
+#define CLI_MATCH_WILDCARD	0xff00
36
+#define CLI_MATCH_IGNORE	0x0100
37
+#define CLI_MATCH_ALTERNATIVE	0x0200
38
+#define CLI_MATCH_NIBBLE_HIGH	0x0300
39
+#define CLI_MATCH_NIBBLE_LOW	0x0400
40
+
41
+struct cli_matcher {
42
+    uint16_t maxpatlen;
43
+    uint8_t ac_only;
44
+
45
+    /* Extended Boyer-Moore */
46
+    int32_t *bm_shift;
47
+    struct cli_bm_patt **bm_suffix;
48
+
49
+    /* Extended Aho-Corasick */
50
+    uint8_t ac_depth;
51
+    struct cli_ac_node *ac_root, **ac_nodetable;
52
+    uint32_t ac_partsigs, ac_nodes;
53
+};
54
+
32 55
 #define CL_TARGET_TABLE_SIZE 7
33 56
 
34 57
 struct cli_target_info {
... ...
@@ -37,9 +60,9 @@ struct cli_target_info {
37 37
     int8_t status; /* 0 == not initialised, 1 == initialised OK, -1 == error */
38 38
 };
39 39
 
40
-int cli_scandesc(int desc, cli_ctx *ctx, unsigned short otfrec, cli_file_t ftype, unsigned short ftonly, struct cli_matched_type **ftoffset);
40
+int cli_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cl_engine *engine, cli_file_t ftype);
41 41
 
42
-int cli_scanbuff(const unsigned char *buffer, unsigned int length, const char **virname, const struct cl_engine *engine, cli_file_t ftype);
42
+int cli_scandesc(int desc, cli_ctx *ctx, uint8_t otfrec, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset);
43 43
 
44 44
 int cli_validatesig(cli_file_t ftype, const char *offstr, off_t fileoff, struct cli_target_info *info, int desc, const char *virname);
45 45
 
... ...
@@ -70,7 +70,6 @@ static	char	const	rcsid[] = "$Id: mbox.c,v 1.381 2007/02/15 12:26:44 njh Exp $";
70 70
 #endif
71 71
 
72 72
 #include "others.h"
73
-#include "defaults.h"
74 73
 #include "str.h"
75 74
 #include "filetypes.h"
76 75
 #include "mbox.h"
... ...
@@ -81,7 +81,7 @@ static pthread_mutex_t cli_gentempname_mutex = PTHREAD_MUTEX_INITIALIZER;
81 81
 #define       P_tmpdir        "C:\\WINDOWS\\TEMP"
82 82
 #endif
83 83
 
84
-#define CL_FLEVEL 14 /* don't touch it */
84
+#define CL_FLEVEL 15 /* don't touch it */
85 85
 
86 86
 short cli_debug_flag = 0, cli_leavetemps_flag = 0;
87 87
 
... ...
@@ -286,7 +286,7 @@ char *cli_md5file(const char *filename)
286 286
     return md5str;
287 287
 }
288 288
 
289
-static char *cli_md5buff(const char *buffer, unsigned int len, unsigned char *dig)
289
+static char *cli_md5buff(const unsigned char *buffer, unsigned int len, unsigned char *dig)
290 290
 {
291 291
 	unsigned char digest[16];
292 292
 	char *md5str, *pt;
... ...
@@ -295,7 +295,7 @@ static char *cli_md5buff(const char *buffer, unsigned int len, unsigned char *di
295 295
 
296 296
 
297 297
     cli_md5_init(&ctx);
298
-    cli_md5_update(&ctx, (const unsigned char *) buffer, len);
298
+    cli_md5_update(&ctx, buffer, len);
299 299
     cli_md5_final(digest, &ctx);
300 300
 
301 301
     if(dig)
... ...
@@ -465,7 +465,7 @@ static char *cli_gentempname(const char *dir)
465 465
     for(i = 16; i < 48; i++)
466 466
 	salt[i] = cli_rndnum(256);
467 467
 
468
-    tmp = cli_md5buff((char *) salt, 48, name_salt);
468
+    tmp = cli_md5buff(salt, 48, name_salt);
469 469
 
470 470
 #ifdef CL_THREAD_SAFE
471 471
     pthread_mutex_unlock(&cli_gentempname_mutex);
... ...
@@ -49,9 +49,9 @@
49 49
 #endif
50 50
 #include "matcher-ac.h"
51 51
 #include "matcher-bm.h"
52
+#include "matcher.h"
52 53
 #include "others.h"
53 54
 #include "str.h"
54
-#include "defaults.h"
55 55
 #include "dconf.h"
56 56
 #include "lockdb.h"
57 57
 #include "readdb.h"
... ...
@@ -101,6 +101,9 @@ static int cli_ac_addsig(struct cli_matcher *root, const char *virname, const ch
101 101
 	free(hex);			\
102 102
     }
103 103
 
104
+    if(strlen(hexsig) / 2 < AC_DEFAULT_DEPTH)
105
+	return CL_EPATSHORT;
106
+
104 107
     if((new = (struct cli_ac_patt *) cli_calloc(1, sizeof(struct cli_ac_patt))) == NULL)
105 108
 	return CL_EMEM;
106 109
 
... ...
@@ -210,7 +213,7 @@ static int cli_ac_addsig(struct cli_matcher *root, const char *virname, const ch
210 210
 	}
211 211
     }
212 212
 
213
-    if((new->pattern = cli_hex2si(new->alt ? hex : hexsig)) == NULL) {
213
+    if((new->pattern = cli_hex2ui(new->alt ? hex : hexsig)) == NULL) {
214 214
 	FREE_ALT;
215 215
 	if(new->offset)
216 216
 	    free(new->offset);
... ...
@@ -221,17 +224,17 @@ static int cli_ac_addsig(struct cli_matcher *root, const char *virname, const ch
221 221
     new->length = strlen(new->alt ? hex : hexsig) / 2;
222 222
 
223 223
     for(i = 0; i < AC_DEFAULT_DEPTH; i++) {
224
-	if(new->pattern[i] == CLI_IGN || new->pattern[i] == CLI_ALT) {
224
+	if(new->pattern[i] & CLI_MATCH_WILDCARD) {
225 225
 	    wprefix = 1;
226 226
 	    break;
227 227
 	}
228 228
     }
229 229
 
230 230
     if(wprefix) {
231
-	for(; i < new->length - AC_DEFAULT_DEPTH + 1; i++) {
231
+	for(; i < (uint16_t) (new->length - AC_DEFAULT_DEPTH + 1); i++) {
232 232
 	    wprefix = 0;
233 233
 	    for(j = i; j < i + AC_DEFAULT_DEPTH; j++) {
234
-		if(new->pattern[j] == CLI_IGN || new->pattern[j] == CLI_ALT) {
234
+		if(new->pattern[j] & CLI_MATCH_WILDCARD) {
235 235
 		    wprefix = 1;
236 236
 		    break;
237 237
 		}
... ...
@@ -255,7 +258,7 @@ static int cli_ac_addsig(struct cli_matcher *root, const char *virname, const ch
255 255
 	new->length -= i;
256 256
 
257 257
 	for(i = 0; i < new->prefix_length; i++)
258
-	    if(new->prefix[i] == CLI_ALT)
258
+	    if((new->prefix[i] & CLI_MATCH_WILDCARD) == CLI_MATCH_ALTERNATIVE)
259 259
 		new->alt_pattern++;
260 260
     }
261 261
 
... ...
@@ -524,7 +527,7 @@ int cli_initengine(struct cl_engine **engine, unsigned int options)
524 524
 
525 525
 	(*engine)->refcount = 1;
526 526
 
527
-	(*engine)->root = (struct cli_matcher **) cli_calloc(CL_TARGET_TABLE_SIZE, sizeof(struct cli_matcher *));
527
+	(*engine)->root = cli_calloc(CL_TARGET_TABLE_SIZE, sizeof(struct cli_matcher *));
528 528
 	if(!(*engine)->root) {
529 529
 	    /* no need to free previously allocated memory here */
530 530
 	    cli_errmsg("Can't allocate memory for roots!\n");
... ...
@@ -1674,9 +1677,9 @@ void cl_free(struct cl_engine *engine)
1674 1674
     if(engine->root) {
1675 1675
 	for(i = 0; i < CL_TARGET_TABLE_SIZE; i++) {
1676 1676
 	    if((root = engine->root[i])) {
1677
-		cli_ac_free(root);
1678
-		if(!engine->root[i]->ac_only)
1677
+		if(!root->ac_only)
1679 1678
 		    cli_bm_free(root);
1679
+		cli_ac_free(root);
1680 1680
 		free(root);
1681 1681
 	    }
1682 1682
 	}
... ...
@@ -21,6 +21,7 @@
21 21
 #define __READDB_H
22 22
 
23 23
 #include "clamav.h"
24
+#include "matcher.h"
24 25
 
25 26
 int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hexsig, unsigned short type, const char *offset, unsigned short target);
26 27
 
... ...
@@ -1748,7 +1748,7 @@ static int cli_scanembpe(int desc, cli_ctx *ctx)
1748 1748
 static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type)
1749 1749
 {
1750 1750
 	int ret = CL_CLEAN, nret = CL_CLEAN;
1751
-	unsigned short ftrec, break_loop = 0;
1751
+	uint8_t ftrec, break_loop = 0;
1752 1752
 	struct cli_matched_type *ftoffset = NULL, *fpt;
1753 1753
 	uint32_t lastzip, lastrar;
1754 1754
 	struct cli_exe_info peinfo;
... ...
@@ -33,7 +33,8 @@
33 33
 
34 34
 #include "clamav.h"
35 35
 #include "others.h"
36
-#include "defaults.h"
36
+#include "matcher.h"
37
+#include "cltypes.h"
37 38
 
38 39
 static int cli_hex2int(int c)
39 40
 {
... ...
@@ -53,30 +54,53 @@ static int cli_hex2int(int c)
53 53
     return -1;
54 54
 }
55 55
 
56
-short int *cli_hex2si(const char *hex)
56
+uint16_t *cli_hex2ui(const char *hex)
57 57
 {
58
-	short int *str, *ptr, val, c;
59
-	int i, len;
58
+	uint16_t *str, *ptr, val;
59
+	unsigned int i, len;
60
+	int c;
60 61
 
61 62
 
62 63
     len = strlen(hex);
63 64
 
64 65
     if(len % 2 != 0) {
65
-	cli_errmsg("cli_hex2si(): Malformed hexstring: %s (length: %d)\n", hex, len);
66
+	cli_errmsg("cli_hex2si(): Malformed hexstring: %s (length: %u)\n", hex, len);
66 67
 	return NULL;
67 68
     }
68 69
 
69
-    str = cli_calloc((len / 2) + 1, sizeof(short int));
70
+    str = cli_calloc((len / 2) + 1, sizeof(uint16_t));
70 71
     if(!str)
71 72
 	return NULL;
72 73
 
73 74
     ptr = str;
74 75
 
75 76
     for(i = 0; i < len; i += 2) {
76
-	if(hex[i] == '?') {
77
-	    val = CLI_IGN;
77
+	val = 0;
78
+
79
+	if(hex[i] == '?' && hex[i + 1] == '?') {
80
+	    val |= CLI_MATCH_IGNORE;
81
+
82
+	} else if(hex[i + 1] == '?') {
83
+	    if((c = cli_hex2int(hex[i])) >= 0) {
84
+		val = c << 4;
85
+	    } else {
86
+		free(str);
87
+		return NULL;
88
+	    }
89
+	    val |= CLI_MATCH_NIBBLE_HIGH;
90
+
91
+	} else if(hex[i] == '?') {
92
+	    if((c = cli_hex2int(hex[i + 1])) >= 0) {
93
+		val = c;
94
+	    } else {
95
+		free(str);
96
+		return NULL;
97
+	    }
98
+	    val |= CLI_MATCH_NIBBLE_LOW;
99
+
78 100
 	} else if(hex[i] == '@') {
79
-	    val = CLI_ALT;
101
+	    val |= CLI_MATCH_ALTERNATIVE;
102
+
80 103
 	} else {
81 104
 	    if((c = cli_hex2int(hex[i])) >= 0) {
82 105
 		val = c;
... ...
@@ -91,6 +115,7 @@ short int *cli_hex2si(const char *hex)
91 91
 		return NULL;
92 92
 	    }
93 93
 	}
94
+
94 95
 	*ptr++ = val;
95 96
     }
96 97
 
... ...
@@ -22,10 +22,12 @@
22 22
 
23 23
 #include <sys/types.h>
24 24
 
25
+#include "cltypes.h"
26
+
25 27
 int cli_strbcasestr(const char *haystack, const char *needle);
26 28
 int cli_chomp(char *string);
27 29
 char *cli_strtok(const char *line, int field, const char *delim);
28
-short int *cli_hex2si(const char *hex);
30
+uint16_t *cli_hex2ui(const char *hex);
29 31
 char *cli_hex2str(const char *hex);
30 32
 int cli_hex2num(const char *hex);
31 33
 char *cli_str2hex(const char *string, unsigned int len);