fe473bcb |
#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <limits.h> |
3dcc2d78 |
#include <fcntl.h> |
fe473bcb |
#include <string.h>
#include <check.h> |
d5f7afdd |
#include <sys/types.h>
#include <dirent.h> |
62ee12b2 |
#include <sys/mman.h> |
b2e7c931 |
|
849cdc78 |
#if HAVE_LIBXML2
#include <libxml/parser.h>
#endif
|
fe473bcb |
#include "../libclamav/clamav.h"
#include "../libclamav/others.h"
#include "../libclamav/matcher.h" |
04f9bedf |
#include "../libclamav/version.h" |
c5944b54 |
#include "../libclamav/dsig.h" |
a393d999 |
#include "../libclamav/fpu.h" |
a39b29cb |
#include "checks.h" |
fe473bcb |
|
a393d999 |
static int fpu_words = FPU_ENDIAN_INITME;
#define NO_FPU_ENDIAN (fpu_words == FPU_ENDIAN_UNKNOWN)
#define EA06_SCAN strstr(file, "clam.ea06.exe")
#define FALSE_NEGATIVE (EA06_SCAN && NO_FPU_ENDIAN)
|
fe473bcb |
/* extern void cl_free(struct cl_engine *engine); */
START_TEST (test_cl_free)
/*
struct cl_engine *engine = NULL;
cl_free(NULL);
*/
END_TEST
/* extern struct cl_engine *cl_dup(struct cl_engine *engine); */
START_TEST (test_cl_dup)
/*
struct cl_engine *engine;
fail_unless(NULL == cl_dup(NULL), "cl_dup null pointer");
*/
END_TEST
/* extern int cl_build(struct cl_engine *engine); */
START_TEST (test_cl_build)
/*
struct cl_engine *engine;
fail_unless(CL_ENULLARG == cl_build(NULL), "cl_build null pointer");
engine = calloc(sizeof(struct cl_engine),1);
fail_unless(engine, "cl_build calloc");
fail_unless(CL_ENULLARG == cl_build(engine), "cl_build(engine) with null ->root");
*/
/* engine->root = cli_calloc(CL_TARGET_TABLE_SIZE, sizeof(struct cli_matcher *)); */
END_TEST
/* extern void cl_debug(void); */
START_TEST (test_cl_debug) |
5cd3f734 |
{ |
2b9e5d29 |
int old_status = cli_debug_flag; |
fe473bcb |
cli_debug_flag = 0;
cl_debug();
fail_unless(1 == cli_debug_flag, "cl_debug failed to set cli_debug_flag");
cli_debug_flag = 1;
cl_debug();
fail_unless(1 == cli_debug_flag, "cl_debug failed when flag was already set"); |
2b9e5d29 |
cli_debug_flag = old_status; |
5cd3f734 |
} |
fe473bcb |
END_TEST
/* extern const char *cl_retdbdir(void); */
START_TEST (test_cl_retdbdir)
fail_unless(!strcmp(DATADIR, cl_retdbdir()), "cl_retdbdir");
END_TEST
|
add738d2 |
#ifndef REPO_VERSION
#define REPO_VERSION VERSION
#endif
|
fe473bcb |
/* extern const char *cl_retver(void); */
START_TEST (test_cl_retver) |
5cd3f734 |
{ |
04f9bedf |
const char *ver = cl_retver(); |
b105842c |
fail_unless(!strcmp(REPO_VERSION""VERSION_SUFFIX, ver),"cl_retver"); |
add738d2 |
fail_unless(strcspn(ver,"012345789") < strlen(ver),
"cl_retver must have a number"); |
5cd3f734 |
} |
fe473bcb |
END_TEST
/* extern void cl_cvdfree(struct cl_cvd *cvd); */
START_TEST (test_cl_cvdfree)
/*
struct cl_cvd *cvd1, *cvd2;
cvd1 = malloc(sizeof(struct cl_cvd));
fail_unless(cvd1, "cvd malloc");
cl_cvdfree(cvd1);
cvd2 = malloc(sizeof(struct cl_cvd));
cvd2->time = malloc(1);
cvd2->md5 = malloc(1);
cvd2->dsig= malloc(1);
cvd2->builder = malloc(1);
fail_unless(cvd2, "cvd malloc");
fail_unless(cvd2->time, "cvd malloc");
fail_unless(cvd2->md5, "cvd malloc");
fail_unless(cvd2->dsig, "cvd malloc");
fail_unless(cvd2->builder, "cvd malloc");
cl_cvdfree(cvd2);
cl_cvdfree(NULL);
*/
END_TEST
/* extern int cl_statfree(struct cl_stat *dbstat); */
START_TEST (test_cl_statfree)
/*
struct cl_stat *stat;
fail_unless(CL_ENULLARG == cl_statfree(NULL), "cl_statfree(NULL)");
stat = malloc(sizeof(struct cl_stat));
fail_unless(NULL != stat, "malloc");
fail_unless(CL_SUCCESS == cl_statfree(stat), "cl_statfree(empty_struct)");
stat = malloc(sizeof(struct cl_stat));
fail_unless(NULL != stat, "malloc");
stat->stattab = strdup("test");
fail_unless(NULL != stat->stattab, "strdup");
fail_unless(CL_SUCCESS == cl_statfree(stat), "cl_statfree(stat with stattab)");
stat = malloc(sizeof(struct cl_stat));
fail_unless(NULL != stat, "malloc");
stat->stattab = NULL;
fail_unless(CL_SUCCESS == cl_statfree(stat), "cl_statfree(stat with stattab) set to NULL");
*/
END_TEST
/* extern unsigned int cl_retflevel(void); */
START_TEST (test_cl_retflevel)
END_TEST
/* extern struct cl_cvd *cl_cvdhead(const char *file); */
START_TEST (test_cl_cvdhead)
/*
fail_unless(NULL == cl_cvdhead(NULL), "cl_cvdhead(null)");
fail_unless(NULL == cl_cvdhead("input/cl_cvdhead/1.txt"), "cl_cvdhead(515 byte file, all nulls)");
*/
/* the data read from the file is passed to cl_cvdparse, test cases for that are separate */
END_TEST
/* extern struct cl_cvd *cl_cvdparse(const char *head); */
START_TEST (test_cl_cvdparse)
END_TEST
|
d5f7afdd |
static int get_test_file(int i, char *file, unsigned fsize, unsigned long *size);
static struct cl_engine *g_engine;
|
d1b44b4d |
#ifdef CHECK_HAVE_LOOPS |
fe473bcb |
/* 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) */
START_TEST (test_cl_scandesc) |
d5f7afdd |
{
const char *virname = NULL;
char file[256];
unsigned long size;
unsigned long int scanned = 0;
int ret;
int fd = get_test_file(_i, file, sizeof(file), &size);
cli_dbgmsg("scanning (scandesc) %s\n", file);
ret = cl_scandesc(fd, &virname, &scanned, g_engine, CL_SCAN_STDOPT);
cli_dbgmsg("scan end (scandesc) %s\n", file);
|
a393d999 |
if (!FALSE_NEGATIVE) {
fail_unless_fmt(ret == CL_VIRUS, "cl_scandesc failed for %s: %s", file, cl_strerror(ret));
fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname);
} |
d5f7afdd |
close(fd);
} |
fe473bcb |
END_TEST
|
6ad45a29 |
START_TEST (test_cl_scandesc_allscan)
{
const char *virname = NULL;
char file[256];
unsigned long size;
unsigned long int scanned = 0;
int ret;
int fd = get_test_file(_i, file, sizeof(file), &size);
cli_dbgmsg("scanning (scandesc) %s\n", file); |
1f1bf36b |
ret = cl_scandesc(fd, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT); |
a393d999 |
|
6ad45a29 |
cli_dbgmsg("scan end (scandesc) %s\n", file);
|
a393d999 |
if (!FALSE_NEGATIVE) {
fail_unless_fmt(ret == CL_VIRUS, "cl_scandesc_allscan failed for %s: %s", file, cl_strerror(ret)); |
1f1bf36b |
fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname); |
a393d999 |
} |
6ad45a29 |
close(fd);
}
END_TEST
//* 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) */ |
fe473bcb |
START_TEST (test_cl_scanfile) |
d5f7afdd |
{
const char *virname = NULL;
char file[256];
unsigned long size;
unsigned long int scanned = 0;
int ret;
int fd = get_test_file(_i, file, sizeof(file), &size);
close(fd);
cli_dbgmsg("scanning (scanfile) %s\n", file);
ret = cl_scanfile(file, &virname, &scanned, g_engine, CL_SCAN_STDOPT);
cli_dbgmsg("scan end (scanfile) %s\n", file);
|
a393d999 |
if (!FALSE_NEGATIVE) {
fail_unless_fmt(ret == CL_VIRUS , "cl_scanfile failed for %s: %s", file, cl_strerror(ret));
fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname);
} |
d5f7afdd |
}
END_TEST
|
6ad45a29 |
START_TEST (test_cl_scanfile_allscan)
{
const char *virname = NULL;
char file[256];
unsigned long size;
unsigned long int scanned = 0;
int ret;
int fd = get_test_file(_i, file, sizeof(file), &size);
close(fd);
cli_dbgmsg("scanning (scanfile_allscan) %s\n", file); |
1f1bf36b |
ret = cl_scanfile(file, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT); |
6ad45a29 |
cli_dbgmsg("scan end (scanfile_allscan) %s\n", file);
|
a393d999 |
if (!FALSE_NEGATIVE) {
fail_unless_fmt(ret == CL_VIRUS, "cl_scanfile_allscan failed for %s: %s", file, cl_strerror(ret)); |
1f1bf36b |
fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname); |
a393d999 |
} |
6ad45a29 |
}
END_TEST
|
d5f7afdd |
START_TEST (test_cl_scanfile_callback)
{
const char *virname = NULL;
char file[256];
unsigned long size;
unsigned long int scanned = 0;
int ret;
int fd = get_test_file(_i, file, sizeof(file), &size);
close(fd);
cli_dbgmsg("scanning (scanfile_cb) %s\n", file);
/* TODO: test callbacks */
ret = cl_scanfile_callback(file, &virname, &scanned, g_engine, CL_SCAN_STDOPT, NULL);
cli_dbgmsg("scan end (scanfile_cb) %s\n", file);
|
a393d999 |
if (!FALSE_NEGATIVE) {
fail_unless_fmt(ret == CL_VIRUS, "cl_scanfile_cb failed for %s: %s", file, cl_strerror(ret));
fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname);
} |
d5f7afdd |
}
END_TEST
|
6ad45a29 |
START_TEST (test_cl_scanfile_callback_allscan)
{
const char *virname = NULL;
char file[256];
unsigned long size;
unsigned long int scanned = 0;
int ret;
int fd = get_test_file(_i, file, sizeof(file), &size);
close(fd);
cli_dbgmsg("scanning (scanfile_cb_allscan) %s\n", file);
/* TODO: test callbacks */ |
1f1bf36b |
ret = cl_scanfile_callback(file, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT, NULL); |
6ad45a29 |
cli_dbgmsg("scan end (scanfile_cb_allscan) %s\n", file);
|
a393d999 |
if (!FALSE_NEGATIVE) {
fail_unless_fmt(ret == CL_VIRUS, "cl_scanfile_cb_allscan failed for %s: %s", file, cl_strerror(ret)); |
1f1bf36b |
fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname); |
a393d999 |
} |
6ad45a29 |
}
END_TEST
|
d5f7afdd |
START_TEST (test_cl_scandesc_callback)
{
const char *virname = NULL;
char file[256];
unsigned long size;
unsigned long int scanned = 0;
int ret;
int fd = get_test_file(_i, file, sizeof(file), &size);
cli_dbgmsg("scanning (scandesc_cb) %s\n", file);
/* TODO: test callbacks */
ret = cl_scandesc_callback(fd, &virname, &scanned, g_engine, CL_SCAN_STDOPT, NULL);
cli_dbgmsg("scan end (scandesc_cb) %s\n", file);
|
a393d999 |
if (!FALSE_NEGATIVE) {
fail_unless_fmt(ret == CL_VIRUS, "cl_scanfile failed for %s: %s", file, cl_strerror(ret));
fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname);
} |
d5f7afdd |
close(fd);
} |
fe473bcb |
END_TEST |
6ad45a29 |
START_TEST (test_cl_scandesc_callback_allscan)
{
const char *virname = NULL;
char file[256];
unsigned long size;
unsigned long int scanned = 0;
int ret;
int fd = get_test_file(_i, file, sizeof(file), &size);
cli_dbgmsg("scanning (scandesc_cb_allscan) %s\n", file);
/* TODO: test callbacks */ |
1f1bf36b |
ret = cl_scandesc_callback(fd, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT, NULL); |
6ad45a29 |
cli_dbgmsg("scan end (scandesc_cb_allscan) %s\n", file);
|
a393d999 |
if (!FALSE_NEGATIVE) {
fail_unless_fmt(ret == CL_VIRUS, "cl_scanfile_allscan failed for %s: %s", file, cl_strerror(ret)); |
1f1bf36b |
fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname); |
a393d999 |
} |
6ad45a29 |
close(fd);
}
END_TEST
|
d1b44b4d |
#endif |
fe473bcb |
/* int cl_load(const char *path, struct cl_engine **engine, unsigned int *signo, unsigned int options) */
START_TEST (test_cl_load)
END_TEST
/* int cl_cvdverify(const char *file) */
START_TEST (test_cl_cvdverify)
END_TEST
/* int cl_statinidir(const char *dirname, struct cl_stat *dbstat) */
START_TEST (test_cl_statinidir)
END_TEST
/* int cl_statchkdir(const struct cl_stat *dbstat) */
START_TEST (test_cl_statchkdir)
END_TEST
/* void cl_settempdir(const char *dir, short leavetemps) */
START_TEST (test_cl_settempdir)
END_TEST
/* const char *cl_strerror(int clerror) */
START_TEST (test_cl_strerror)
END_TEST
|
d5f7afdd |
static char **testfiles = NULL;
static unsigned testfiles_n = 0; |
f0f3fe69 |
|
ca804a8d |
static const int expected_testfiles = 48; |
d5f7afdd |
|
f4f331ae |
static unsigned skip_files(void) |
97fd85d1 |
{ |
f4f331ae |
unsigned skipped = 0;
/* skip .rar files if unrar is disabled */ |
97fd85d1 |
const char *s = getenv("unrar_disabled"); |
f4f331ae |
if (s && !strcmp(s, "1")) {
skipped += 2;
} |
97fd85d1 |
|
f4f331ae |
/* skip .bz2 files if bzip is disabled */
#if HAVE_BZLIB_H
#else
skipped += 2;
#endif |
97fd85d1 |
|
f4f331ae |
/* skip [placeholder] files if xml is disabled */
#if HAVE_LIBXML2
#else
skipped += 0;
#endif |
97fd85d1 |
|
f4f331ae |
return skipped; |
97fd85d1 |
}
|
d5f7afdd |
static void init_testfiles(void)
{
struct dirent *dirent;
unsigned i = 0; |
04ad6854 |
int expect = expected_testfiles; |
d5f7afdd |
DIR *d = opendir(OBJDIR"/../test");
fail_unless(!!d, "opendir");
if (!d)
return;
testfiles = NULL;
testfiles_n = 0;
while ((dirent = readdir(d))) {
if (strncmp(dirent->d_name, "clam", 4))
continue; |
97fd85d1 |
i++; |
d5f7afdd |
testfiles = cli_realloc(testfiles, i*sizeof(*testfiles));
fail_unless(!!testfiles, "cli_realloc");
testfiles[i-1] = strdup(dirent->d_name);
}
testfiles_n = i; |
b02190b4 |
if (get_fpu_endian() == FPU_ENDIAN_UNKNOWN)
expect--; |
f4f331ae |
expect -= skip_files(); |
04ad6854 |
fail_unless_fmt(testfiles_n == expect, "testfiles: %d != %d", testfiles_n, expect); |
d5f7afdd |
closedir(d);
}
static void free_testfiles(void)
{
unsigned i;
for (i=0;i<testfiles_n;i++) {
free(testfiles[i]);
}
free(testfiles);
testfiles = NULL;
testfiles_n = 0;
}
static int inited = 0;
static void engine_setup(void)
{
unsigned int sigs = 0;
const char *hdb = OBJDIR"/clamav.hdb";
init_testfiles();
if (!inited)
fail_unless(cl_init(CL_INIT_DEFAULT) == 0, "cl_init");
inited = 1;
g_engine = cl_engine_new();
fail_unless(!!g_engine, "engine");
fail_unless_fmt(cl_load(hdb, g_engine, &sigs, CL_DB_STDOPT) == 0, "cl_load %s", hdb);
fail_unless(sigs == 1, "sigs");
fail_unless(cl_engine_compile(g_engine) == 0, "cl_engine_compile");
}
static void engine_teardown(void)
{
free_testfiles();
cl_engine_free(g_engine);
}
static int get_test_file(int i, char *file, unsigned fsize, unsigned long *size)
{
int fd; |
a2a004df |
STATBUF st; |
d5f7afdd |
|
04ad6854 |
fail_unless(i < testfiles_n, "%i < %i %s", i, testfiles_n, file); |
d5f7afdd |
snprintf(file, fsize, OBJDIR"/../test/%s", testfiles[i]);
fd = open(file, O_RDONLY);
fail_unless(fd > 0, "open"); |
a2a004df |
fail_unless(FSTAT(fd, &st) == 0, "fstat"); |
d5f7afdd |
*size = st.st_size;
return fd;
} |
b32ad857 |
#ifdef CHECK_HAVE_LOOPS |
d5f7afdd |
|
e8b63834 |
static off_t pread_cb(void *handle, void *buf, size_t count, off_t offset) |
62ee12b2 |
{
return pread(*((int*)handle), buf, count, offset);
}
START_TEST (test_cl_scanmap_callback_handle)
{
const char *virname = NULL; |
81e57728 |
unsigned long int scanned = 0; |
62ee12b2 |
cl_fmap_t *map;
int ret; |
592e246c |
char file[256];
unsigned long size; |
62ee12b2 |
|
592e246c |
int fd = get_test_file(_i, file, sizeof(file), &size); |
62ee12b2 |
/* intentionally use different way than scanners.c for testing */ |
592e246c |
map = cl_fmap_open_handle(&fd, 0, size, pread_cb, 1); |
62ee12b2 |
fail_unless(!!map, "cl_fmap_open_handle");
|
81e57728 |
cli_dbgmsg("scanning (handle) %s\n", file); |
62ee12b2 |
ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, CL_SCAN_STDOPT, NULL); |
81e57728 |
cli_dbgmsg("scan end (handle) %s\n", file);
|
a393d999 |
if (!FALSE_NEGATIVE) {
fail_unless_fmt(ret == CL_VIRUS, "cl_scanmap_callback failed for %s: %s", file, cl_strerror(ret));
fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname);
} |
62ee12b2 |
close(fd);
}
END_TEST
|
6ad45a29 |
START_TEST (test_cl_scanmap_callback_handle_allscan)
{
const char *virname = NULL;
unsigned long int scanned = 0;
cl_fmap_t *map;
int ret;
char file[256];
unsigned long size;
int fd = get_test_file(_i, file, sizeof(file), &size);
/* intentionally use different way than scanners.c for testing */
map = cl_fmap_open_handle(&fd, 0, size, pread_cb, 1); |
a393d999 |
fail_unless(!!map, "cl_fmap_open_handle %s"); |
6ad45a29 |
cli_dbgmsg("scanning (handle) allscan %s\n", file); |
1f1bf36b |
ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT, NULL); |
6ad45a29 |
cli_dbgmsg("scan end (handle) allscan %s\n", file);
|
a393d999 |
if (!FALSE_NEGATIVE) {
fail_unless_fmt(ret == CL_VIRUS, "cl_scanmap_callback_allscan failed for %s: %s", file, cl_strerror(ret)); |
1f1bf36b |
fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname); |
a393d999 |
} |
6ad45a29 |
close(fd);
}
END_TEST
|
62ee12b2 |
START_TEST (test_cl_scanmap_callback_mem)
{
const char *virname = NULL; |
81e57728 |
unsigned long int scanned = 0; |
62ee12b2 |
cl_fmap_t *map;
int ret;
void *mem; |
592e246c |
unsigned long size;
char file[256]; |
62ee12b2 |
|
592e246c |
int fd = get_test_file(_i, file, sizeof(file), &size); |
62ee12b2 |
|
592e246c |
mem = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); |
62ee12b2 |
fail_unless(mem != MAP_FAILED, "mmap");
/* intentionally use different way than scanners.c for testing */ |
592e246c |
map = cl_fmap_open_memory(mem, size); |
62ee12b2 |
fail_unless(!!map, "cl_fmap_open_mem");
|
81e57728 |
cli_dbgmsg("scanning (mem) %s\n", file); |
62ee12b2 |
ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, CL_SCAN_STDOPT, NULL); |
81e57728 |
cli_dbgmsg("scan end (mem) %s\n", file); |
a393d999 |
if (!FALSE_NEGATIVE) {
fail_unless_fmt(ret == CL_VIRUS, "cl_scanmap_callback failed for %s: %s", file, cl_strerror(ret));
fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s for %s", virname, file);
} |
62ee12b2 |
close(fd); |
0d54f271 |
cl_fmap_close(map); |
62ee12b2 |
|
592e246c |
munmap(mem, size); |
62ee12b2 |
}
END_TEST |
6ad45a29 |
START_TEST (test_cl_scanmap_callback_mem_allscan)
{
const char *virname = NULL;
unsigned long int scanned = 0;
cl_fmap_t *map;
int ret;
void *mem;
unsigned long size;
char file[256];
int fd = get_test_file(_i, file, sizeof(file), &size);
mem = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
fail_unless(mem != MAP_FAILED, "mmap");
/* intentionally use different way than scanners.c for testing */
map = cl_fmap_open_memory(mem, size); |
a393d999 |
fail_unless(!!map, "cl_fmap_open_mem %s"); |
6ad45a29 |
cli_dbgmsg("scanning (mem) allscan %s\n", file); |
1f1bf36b |
ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT, NULL); |
6ad45a29 |
cli_dbgmsg("scan end (mem) allscan %s\n", file); |
a393d999 |
if (!FALSE_NEGATIVE) {
fail_unless_fmt(ret == CL_VIRUS, "cl_scanmap_callback failed for %s: %s", file, cl_strerror(ret)); |
1f1bf36b |
fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s for %s", virname, file); |
a393d999 |
} |
6ad45a29 |
close(fd);
cl_fmap_close(map);
munmap(mem, size);
}
END_TEST |
b32ad857 |
#endif |
62ee12b2 |
|
c47e43ce |
static Suite *test_cl_suite(void) |
fe473bcb |
{ |
c47e43ce |
Suite *s = suite_create("cl_api");
TCase *tc_cl = tcase_create("cl_dup"); |
d5f7afdd |
TCase *tc_cl_scan = tcase_create("cl_scan"); |
11bdd8a7 |
char *user_timeout = NULL; |
04ad6854 |
int expect = expected_testfiles; |
fe473bcb |
suite_add_tcase (s, tc_cl);
tcase_add_test(tc_cl, test_cl_free);
tcase_add_test(tc_cl, test_cl_dup);
tcase_add_test(tc_cl, test_cl_build);
tcase_add_test(tc_cl, test_cl_debug);
tcase_add_test(tc_cl, test_cl_retdbdir);
tcase_add_test(tc_cl, test_cl_retver);
tcase_add_test(tc_cl, test_cl_cvdfree);
tcase_add_test(tc_cl, test_cl_statfree);
tcase_add_test(tc_cl, test_cl_retflevel);
tcase_add_test(tc_cl, test_cl_cvdhead);
tcase_add_test(tc_cl, test_cl_cvdparse);
tcase_add_test(tc_cl, test_cl_load);
tcase_add_test(tc_cl, test_cl_cvdverify);
tcase_add_test(tc_cl, test_cl_statinidir);
tcase_add_test(tc_cl, test_cl_statchkdir);
tcase_add_test(tc_cl, test_cl_settempdir);
tcase_add_test(tc_cl, test_cl_strerror);
|
d5f7afdd |
suite_add_tcase(s, tc_cl_scan);
tcase_add_checked_fixture (tc_cl_scan, engine_setup, engine_teardown); |
d1b44b4d |
#ifdef CHECK_HAVE_LOOPS |
b02190b4 |
if (get_fpu_endian() == FPU_ENDIAN_UNKNOWN)
expect--; |
f4f331ae |
expect -= skip_files(); |
04ad6854 |
tcase_add_loop_test(tc_cl_scan, test_cl_scandesc, 0, expect);
tcase_add_loop_test(tc_cl_scan, test_cl_scandesc_allscan, 0, expect);
tcase_add_loop_test(tc_cl_scan, test_cl_scanfile, 0, expect);
tcase_add_loop_test(tc_cl_scan, test_cl_scanfile_allscan, 0, expect);
tcase_add_loop_test(tc_cl_scan, test_cl_scandesc_callback, 0, expect);
tcase_add_loop_test(tc_cl_scan, test_cl_scandesc_callback_allscan, 0, expect);
tcase_add_loop_test(tc_cl_scan, test_cl_scanfile_callback, 0, expect);
tcase_add_loop_test(tc_cl_scan, test_cl_scanfile_callback_allscan, 0, expect);
tcase_add_loop_test(tc_cl_scan, test_cl_scanmap_callback_handle, 0, expect);
tcase_add_loop_test(tc_cl_scan, test_cl_scanmap_callback_handle_allscan, 0, expect);
tcase_add_loop_test(tc_cl_scan, test_cl_scanmap_callback_mem, 0, expect);
tcase_add_loop_test(tc_cl_scan, test_cl_scanmap_callback_mem_allscan, 0, expect); |
11bdd8a7 |
user_timeout = getenv("T");
if (user_timeout) {
int timeout = atoi(user_timeout);
tcase_set_timeout(tc_cl_scan, timeout); |
c2b36ddd |
printf("Using test case timeout of %d seconds set by user\n", timeout);
} else {
printf("Using default test timeout; alter by setting 'T' env var (in seconds)\n"); |
11bdd8a7 |
} |
d1b44b4d |
#endif |
fe473bcb |
return s;
}
|
c47e43ce |
static uint8_t le_data[4] = {0x67,0x45,0x23,0x01};
static int32_t le_expected[4] = { 0x01234567, 0x67012345, 0x45670123, 0x23456701}; |
2565ef49 |
uint8_t *data = NULL;
uint8_t *data2 = NULL; |
c47e43ce |
#define DATA_REP 100
static void data_setup(void)
{
uint8_t *p;
size_t i;
|
2565ef49 |
data = malloc(sizeof(le_data)*DATA_REP);
data2 = malloc(sizeof(le_data)*DATA_REP);
fail_unless(!!data, "unable to allocate memory for fixture");
fail_unless(!!data2, "unable to allocate memory for fixture"); |
c47e43ce |
p = data;
/* make multiple copies of le_data, we need to run readint tests in a loop, so we need
* to give it some data to run it on */
for(i=0; i<DATA_REP;i++) {
memcpy(p, le_data, sizeof(le_data));
p += sizeof(le_data);
}
memset(data2, 0, DATA_REP*sizeof(le_data));
}
static void data_teardown(void)
{
free(data); |
377a2330 |
free(data2); |
c47e43ce |
}
|
99f74adc |
#ifdef CHECK_HAVE_LOOPS |
c47e43ce |
/* test reading with different alignments, _i is parameter from tcase_add_loop_test */ |
2565ef49 |
START_TEST (test_cli_readint16)
{
size_t j;
int16_t value;
/* read 2 bytes apart, start is not always aligned*/
for(j=_i;j <= DATA_REP*sizeof(le_data)-2;j += 2) {
value = le_expected[j&3];
fail_unless(cli_readint16(&data[j]) == value, "(1) data read must be little endian");
}
/* read 2 bytes apart, always aligned*/
for(j=0;j <= DATA_REP*sizeof(le_data)-2;j += 2) {
value = le_expected[j&3];
fail_unless(cli_readint16(&data[j]) == value, "(2) data read must be little endian");
}
}
END_TEST
/* test reading with different alignments, _i is parameter from tcase_add_loop_test */
START_TEST (test_cli_readint32) |
c47e43ce |
{
size_t j;
int32_t value = le_expected[_i&3];
/* read 4 bytes apart, start is not always aligned*/ |
2565ef49 |
for(j=_i;j < DATA_REP*sizeof(le_data)-4;j += 4) { |
c47e43ce |
fail_unless(cli_readint32(&data[j]) == value, "(1) data read must be little endian");
}
value = le_expected[0];
/* read 4 bytes apart, always aligned*/ |
2565ef49 |
for(j=0;j < DATA_REP*sizeof(le_data)-4;j += 4) { |
c47e43ce |
fail_unless(cli_readint32(&data[j]) == value, "(2) data read must be little endian");
}
}
END_TEST
/* test writing with different alignments, _i is parameter from tcase_add_loop_test */ |
2565ef49 |
START_TEST (test_cli_writeint32) |
c47e43ce |
{
size_t j;
/* write 4 bytes apart, start is not always aligned*/
for(j=_i;j < DATA_REP*sizeof(le_data) - 4;j += 4) {
cli_writeint32(&data2[j], 0x12345678);
}
for(j=_i;j < DATA_REP*sizeof(le_data) - 4;j += 4) {
fail_unless(cli_readint32(&data2[j]) == 0x12345678, "write/read mismatch");
}
/* write 4 bytes apart, always aligned*/
for(j=0;j < DATA_REP*sizeof(le_data) - 4;j += 4) {
cli_writeint32(&data2[j], 0x12345678);
}
for(j=0;j < DATA_REP*sizeof(le_data) - 4;j += 4) {
fail_unless(cli_readint32(&data2[j]) == 0x12345678, "write/read mismatch");
}
}
END_TEST
|
7b57a833 |
static struct dsig_test {
const char *md5;
const char *dsig;
int result;
} dsig_tests [] = {
{"ae307614434715274c60854c931a26de", "60uhCFmiN48J8r6c7coBv9Q1mehAWEGh6GPYA+60VhQcuXfb0iV1O+sCEyMiRXt/iYF6vXtPXHVd6DiuZ4Gfrry7sVQqNTt3o1/KwU1rc0l5FHgX/nC99fdr/fjaFtinMtRnUXHLeu0j8e6HK+7JLBpD37fZ60GC9YY86EclYGe",
CL_SUCCESS},
{"96b7feb3b2a863846438809fe481906f", "Zh5gmf09Zfj6V4gmRKu/NURzhFiE9VloI7w1G33BgDdGSs0Xhscx6sjPUpFSCPsjOalyS4L8q7RS+NdGvNCsLymiIH6RYItlOZsygFhcGuH4jt15KAaAkvEg2TwmqR8z41nUaMlZ0c8q1MXYCLvQJyFARsfzIxS3PAoN2Y3HPoe",
CL_SUCCESS},
{"ae307614434715274c60854c931a26de", "Zh5gmf09Zfj6V4gmRKu/NURzhFiE9VloI7w1G33BgDdGSs0Xhscx6sjPUpFSCPsjOalyS4L8q7RS+NdGvNCsLymiIH6RYItlOZsygFhcGuH4jt15KAaAkvEg2TwmqR8z41nUaMlZ0c8q1MXYCLvQJyFARsfzIxS3PAoN2Y3HPoe", |
871177cd |
CL_EVERIFY}, |
7b57a833 |
{"96b7feb3b2a863846438809fe481906f", "60uhCFmiN48J8r6c7coBv9Q1mehAWEGh6GPYA+60VhQcuXfb0iV1O+sCEyMiRXt/iYF6vXtPXHVd6DiuZ4Gfrry7sVQqNTt3o1/KwU1rc0l5FHgX/nC99fdr/fjaFtinMtRnUXHLeu0j8e6HK+7JLBpD37fZ60GC9YY86EclYGe", |
871177cd |
CL_EVERIFY}, |
7b57a833 |
{"ae307614434715274060854c931a26de", "60uhCFmiN48J8r6c7coBv9Q1mehAWEGh6GPYA+60VhQcuXfb0iV1O+sCEyMiRXt/iYF6vXtPXHVd6DiuZ4Gfrry7sVQqNTt3o1/KwU1rc0l5FHgX/nC99fdr/fjaFtinMtRnUXHLeu0j8e6HK+7JLBpD37fZ60GC9YY86EclYGe", |
871177cd |
CL_EVERIFY}, |
7b57a833 |
{"ae307614434715274c60854c931a26de", "60uhCFmiN48J8r6c7coBv9Q1mehAWEGh6GPYA+60VhQcuXfb0iV1O+sCEyMiRXt/iYF6vXtPXHVd6DiuZ4Gfrry7sVQqNTt3o1/KwU1rc0l5FHgX/nC99fdr/fjaatinMtRnUXHLeu0j8e6HK+7JLBpD37fZ60GC9YY86EclYGe", |
871177cd |
CL_EVERIFY}, |
7b57a833 |
{"96b7feb3b2a863846438809fe481906f", "Zh5gmf09Zfj6V4gmRKu/NURzhFiE9VloI7w1G33BgDdGSs0Xhscx6sjPUpFSCPsjOalyS4L8q7RS+NdGvNCsLymiIH6RYItlOZsygFhcGuH4jt15KAaAkvEg2TwmqR8z41nUaMlZ0c8q1MYYCLvQJyFARsfzIxS3PAoN2Y3HPoe", |
871177cd |
CL_EVERIFY}, |
7b57a833 |
{"ge307614434715274c60854c931a26dee","60uhCFmiN48J8r6c7coBv9Q1mehAWEGh6GPYA+60VhQcuXfb0iV1O+sCEyMiRXt/iYF6vXtPXHVd6DiuZ4Gfrry7sVQqNTt3o1/KwU1rc0l5FHgX/nC99fdr/fjaFtinMtRnUXHLeu0j8e6HK+7JLBpD37fZ60GC9YY86EclYGe", |
871177cd |
CL_EVERIFY}, |
7b57a833 |
{"ae307614434715274c60854c931a26de", "60uhCFmiN48J8r6c7coBv9Q1mehAWEGh6GPYA+60VhQcuXfb0iV1O+sCEyMiRXt/iYF6vXtPXHVd6DiuZ4Gfrry7sVQqNTt3o1/KwU1rc0l5FHgX/nC99fdr/fjaFtinMtRnUXHLeu0j8e6HK+7JLBpD37fZ60GC9YY86EclYGee", |
871177cd |
CL_EVERIFY}, |
7b57a833 |
{"ae307614434715274c60854c931a26de", "60uhCFmiN48J8r6c7coBv9Q1mehAWEGh6GPYA+", |
871177cd |
CL_EVERIFY} |
7b57a833 |
};
static const size_t dsig_tests_cnt = sizeof(dsig_tests)/sizeof(dsig_tests[0]);
START_TEST (test_cli_dsig)
{
fail_unless(cli_versig(dsig_tests[_i].md5, dsig_tests[_i].dsig) == dsig_tests[_i].result,
"digital signature verification test failed");
}
END_TEST
|
4e46d65d |
static uint8_t tv1[3] = {
0x61, 0x62, 0x63
};
static uint8_t tv2[56] = {
0x61, 0x62, 0x63, 0x64, 0x62, 0x63, 0x64, 0x65,
0x63, 0x64, 0x65, 0x66, 0x64, 0x65, 0x66, 0x67,
0x65, 0x66, 0x67, 0x68, 0x66, 0x67, 0x68, 0x69,
0x67, 0x68, 0x69, 0x6a, 0x68, 0x69, 0x6a, 0x6b,
0x69, 0x6a, 0x6b, 0x6c, 0x6a, 0x6b, 0x6c, 0x6d,
0x6b, 0x6c, 0x6d, 0x6e, 0x6c, 0x6d, 0x6e, 0x6f,
0x6d, 0x6e, 0x6f, 0x70, 0x6e, 0x6f, 0x70, 0x71
};
static uint8_t res256[3][SHA256_HASH_SIZE] = {
{ 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad },
{ 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93,
0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 },
{ 0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92, 0x81, 0xa1, 0xc7, 0xe2,
0x84, 0xd7, 0x3e, 0x67, 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e,
0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0 }
};
START_TEST (test_sha256)
{ |
da6e06dd |
void *sha256; |
4e46d65d |
uint8_t hsha256[SHA256_HASH_SIZE];
uint8_t buf[1000];
int i;
memset (buf, 0x61, sizeof (buf));
|
b2e7c931 |
cl_sha256(tv1, sizeof(tv1), hsha256, NULL); |
4e46d65d |
fail_unless(!memcmp (hsha256, res256[0], sizeof (hsha256)), "sha256 test vector #1 failed");
|
b2e7c931 |
cl_sha256(tv2, sizeof(tv2), hsha256, NULL); |
4e46d65d |
fail_unless(!memcmp (hsha256, res256[1], sizeof (hsha256)), "sha256 test vector #2 failed");
|
da6e06dd |
sha256 = cl_hash_init("sha256"); |
f077c617 |
fail_unless(sha256 != NULL, "Could not create EVP_MD_CTX for sha256");
|
4e46d65d |
for (i = 0; i < 1000; i++) |
da6e06dd |
cl_update_hash (sha256, buf, sizeof (buf));
cl_finish_hash(sha256, hsha256); |
4e46d65d |
fail_unless(!memcmp (hsha256, res256[2], sizeof (hsha256)), "sha256 test vector #3 failed");
}
END_TEST
|
c47e43ce |
static Suite *test_cli_suite(void)
{
Suite *s = suite_create("cli");
TCase *tc_cli_others = tcase_create("byteorder_macros"); |
7b57a833 |
TCase *tc_cli_dsig = tcase_create("digital signatures"); |
c47e43ce |
suite_add_tcase (s, tc_cli_others);
tcase_add_checked_fixture (tc_cli_others, data_setup, data_teardown); |
7b57a833 |
tcase_add_loop_test(tc_cli_others, test_cli_readint32, 0, 16);
tcase_add_loop_test(tc_cli_others, test_cli_readint16, 0, 16);
tcase_add_loop_test(tc_cli_others, test_cli_writeint32, 0, 16);
suite_add_tcase (s, tc_cli_dsig);
tcase_add_loop_test(tc_cli_dsig, test_cli_dsig, 0, dsig_tests_cnt); |
4e46d65d |
tcase_add_test(tc_cli_dsig, test_sha256); |
c47e43ce |
return s;
} |
61b295f4 |
#endif /* CHECK_HAVE_LOOPS */ |
c47e43ce |
|
5ee56e41 |
void errmsg_expected(void)
{
fputs("cli_errmsg() expected here\n", stderr);
}
|
3dcc2d78 |
int open_testfile(const char *name)
{
int fd;
const char * srcdir = getenv("srcdir");
char *str;
if(!srcdir) {
/* when run from automake srcdir is set, but if run manually then not */
srcdir = SRCDIR;
}
str = cli_malloc(strlen(name)+strlen(srcdir)+2);
fail_unless(!!str, "cli_malloc");
sprintf(str, "%s/%s", srcdir, name);
fd = open(str, O_RDONLY); |
d5d06ecc |
fail_unless_fmt(fd >= 0, "open() failed: %s", str); |
3dcc2d78 |
free(str);
return fd;
}
|
1279faf6 |
void diff_file_mem(int fd, const char *ref, size_t len)
{ |
e0ac8b20 |
char c1,c2; |
1279faf6 |
size_t p, reflen = len;
char *buf = cli_malloc(len);
|
d5d06ecc |
fail_unless_fmt(!!buf, "unable to malloc buffer: %d", len); |
6a53bbdf |
p = read(fd, buf, len); |
d5d06ecc |
fail_unless_fmt(p == len, "file is smaller: %lu, expected: %lu", p, len); |
1279faf6 |
p = 0;
while(len > 0) { |
e0ac8b20 |
c1 = ref[p];
c2 = buf[p];
if(c1 != c2)
break; |
1279faf6 |
p++;
len--;
} |
e0ac8b20 |
if (len > 0) |
d5d06ecc |
fail_unless_fmt(c1 == c2, "file contents mismatch at byte: %lu, was: %c, expected: %c", p, c2, c1); |
1279faf6 |
free(buf);
p = lseek(fd, 0, SEEK_END); |
d5d06ecc |
fail_unless_fmt(p == reflen, "trailing garbage, file size: %ld, expected: %ld", p, reflen); |
1279faf6 |
close(fd);
}
void diff_files(int fd, int ref_fd)
{
char *ref;
ssize_t nread;
off_t siz = lseek(ref_fd, 0, SEEK_END); |
d5d06ecc |
fail_unless_fmt(siz != -1, "lseek failed"); |
1279faf6 |
ref = cli_malloc(siz); |
d5d06ecc |
fail_unless_fmt(!!ref, "unable to malloc buffer: %d", siz); |
1279faf6 |
|
d5d06ecc |
fail_unless_fmt(lseek(ref_fd, 0, SEEK_SET) == 0,"lseek failed"); |
1279faf6 |
nread = read(ref_fd, ref, siz); |
d5d06ecc |
fail_unless_fmt(nread == siz, "short read, expected: %ld, was: %ld", siz, nread); |
1279faf6 |
close(ref_fd);
diff_file_mem(fd, ref, siz);
free(ref);
}
|
7866b37c |
#ifdef USE_MPOOL |
47d40feb |
static mpool_t *pool; |
563582a1 |
#else
static void *pool;
#endif
struct cli_dconf *dconf;
void dconf_setup(void)
{
pool = NULL;
dconf = NULL; |
7866b37c |
#ifdef USE_MPOOL |
47d40feb |
pool = mpool_create(); |
563582a1 |
fail_unless(!!pool, "unable to create pool");
#endif |
47d40feb |
dconf = cli_mpool_dconf_init(pool); |
563582a1 |
fail_unless(!!dconf, "failed to init dconf");
}
void dconf_teardown(void)
{ |
47d40feb |
mpool_free(pool, dconf); |
7866b37c |
#ifdef USE_MPOOL |
563582a1 |
if (pool) |
47d40feb |
mpool_destroy(pool); |
563582a1 |
#endif
}
|
acba3cf5 |
static void check_version_compatible()
{
/* check 0.9.8 is not ABI compatible with 0.9.6,
* if by accident you compile with check 0.9.6 header
* and link with 0.9.8 then check will hang/crash. */
if ((check_major_version != CHECK_MAJOR_VERSION) ||
(check_minor_version != CHECK_MINOR_VERSION) ||
(check_micro_version != CHECK_MICRO_VERSION)) {
fprintf(stderr, "ERROR: check version mismatch!\n"
"\tVersion from header: %u.%u.%u\n"
"\tVersion from library: %u.%u.%u\n"
"\tMake sure check.h and -lcheck are same version!\n",
CHECK_MAJOR_VERSION,
CHECK_MINOR_VERSION,
CHECK_MICRO_VERSION,
check_major_version,
check_minor_version,
check_micro_version);
exit(EXIT_FAILURE);
}
} |
563582a1 |
|
15adbc84 |
int main(void) |
fe473bcb |
{ |
c47e43ce |
int nf; |
acba3cf5 |
Suite *s;
SRunner *sr;
|
f9afc309 |
cl_initialize_crypto();
|
a393d999 |
fpu_words = get_fpu_endian();
|
acba3cf5 |
check_version_compatible();
s = test_cl_suite();
sr = srunner_create(s); |
99f74adc |
#ifdef CHECK_HAVE_LOOPS |
c47e43ce |
srunner_add_suite(sr, test_cli_suite()); |
61b295f4 |
#else |
abbd1d36 |
printf("*** Warning ***: your check version is too old,\nseveral important tests will not execute\n"); |
99f74adc |
#endif |
4a6ade44 |
srunner_add_suite(sr, test_jsnorm_suite()); |
eb290151 |
srunner_add_suite(sr, test_str_suite()); |
9ee053fe |
srunner_add_suite(sr, test_regex_suite()); |
c92b0057 |
srunner_add_suite(sr, test_disasm_suite()); |
5e07cfed |
srunner_add_suite(sr, test_uniq_suite()); |
ec285505 |
srunner_add_suite(sr, test_matchers_suite()); |
1279faf6 |
srunner_add_suite(sr, test_htmlnorm_suite()); |
d99c0c42 |
srunner_add_suite(sr, test_bytecode_suite()); |
fe473bcb |
|
d5f7afdd |
|
fe473bcb |
srunner_set_log(sr, "test.log"); |
a497dce5 |
if(freopen("test-stderr.log","w+",stderr) == NULL) {
fputs("Unable to redirect stderr!\n",stderr);
} |
5cd3f734 |
cl_debug(); |
5ee56e41 |
|
fe473bcb |
srunner_run_all(sr, CK_NORMAL);
nf = srunner_ntests_failed(sr); |
c2b36ddd |
if (nf)
printf("NOTICE: Use the 'T' environment variable to adjust testcase timeout\n"); |
fe473bcb |
srunner_free(sr); |
62ee12b2 |
|
849cdc78 |
#if HAVE_LIBXML2
xmlCleanupParser();
#endif |
f9afc309 |
cl_cleanup_crypto();
|
fe473bcb |
return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
} |