~ubuntu-branches/ubuntu/raring/clamav/raring

« back to all changes in this revision

Viewing changes to unit_tests/check_clamav.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen Gran
  • Date: 2008-09-05 17:25:34 UTC
  • mfrom: (0.35.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080905172534-yi3f8fkye1o7u1r3
* New upstream version (closes: #497662, #497773)
  - lots of new options for clamd.conf
  - fixes CVEs CVE-2008-3912, CVE-2008-3913, CVE-2008-3914, and
    CVE-2008-1389
* No longer supports --unzip option, so typo is gone (closes: #496276)
* Translations:
  - sv (thanks Martin Bagge <brother@bsnet.se>) (closes: #491760)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#if HAVE_CONFIG_H
 
2
#include "clamav-config.h"
 
3
#endif
 
4
 
 
5
#include <stdio.h>
 
6
 
 
7
#ifndef HAVE_CHECK
 
8
int main(int argc, char **argv)
 
9
{
 
10
    puts("\n*** Unit tests disabled in this build\n*** Use ./configure --enable-check to enable them\n");
 
11
    /* tell automake the test was skipped */
 
12
    return 77;
 
13
}
 
14
#else
 
15
 
 
16
#include <stdlib.h>
 
17
#include <limits.h>
 
18
#include <fcntl.h>
 
19
#include <string.h>
 
20
#include <check.h>
 
21
#include "../libclamav/clamav.h"
 
22
#include "../libclamav/others.h"
 
23
#include "../libclamav/matcher.h"
 
24
#include "../libclamav/version.h"
 
25
#include "checks.h"
 
26
 
 
27
/* extern void cl_free(struct cl_engine *engine); */
 
28
START_TEST (test_cl_free)
 
29
/*
 
30
    struct cl_engine *engine = NULL;
 
31
    cl_free(NULL);
 
32
*/
 
33
END_TEST
 
34
 
 
35
/* extern struct cl_engine *cl_dup(struct cl_engine *engine); */
 
36
START_TEST (test_cl_dup)
 
37
    /*
 
38
    struct cl_engine *engine;
 
39
    fail_unless(NULL == cl_dup(NULL), "cl_dup null pointer");
 
40
    */
 
41
END_TEST
 
42
 
 
43
/* extern int cl_build(struct cl_engine *engine); */
 
44
START_TEST (test_cl_build)
 
45
    /*
 
46
    struct cl_engine *engine;
 
47
    fail_unless(CL_ENULLARG == cl_build(NULL), "cl_build null pointer");
 
48
    engine = calloc(sizeof(struct cl_engine),1);
 
49
    fail_unless(engine, "cl_build calloc");
 
50
    fail_unless(CL_ENULLARG == cl_build(engine), "cl_build(engine) with null ->root");
 
51
    */
 
52
/*    engine->root = cli_calloc(CL_TARGET_TABLE_SIZE, sizeof(struct cli_matcher *)); */
 
53
END_TEST
 
54
 
 
55
/* extern void cl_debug(void); */
 
56
START_TEST (test_cl_debug)
 
57
{
 
58
    int old_status = cli_debug_flag;
 
59
    cli_debug_flag = 0;
 
60
    cl_debug();
 
61
    fail_unless(1 == cli_debug_flag, "cl_debug failed to set cli_debug_flag");
 
62
 
 
63
    cli_debug_flag = 1;
 
64
    cl_debug();
 
65
    fail_unless(1 == cli_debug_flag, "cl_debug failed when flag was already set");
 
66
    cli_debug_flag = old_status;
 
67
}
 
68
END_TEST
 
69
 
 
70
/* extern const char *cl_retdbdir(void); */
 
71
START_TEST (test_cl_retdbdir)
 
72
    fail_unless(!strcmp(DATADIR, cl_retdbdir()), "cl_retdbdir");
 
73
END_TEST
 
74
 
 
75
#ifndef REPO_VERSION
 
76
#define REPO_VERSION VERSION
 
77
#endif
 
78
 
 
79
/* extern const char *cl_retver(void); */
 
80
START_TEST (test_cl_retver)
 
81
{
 
82
    const char *ver = cl_retver();
 
83
    fail_unless(!strcmp(REPO_VERSION, ver),"cl_retver");
 
84
    fail_unless(strcspn(ver,"012345789") < strlen(ver),
 
85
                    "cl_retver must have a number");
 
86
}
 
87
END_TEST
 
88
 
 
89
/* extern void cl_cvdfree(struct cl_cvd *cvd); */
 
90
START_TEST (test_cl_cvdfree)
 
91
/*
 
92
    struct cl_cvd *cvd1, *cvd2;
 
93
 
 
94
    cvd1 = malloc(sizeof(struct cl_cvd));
 
95
    fail_unless(cvd1, "cvd malloc");
 
96
    cl_cvdfree(cvd1);
 
97
 
 
98
    cvd2 = malloc(sizeof(struct cl_cvd));
 
99
    cvd2->time = malloc(1);
 
100
    cvd2->md5 = malloc(1);
 
101
    cvd2->dsig= malloc(1);
 
102
    cvd2->builder = malloc(1);
 
103
    fail_unless(cvd2, "cvd malloc");
 
104
    fail_unless(cvd2->time, "cvd malloc");
 
105
    fail_unless(cvd2->md5, "cvd malloc");
 
106
    fail_unless(cvd2->dsig, "cvd malloc");
 
107
    fail_unless(cvd2->builder, "cvd malloc");
 
108
    cl_cvdfree(cvd2);
 
109
    cl_cvdfree(NULL);
 
110
*/
 
111
END_TEST
 
112
 
 
113
/* extern int cl_statfree(struct cl_stat *dbstat); */
 
114
START_TEST (test_cl_statfree)
 
115
/*
 
116
    struct cl_stat *stat;
 
117
    fail_unless(CL_ENULLARG == cl_statfree(NULL), "cl_statfree(NULL)");
 
118
    
 
119
    stat = malloc(sizeof(struct cl_stat));
 
120
    fail_unless(NULL != stat, "malloc");
 
121
    fail_unless(CL_SUCCESS == cl_statfree(stat), "cl_statfree(empty_struct)");
 
122
    
 
123
    stat = malloc(sizeof(struct cl_stat));
 
124
    fail_unless(NULL != stat, "malloc");
 
125
    stat->stattab = strdup("test");
 
126
    fail_unless(NULL != stat->stattab, "strdup");
 
127
    fail_unless(CL_SUCCESS == cl_statfree(stat), "cl_statfree(stat with stattab)");
 
128
 
 
129
    stat = malloc(sizeof(struct cl_stat));
 
130
    fail_unless(NULL != stat, "malloc");
 
131
    stat->stattab = NULL;
 
132
    fail_unless(CL_SUCCESS == cl_statfree(stat), "cl_statfree(stat with stattab) set to NULL");
 
133
*/
 
134
END_TEST
 
135
 
 
136
/* extern unsigned int cl_retflevel(void); */
 
137
START_TEST (test_cl_retflevel)
 
138
END_TEST    
 
139
 
 
140
/* extern struct cl_cvd *cl_cvdhead(const char *file); */
 
141
START_TEST (test_cl_cvdhead)
 
142
/*
 
143
    fail_unless(NULL == cl_cvdhead(NULL), "cl_cvdhead(null)");
 
144
    fail_unless(NULL == cl_cvdhead("input/cl_cvdhead/1.txt"), "cl_cvdhead(515 byte file, all nulls)");
 
145
*/
 
146
    /* the data read from the file is passed to cl_cvdparse, test cases for that are separate */
 
147
END_TEST
 
148
 
 
149
/* extern struct cl_cvd *cl_cvdparse(const char *head); */
 
150
START_TEST (test_cl_cvdparse)
 
151
END_TEST
 
152
 
 
153
/* int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options) */
 
154
START_TEST (test_cl_scandesc)
 
155
END_TEST
 
156
 
 
157
/* int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options) */
 
158
START_TEST (test_cl_scanfile)
 
159
END_TEST
 
160
 
 
161
/* int cl_load(const char *path, struct cl_engine **engine, unsigned int *signo, unsigned int options) */
 
162
START_TEST (test_cl_load)
 
163
END_TEST
 
164
 
 
165
/* int cl_cvdverify(const char *file) */
 
166
START_TEST (test_cl_cvdverify)
 
167
END_TEST
 
168
 
 
169
/* int cl_statinidir(const char *dirname, struct cl_stat *dbstat) */
 
170
START_TEST (test_cl_statinidir)
 
171
END_TEST
 
172
 
 
173
/* int cl_statchkdir(const struct cl_stat *dbstat) */
 
174
START_TEST (test_cl_statchkdir)
 
175
END_TEST
 
176
 
 
177
/* void cl_settempdir(const char *dir, short leavetemps) */
 
178
START_TEST (test_cl_settempdir)
 
179
END_TEST
 
180
 
 
181
/* const char *cl_strerror(int clerror) */
 
182
START_TEST (test_cl_strerror)
 
183
END_TEST
 
184
 
 
185
static Suite *test_cl_suite(void)
 
186
{
 
187
    Suite *s = suite_create("cl_api");
 
188
    TCase *tc_cl = tcase_create("cl_dup");
 
189
 
 
190
    suite_add_tcase (s, tc_cl);
 
191
    tcase_add_test(tc_cl, test_cl_free);
 
192
    tcase_add_test(tc_cl, test_cl_dup);
 
193
    tcase_add_test(tc_cl, test_cl_build);
 
194
    tcase_add_test(tc_cl, test_cl_debug);
 
195
    tcase_add_test(tc_cl, test_cl_retdbdir);
 
196
    tcase_add_test(tc_cl, test_cl_retver);
 
197
    tcase_add_test(tc_cl, test_cl_cvdfree);
 
198
    tcase_add_test(tc_cl, test_cl_statfree);
 
199
    tcase_add_test(tc_cl, test_cl_retflevel);
 
200
    tcase_add_test(tc_cl, test_cl_cvdhead);
 
201
    tcase_add_test(tc_cl, test_cl_cvdparse);
 
202
    tcase_add_test(tc_cl, test_cl_scandesc);
 
203
    tcase_add_test(tc_cl, test_cl_scanfile);
 
204
    tcase_add_test(tc_cl, test_cl_load);
 
205
    tcase_add_test(tc_cl, test_cl_cvdverify);
 
206
    tcase_add_test(tc_cl, test_cl_statinidir);
 
207
    tcase_add_test(tc_cl, test_cl_statchkdir);
 
208
    tcase_add_test(tc_cl, test_cl_settempdir);
 
209
    tcase_add_test(tc_cl, test_cl_strerror);
 
210
 
 
211
    return s;
 
212
}
 
213
 
 
214
static uint8_t le_data[4] = {0x67,0x45,0x23,0x01};
 
215
static int32_t le_expected[4] = { 0x01234567, 0x67012345, 0x45670123, 0x23456701};
 
216
uint8_t *data = NULL;
 
217
uint8_t *data2 = NULL;
 
218
#define DATA_REP 100
 
219
 
 
220
static void data_setup(void)
 
221
{
 
222
        uint8_t *p;
 
223
        size_t i;
 
224
 
 
225
        data = malloc(sizeof(le_data)*DATA_REP);
 
226
        data2 = malloc(sizeof(le_data)*DATA_REP);
 
227
        fail_unless(!!data, "unable to allocate memory for fixture");
 
228
        fail_unless(!!data2, "unable to allocate memory for fixture");
 
229
        p = data;
 
230
        /* make multiple copies of le_data, we need to run readint tests in a loop, so we need
 
231
         * to give it some data to run it on */
 
232
        for(i=0; i<DATA_REP;i++) {
 
233
                memcpy(p, le_data, sizeof(le_data));
 
234
                p += sizeof(le_data);
 
235
        }
 
236
        memset(data2, 0, DATA_REP*sizeof(le_data));
 
237
}
 
238
 
 
239
static void data_teardown(void)
 
240
{
 
241
        free(data);
 
242
        free(data2);
 
243
}
 
244
 
 
245
#ifdef CHECK_HAVE_LOOPS
 
246
/* test reading with different alignments, _i is parameter from tcase_add_loop_test */
 
247
START_TEST (test_cli_readint16)
 
248
{
 
249
    size_t j;
 
250
    int16_t value;
 
251
    /* read 2 bytes apart, start is not always aligned*/
 
252
    for(j=_i;j <= DATA_REP*sizeof(le_data)-2;j += 2) {
 
253
        value = le_expected[j&3];
 
254
        fail_unless(cli_readint16(&data[j]) == value, "(1) data read must be little endian");
 
255
    }
 
256
    /* read 2 bytes apart, always aligned*/
 
257
    for(j=0;j <= DATA_REP*sizeof(le_data)-2;j += 2) {
 
258
        value = le_expected[j&3];
 
259
        fail_unless(cli_readint16(&data[j]) == value, "(2) data read must be little endian");
 
260
    }
 
261
}
 
262
END_TEST
 
263
 
 
264
/* test reading with different alignments, _i is parameter from tcase_add_loop_test */
 
265
START_TEST (test_cli_readint32)
 
266
{
 
267
    size_t j;
 
268
    int32_t value = le_expected[_i&3];
 
269
    /* read 4 bytes apart, start is not always aligned*/
 
270
    for(j=_i;j < DATA_REP*sizeof(le_data)-4;j += 4) {
 
271
        fail_unless(cli_readint32(&data[j]) == value, "(1) data read must be little endian");
 
272
    }
 
273
    value = le_expected[0];
 
274
    /* read 4 bytes apart, always aligned*/
 
275
    for(j=0;j < DATA_REP*sizeof(le_data)-4;j += 4) {
 
276
        fail_unless(cli_readint32(&data[j]) == value, "(2) data read must be little endian");
 
277
    }
 
278
}
 
279
END_TEST
 
280
 
 
281
/* test writing with different alignments, _i is parameter from tcase_add_loop_test */
 
282
START_TEST (test_cli_writeint32)
 
283
{
 
284
    size_t j;
 
285
    /* write 4 bytes apart, start is not always aligned*/
 
286
    for(j=_i;j < DATA_REP*sizeof(le_data) - 4;j += 4) {
 
287
        cli_writeint32(&data2[j], 0x12345678);
 
288
    }
 
289
    for(j=_i;j < DATA_REP*sizeof(le_data) - 4;j += 4) {
 
290
        fail_unless(cli_readint32(&data2[j]) == 0x12345678, "write/read mismatch");
 
291
    }
 
292
    /* write 4 bytes apart, always aligned*/
 
293
    for(j=0;j < DATA_REP*sizeof(le_data) - 4;j += 4) {
 
294
        cli_writeint32(&data2[j], 0x12345678);
 
295
    }
 
296
    for(j=0;j < DATA_REP*sizeof(le_data) - 4;j += 4) {
 
297
        fail_unless(cli_readint32(&data2[j]) == 0x12345678, "write/read mismatch");
 
298
    }
 
299
}
 
300
END_TEST
 
301
 
 
302
static Suite *test_cli_suite(void)
 
303
{
 
304
    Suite *s = suite_create("cli");
 
305
    TCase *tc_cli_others = tcase_create("byteorder_macros");
 
306
 
 
307
    suite_add_tcase (s, tc_cli_others);
 
308
    tcase_add_checked_fixture (tc_cli_others, data_setup, data_teardown);
 
309
    tcase_add_loop_test(tc_cli_others, test_cli_readint32, 0, 15);
 
310
    tcase_add_loop_test(tc_cli_others, test_cli_readint16, 0, 15);
 
311
    tcase_add_loop_test(tc_cli_others, test_cli_writeint32, 0, 15);
 
312
 
 
313
    return s;
 
314
}
 
315
#endif /* CHECK_HAVE_LOOPS */
 
316
 
 
317
void errmsg_expected(void)
 
318
{
 
319
        fputs("cli_errmsg() expected here\n", stderr);
 
320
}
 
321
 
 
322
int open_testfile(const char *name)
 
323
{
 
324
        int fd;
 
325
        const char * srcdir = getenv("srcdir");
 
326
        char *str;
 
327
 
 
328
        if(!srcdir) {
 
329
                /* when run from automake srcdir is set, but if run manually then not */
 
330
                srcdir = SRCDIR;
 
331
        }
 
332
 
 
333
        str = cli_malloc(strlen(name)+strlen(srcdir)+2);
 
334
        fail_unless(!!str, "cli_malloc");
 
335
        sprintf(str, "%s/%s", srcdir, name);
 
336
 
 
337
        fd = open(str, O_RDONLY);
 
338
        fail_unless(fd >= 0, "open()");
 
339
        free(str);
 
340
        return fd;
 
341
}
 
342
 
 
343
int main(int argc, char **argv)
 
344
{
 
345
    int nf;
 
346
    Suite *s = test_cl_suite();
 
347
    SRunner *sr = srunner_create(s);
 
348
#ifdef CHECK_HAVE_LOOPS
 
349
    srunner_add_suite(sr, test_cli_suite());
 
350
#else
 
351
    printf("*** Warning ***: your check version is too old,\nseveral important tests will not execute\n");
 
352
#endif
 
353
    srunner_add_suite(sr, test_jsnorm_suite());
 
354
    srunner_add_suite(sr, test_str_suite());
 
355
    srunner_add_suite(sr, test_regex_suite());
 
356
    srunner_add_suite(sr, test_disasm_suite());
 
357
    srunner_add_suite(sr, test_uniq_suite());
 
358
    srunner_add_suite(sr, test_matchers_suite());
 
359
 
 
360
    srunner_set_log(sr, "test.log");
 
361
    if(freopen("test-stderr.log","w+",stderr) == NULL) {
 
362
            fputs("Unable to redirect stderr!\n",stderr);
 
363
    }
 
364
    cl_debug();
 
365
 
 
366
    srunner_run_all(sr, CK_NORMAL);
 
367
    nf = srunner_ntests_failed(sr);
 
368
    srunner_free(sr);
 
369
    return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 
370
}
 
371
 
 
372
#endif /* HAVE_CHECK */