unit_tests/check_bytecode.c
3411775b
 /*
  *  Unit tests for bytecode functions. 
  *
  *  Copyright (C) 2009 Sourcefire, Inc.
  *
  *  Authors: Török Edvin
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
  *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  *  MA 02110-1301, USA.
  */
 #if HAVE_CONFIG_H
 #include "clamav-config.h"
 #endif
 
 #include <stdio.h>
 
 #include <stdlib.h>
 #include <limits.h>
 #include <string.h>
 #include <check.h>
 #include "../libclamav/clamav.h"
 #include "../libclamav/others.h"
 #include "../libclamav/bytecode.h"
 #include "checks.h"
 
2487a4a3
 static void runtest(const char *file, uint64_t expected, int fail, int nojit)
3411775b
 {
     int rc;
     int fd = open_testfile(file);
     FILE *f;
     struct cli_bc bc;
     struct cli_bc_ctx *ctx;
d1487222
     struct cli_all_bc bcs;
3411775b
     uint64_t v;
 
     fail_unless(fd >= 0, "retmagic open failed");
     f = fdopen(fd, "r");
     fail_unless(!!f, "retmagic fdopen failed");
 
     cl_debug();
 
2487a4a3
     if (!nojit) {
 	rc = cli_bytecode_init(&bcs);
 	fail_unless(rc == CL_SUCCESS, "cli_bytecode_init failed");
     } else {
 	bcs.engine = NULL;
     }
d1487222
 
     bcs.all_bcs = &bc;
     bcs.count = 1;
 
3411775b
     rc = cli_bytecode_load(&bc, f, NULL);
     fail_unless(rc == CL_SUCCESS, "cli_bytecode_load failed");
     fclose(f);
 
d1487222
     rc = cli_bytecode_prepare(&bcs);
6922903a
     fail_unless(rc == CL_SUCCESS, "cli_bytecode_prepare failed");
 
2487a4a3
     if (have_clamjit && !nojit && nojit != -1) {
 	fail_unless(bc.state == bc_jit, "preparing for JIT failed");
     }
 
3411775b
     ctx = cli_bytecode_context_alloc();
     fail_unless(!!ctx, "cli_bytecode_context_alloc failed");
 
     cli_bytecode_context_setfuncid(ctx, &bc, 0);
85a25497
     rc = cli_bytecode_run(&bcs, &bc, ctx);
646395bb
     fail_unless_fmt(rc == fail, "cli_bytecode_run failed, expected: %u, have: %u\n",
 		    fail, rc);
3411775b
 
6b67ec6e
     if (rc == CL_SUCCESS) {
 	v = cli_bytecode_context_getresult_int(ctx);
 	fail_unless_fmt(v == expected, "Invalid return value from bytecode run, expected: %llx, have: %llx\n",
 			expected, v);
     }
3411775b
     cli_bytecode_context_destroy(ctx);
     cli_bytecode_destroy(&bc);
d1487222
     cli_bytecode_done(&bcs);
3411775b
 }
 
 START_TEST (test_retmagic)
 {
2487a4a3
     cl_init(CL_INIT_DEFAULT);
     runtest("input/retmagic.cbc", 0x1234f00d, CL_SUCCESS, 0);
     runtest("input/retmagic.cbc", 0x1234f00d, CL_SUCCESS, 1);
3411775b
 }
 END_TEST
 
 START_TEST (test_arith)
 {
2487a4a3
     cl_init(CL_INIT_DEFAULT);
     runtest("input/arith.cbc", 0xd5555555, CL_SUCCESS, 0);
     runtest("input/arith.cbc", 0xd5555555, CL_SUCCESS, 1);
3411775b
 }
 END_TEST
cf0cd429
 
 START_TEST (test_apicalls)
 {
2487a4a3
     cl_init(CL_INIT_DEFAULT);
61661606
     runtest("input/apicalls.cbc", 0xf00d, CL_SUCCESS, 0);
2487a4a3
     runtest("input/apicalls.cbc", 0xf00d, CL_SUCCESS, 1);
cf0cd429
 }
 END_TEST
 
e6d1fe78
 START_TEST (test_apicalls2)
 {
     cl_init(CL_INIT_DEFAULT);
ed4a336e
     if (have_clamjit)/*FIXME: should work with both */
e6d1fe78
     runtest("input/apicalls2.cbc", 0xf00d, CL_SUCCESS, 0);
 //    runtest("input/apicalls2.cbc", 0xf00d, CL_SUCCESS, 1);
 }
 END_TEST
 
6b67ec6e
 START_TEST (test_div0)
 {
2487a4a3
     cl_init(CL_INIT_DEFAULT);
6b67ec6e
     /* must not crash on div#0 but catch it */
2487a4a3
     runtest("input/div0.cbc", 0, CL_EBYTECODE, 0);
     runtest("input/div0.cbc", 0, CL_EBYTECODE, 1);
6b67ec6e
 }
 END_TEST
cf0cd429
 
52dd3a6b
 START_TEST (test_lsig)
 {
     cl_init(CL_INIT_DEFAULT);
ed4a336e
     if (have_clamjit)/* FIXME: should work with both */
646395bb
     runtest("input/lsig.cbc", 0, 0, 0);
ed4a336e
   //runtest("input/lsig.cbc", 0, CL_EBYTECODE, 1);
52dd3a6b
 }
 END_TEST
 
3411775b
 Suite *test_bytecode_suite(void)
 {
     Suite *s = suite_create("bytecode");
     TCase *tc_cli_arith = tcase_create("arithmetic");
     suite_add_tcase(s, tc_cli_arith);
 
41423d38
     tcase_add_test(tc_cli_arith, test_retmagic);
3411775b
     tcase_add_test(tc_cli_arith, test_arith);
cf0cd429
     tcase_add_test(tc_cli_arith, test_apicalls);
e6d1fe78
     tcase_add_test(tc_cli_arith, test_apicalls2);
41423d38
     tcase_add_test(tc_cli_arith, test_div0);
646395bb
     tcase_add_test(tc_cli_arith, test_lsig);
3411775b
     return s;
 }