2008-03-13 10:44:34 +00:00
# if HAVE_CONFIG_H
# include "clamav-config.h"
# endif
# include <stdio.h>
# include <stdlib.h>
# include <limits.h>
2008-07-25 16:03:04 +00:00
# include <fcntl.h>
2008-03-13 10:44:34 +00:00
# include <string.h>
# include <check.h>
2011-06-15 12:21:50 +03:00
# include <sys/types.h>
# include <dirent.h>
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
# ifdef HAVE_SYS_MMAN_H
2011-06-14 22:35:03 +03:00
# include <sys/mman.h>
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
# endif
2014-02-08 00:31:12 -05:00
2014-06-30 16:35:48 -04:00
# include <libxml/parser.h>
Add CMake build tooling
This patch adds experimental-quality CMake build tooling.
The libmspack build required a modification to use "" instead of <> for
header #includes. This will hopefully be included in the libmspack
upstream project when adding CMake build tooling to libmspack.
Removed use of libltdl when using CMake.
Flex & Bison are now required to build.
If -DMAINTAINER_MODE, then GPERF is also required, though it currently
doesn't actually do anything. TODO!
I found that the autotools build system was generating the lexer output
but not actually compiling it, instead using previously generated (and
manually renamed) lexer c source. As a consequence, changes to the .l
and .y files weren't making it into the build. To resolve this, I
removed generated flex/bison files and fixed the tooling to use the
freshly generated files. Flex and bison are now required build tools.
On Windows, this adds a dependency on the winflexbison package,
which can be obtained using Chocolatey or may be manually installed.
CMake tooling only has partial support for building with external LLVM
library, and no support for the internal LLVM (to be removed in the
future). I.e. The CMake build currently only supports the bytecode
interpreter.
Many files used include paths relative to the top source directory or
relative to the current project, rather than relative to each build
target. Modern CMake support requires including internal dependency
headers the same way you would external dependency headers (albeit
with "" instead of <>). This meant correcting all header includes to
be relative to the build targets and not relative to the workspace.
For example, ...
```c
include "../libclamav/clamav.h"
include "clamd/clamd_others.h"
```
... becomes:
```c
// libclamav
include "clamav.h"
// clamd
include "clamd_others.h"
```
Fixes header name conflicts by renaming a few of the files.
Converted the "shared" code into a static library, which depends on
libclamav. The ironically named "shared" static library provides
features common to the ClamAV apps which are not required in
libclamav itself and are not intended for use by downstream projects.
This change was required for correct modern CMake practices but was
also required to use the automake "subdir-objects" option.
This eliminates warnings when running autoreconf which, in the next
version of autoconf & automake are likely to break the build.
libclamav used to build in multiple stages where an earlier stage is
a static library containing utils required by the "shared" code.
Linking clamdscan and clamdtop with this libclamav utils static lib
allowed these two apps to function without libclamav. While this is
nice in theory, the practical gains are minimal and it complicates
the build system. As such, the autotools and CMake tooling was
simplified for improved maintainability and this feature was thrown
out. clamdtop and clamdscan now require libclamav to function.
Removed the nopthreads version of the autotools
libclamav_internal_utils static library and added pthread linking to
a couple apps that may have issues building on some platforms without
it, with the intention of removing needless complexity from the
source. Kept the regular version of libclamav_internal_utils.la
though it is no longer used anywhere but in libclamav.
Added an experimental doxygen build option which attempts to build
clamav.h and libfreshclam doxygen html docs.
The CMake build tooling also may build the example program(s), which
isn't a feature in the Autotools build system.
Changed C standard to C90+ due to inline linking issues with socket.h
when linking libfreshclam.so on Linux.
Generate common.rc for win32.
Fix tabs/spaces in shared Makefile.am, and remove vestigial ifndef
from misc.c.
Add CMake files to the automake dist, so users can try the new
CMake tooling w/out having to build from a git clone.
clamonacc changes:
- Renamed FANOTIFY macro to HAVE_SYS_FANOTIFY_H to better match other
similar macros.
- Added a new clamav-clamonacc.service systemd unit file, based on
the work of ChadDevOps & Aaron Brighton.
- Added missing clamonacc man page.
Updates to clamdscan man page, add missing options.
Remove vestigial CL_NOLIBCLAMAV definitions (all apps now use
libclamav).
Rename Windows mspack.dll to libmspack.dll so all ClamAV-built
libraries have the lib-prefix with Visual Studio as with CMake.
2020-08-13 00:25:34 -07:00
# include "platform.h"
// libclamav
# include "clamav.h"
# include "others.h"
# include "matcher.h"
# include "version.h"
# include "dsig.h"
2020-08-24 15:07:09 -07:00
# include "fpu.h"
Add CMake build tooling
This patch adds experimental-quality CMake build tooling.
The libmspack build required a modification to use "" instead of <> for
header #includes. This will hopefully be included in the libmspack
upstream project when adding CMake build tooling to libmspack.
Removed use of libltdl when using CMake.
Flex & Bison are now required to build.
If -DMAINTAINER_MODE, then GPERF is also required, though it currently
doesn't actually do anything. TODO!
I found that the autotools build system was generating the lexer output
but not actually compiling it, instead using previously generated (and
manually renamed) lexer c source. As a consequence, changes to the .l
and .y files weren't making it into the build. To resolve this, I
removed generated flex/bison files and fixed the tooling to use the
freshly generated files. Flex and bison are now required build tools.
On Windows, this adds a dependency on the winflexbison package,
which can be obtained using Chocolatey or may be manually installed.
CMake tooling only has partial support for building with external LLVM
library, and no support for the internal LLVM (to be removed in the
future). I.e. The CMake build currently only supports the bytecode
interpreter.
Many files used include paths relative to the top source directory or
relative to the current project, rather than relative to each build
target. Modern CMake support requires including internal dependency
headers the same way you would external dependency headers (albeit
with "" instead of <>). This meant correcting all header includes to
be relative to the build targets and not relative to the workspace.
For example, ...
```c
include "../libclamav/clamav.h"
include "clamd/clamd_others.h"
```
... becomes:
```c
// libclamav
include "clamav.h"
// clamd
include "clamd_others.h"
```
Fixes header name conflicts by renaming a few of the files.
Converted the "shared" code into a static library, which depends on
libclamav. The ironically named "shared" static library provides
features common to the ClamAV apps which are not required in
libclamav itself and are not intended for use by downstream projects.
This change was required for correct modern CMake practices but was
also required to use the automake "subdir-objects" option.
This eliminates warnings when running autoreconf which, in the next
version of autoconf & automake are likely to break the build.
libclamav used to build in multiple stages where an earlier stage is
a static library containing utils required by the "shared" code.
Linking clamdscan and clamdtop with this libclamav utils static lib
allowed these two apps to function without libclamav. While this is
nice in theory, the practical gains are minimal and it complicates
the build system. As such, the autotools and CMake tooling was
simplified for improved maintainability and this feature was thrown
out. clamdtop and clamdscan now require libclamav to function.
Removed the nopthreads version of the autotools
libclamav_internal_utils static library and added pthread linking to
a couple apps that may have issues building on some platforms without
it, with the intention of removing needless complexity from the
source. Kept the regular version of libclamav_internal_utils.la
though it is no longer used anywhere but in libclamav.
Added an experimental doxygen build option which attempts to build
clamav.h and libfreshclam doxygen html docs.
The CMake build tooling also may build the example program(s), which
isn't a feature in the Autotools build system.
Changed C standard to C90+ due to inline linking issues with socket.h
when linking libfreshclam.so on Linux.
Generate common.rc for win32.
Fix tabs/spaces in shared Makefile.am, and remove vestigial ifndef
from misc.c.
Add CMake files to the automake dist, so users can try the new
CMake tooling w/out having to build from a git clone.
clamonacc changes:
- Renamed FANOTIFY macro to HAVE_SYS_FANOTIFY_H to better match other
similar macros.
- Added a new clamav-clamonacc.service systemd unit file, based on
the work of ChadDevOps & Aaron Brighton.
- Added missing clamonacc man page.
Updates to clamdscan man page, add missing options.
Remove vestigial CL_NOLIBCLAMAV definitions (all apps now use
libclamav).
Rename Windows mspack.dll to libmspack.dll so all ClamAV-built
libraries have the lib-prefix with Visual Studio as with CMake.
2020-08-13 00:25:34 -07:00
# include "entconv.h"
2008-07-10 13:29:32 +00:00
# include "checks.h"
2008-03-13 10:44:34 +00:00
2018-12-03 12:40:13 -05:00
static int fpu_words = FPU_ENDIAN_INITME ;
2013-10-31 15:41:38 -04:00
# 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)
2022-08-30 15:51:13 -07:00
// Define SRCDIR and OBJDIR when not defined, for the sake of the IDE.
# ifndef SRCDIR
# define SRCDIR " should be defined by CMake "
# endif
# ifndef OBJDIR
# define OBJDIR " should be defined by CMake "
# endif
static char * tmpdir ;
static void cl_setup ( void )
{
tmpdir = cli_gentemp ( NULL ) ;
mkdir ( tmpdir , 0700 ) ;
ck_assert_msg ( ! ! tmpdir , " cli_gentemp failed " ) ;
}
static void cl_teardown ( void )
{
/* can't call fail() functions in teardown, it can cause SEGV */
cli_rmdirs ( tmpdir ) ;
free ( tmpdir ) ;
tmpdir = NULL ;
}
2008-03-13 10:44:34 +00:00
/* extern void cl_free(struct cl_engine *engine); */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_free )
2020-01-15 08:14:23 -08:00
{
// struct cl_engine *engine = NULL;
// cl_free(NULL);
}
2008-03-13 10:44:34 +00:00
END_TEST
/* extern int cl_build(struct cl_engine *engine); */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_build )
2020-01-15 08:14:23 -08:00
{
// struct cl_engine *engine;
// ck_assert_msg(CL_ENULLARG == cl_build(NULL), "cl_build null pointer");
// engine = calloc(sizeof(struct cl_engine),1);
// ck_assert_msg(engine, "cl_build calloc");
// ck_assert_msg(CL_ENULLARG == cl_build(engine), "cl_build(engine) with null ->root");
2022-05-08 14:59:09 -07:00
// engine->root = calloc(CL_TARGET_TABLE_SIZE, sizeof(struct cli_matcher *));
2020-01-15 08:14:23 -08:00
}
2008-03-13 10:44:34 +00:00
END_TEST
/* extern void cl_debug(void); */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_debug )
2008-08-21 20:21:43 +00:00
{
2021-08-11 18:51:42 -07:00
int old_status = cli_set_debug_flag ( 0 ) ;
2008-03-13 10:44:34 +00:00
cl_debug ( ) ;
2021-08-11 18:51:42 -07:00
ck_assert_msg ( 1 = = cli_get_debug_flag ( ) , " cl_debug failed to set cli_debug_flag " ) ;
( void ) cli_set_debug_flag ( 1 ) ;
2008-03-13 10:44:34 +00:00
cl_debug ( ) ;
2021-08-11 18:51:42 -07:00
ck_assert_msg ( 1 = = cli_get_debug_flag ( ) , " cl_debug failed when flag was already set " ) ;
( void ) cli_set_debug_flag ( old_status ) ;
2008-08-21 20:21:43 +00:00
}
2008-03-13 10:44:34 +00:00
END_TEST
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
# ifndef _WIN32
2008-03-13 10:44:34 +00:00
/* extern const char *cl_retdbdir(void); */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_retdbdir )
2020-01-15 08:14:23 -08:00
{
ck_assert_msg ( ! strcmp ( DATADIR , cl_retdbdir ( ) ) , " cl_retdbdir " ) ;
}
2008-03-13 10:44:34 +00:00
END_TEST
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
# endif
2008-03-13 10:44:34 +00:00
2008-08-04 10:38:24 +00:00
# ifndef REPO_VERSION
# define REPO_VERSION VERSION
# endif
2008-03-13 10:44:34 +00:00
/* extern const char *cl_retver(void); */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_retver )
2008-08-21 20:21:43 +00:00
{
2008-08-03 21:52:11 +00:00
const char * ver = cl_retver ( ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ! strcmp ( REPO_VERSION " " VERSION_SUFFIX , ver ) , " cl_retver " ) ;
ck_assert_msg ( strcspn ( ver , " 012345789 " ) < strlen ( ver ) ,
2020-02-29 18:28:39 -05:00
" cl_retver must have a number " ) ;
2008-08-21 20:21:43 +00:00
}
2008-03-13 10:44:34 +00:00
END_TEST
/* extern void cl_cvdfree(struct cl_cvd *cvd); */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_cvdfree )
2020-01-15 08:14:23 -08:00
{
// struct cl_cvd *cvd1, *cvd2;
// cvd1 = malloc(sizeof(struct cl_cvd));
// ck_assert_msg(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);
// ck_assert_msg(cvd2, "cvd malloc");
// ck_assert_msg(cvd2->time, "cvd malloc");
// ck_assert_msg(cvd2->md5, "cvd malloc");
// ck_assert_msg(cvd2->dsig, "cvd malloc");
// ck_assert_msg(cvd2->builder, "cvd malloc");
// cl_cvdfree(cvd2);
// cl_cvdfree(NULL);
}
2008-03-13 10:44:34 +00:00
END_TEST
/* extern int cl_statfree(struct cl_stat *dbstat); */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_statfree )
2020-01-15 08:14:23 -08:00
{
// struct cl_stat *stat;
// ck_assert_msg(CL_ENULLARG == cl_statfree(NULL), "cl_statfree(NULL)");
// stat = malloc(sizeof(struct cl_stat));
// ck_assert_msg(NULL != stat, "malloc");
// ck_assert_msg(CL_SUCCESS == cl_statfree(stat), "cl_statfree(empty_struct)");
// stat = malloc(sizeof(struct cl_stat));
// ck_assert_msg(NULL != stat, "malloc");
// stat->stattab = strdup("test");
// ck_assert_msg(NULL != stat->stattab, "strdup");
// ck_assert_msg(CL_SUCCESS == cl_statfree(stat), "cl_statfree(stat with stattab)");
// stat = malloc(sizeof(struct cl_stat));
// ck_assert_msg(NULL != stat, "malloc");
// stat->stattab = NULL;
// ck_assert_msg(CL_SUCCESS == cl_statfree(stat), "cl_statfree(stat with stattab) set to NULL");
}
2008-03-13 10:44:34 +00:00
END_TEST
/* extern unsigned int cl_retflevel(void); */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_retflevel )
2020-02-29 18:28:39 -05:00
{
}
2018-12-03 12:40:13 -05:00
END_TEST
2008-03-13 10:44:34 +00:00
/* extern struct cl_cvd *cl_cvdhead(const char *file); */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_cvdhead )
2020-01-15 08:14:23 -08:00
{
// ck_assert_msg(NULL == cl_cvdhead(NULL), "cl_cvdhead(null)");
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
// ck_assert_msg(NULL == cl_cvdhead("input" PATHSEP "cl_cvdhead" PATHSEP "1.txt"), "cl_cvdhead(515 byte file, all nulls)");
2020-01-15 08:14:23 -08:00
/* the data read from the file is passed to cl_cvdparse, test cases for that are separate */
}
2008-03-13 10:44:34 +00:00
END_TEST
/* extern struct cl_cvd *cl_cvdparse(const char *head); */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_cvdparse )
2020-02-29 18:28:39 -05:00
{
}
2008-03-13 10:44:34 +00:00
END_TEST
2011-06-15 12:21:50 +03:00
static int get_test_file ( int i , char * file , unsigned fsize , unsigned long * size ) ;
static struct cl_engine * g_engine ;
2022-08-27 10:46:21 -07:00
/* cl_error_t cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, struct cl_scan_options* options) */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_scandesc )
2011-06-15 12:21:50 +03:00
{
const char * virname = NULL ;
char file [ 256 ] ;
unsigned long size ;
unsigned long int scanned = 0 ;
2022-08-27 10:46:21 -07:00
cl_error_t ret ;
2018-07-20 22:28:48 -04:00
struct cl_scan_options options ;
memset ( & options , 0 , sizeof ( struct cl_scan_options ) ) ;
options . parse | = ~ 0 ;
2011-06-15 12:21:50 +03:00
int fd = get_test_file ( _i , file , sizeof ( file ) , & size ) ;
cli_dbgmsg ( " scanning (scandesc) %s \n " , file ) ;
2018-07-30 20:19:28 -04:00
ret = cl_scandesc ( fd , file , & virname , & scanned , g_engine , & options ) ;
2011-06-15 12:21:50 +03:00
cli_dbgmsg ( " scan end (scandesc) %s \n " , file ) ;
2013-10-31 15:41:38 -04:00
if ( ! FALSE_NEGATIVE ) {
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ret = = CL_VIRUS , " cl_scandesc failed for %s: %s " , file , cl_strerror ( ret ) ) ;
ck_assert_msg ( virname & & ! strcmp ( virname , " ClamAV-Test-File.UNOFFICIAL " ) , " virusname: %s " , virname ) ;
2013-10-31 15:41:38 -04:00
}
2011-06-15 12:21:50 +03:00
close ( fd ) ;
}
2008-03-13 10:44:34 +00:00
END_TEST
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_scandesc_allscan )
2012-10-18 14:12:58 -07:00
{
const char * virname = NULL ;
char file [ 256 ] ;
unsigned long size ;
unsigned long int scanned = 0 ;
int ret ;
2018-07-20 22:28:48 -04:00
struct cl_scan_options options ;
memset ( & options , 0 , sizeof ( struct cl_scan_options ) ) ;
options . parse | = ~ 0 ;
options . general | = CL_SCAN_GENERAL_ALLMATCHES ;
2012-10-18 14:12:58 -07:00
int fd = get_test_file ( _i , file , sizeof ( file ) , & size ) ;
cli_dbgmsg ( " scanning (scandesc) %s \n " , file ) ;
2018-07-30 20:19:28 -04:00
ret = cl_scandesc ( fd , file , & virname , & scanned , g_engine , & options ) ;
2013-10-31 15:41:38 -04:00
2012-10-18 14:12:58 -07:00
cli_dbgmsg ( " scan end (scandesc) %s \n " , file ) ;
2013-10-31 15:41:38 -04:00
if ( ! FALSE_NEGATIVE ) {
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ret = = CL_VIRUS , " cl_scandesc_allscan failed for %s: %s " , file , cl_strerror ( ret ) ) ;
ck_assert_msg ( virname & & ! strcmp ( virname , " ClamAV-Test-File.UNOFFICIAL " ) , " virusname: %s " , virname ) ;
2013-10-31 15:41:38 -04:00
}
2012-10-18 14:12:58 -07:00
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) */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_scanfile )
2011-06-15 12:21:50 +03:00
{
const char * virname = NULL ;
char file [ 256 ] ;
unsigned long size ;
unsigned long int scanned = 0 ;
int ret ;
2018-07-20 22:28:48 -04:00
struct cl_scan_options options ;
memset ( & options , 0 , sizeof ( struct cl_scan_options ) ) ;
options . parse | = ~ 0 ;
2011-06-15 12:21:50 +03:00
int fd = get_test_file ( _i , file , sizeof ( file ) , & size ) ;
close ( fd ) ;
cli_dbgmsg ( " scanning (scanfile) %s \n " , file ) ;
2018-07-20 22:28:48 -04:00
ret = cl_scanfile ( file , & virname , & scanned , g_engine , & options ) ;
2011-06-15 12:21:50 +03:00
cli_dbgmsg ( " scan end (scanfile) %s \n " , file ) ;
2013-10-31 15:41:38 -04:00
if ( ! FALSE_NEGATIVE ) {
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ret = = CL_VIRUS , " cl_scanfile failed for %s: %s " , file , cl_strerror ( ret ) ) ;
ck_assert_msg ( virname & & ! strcmp ( virname , " ClamAV-Test-File.UNOFFICIAL " ) , " virusname: %s " , virname ) ;
2013-10-31 15:41:38 -04:00
}
2011-06-15 12:21:50 +03:00
}
END_TEST
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_scanfile_allscan )
2012-10-18 14:12:58 -07:00
{
const char * virname = NULL ;
char file [ 256 ] ;
unsigned long size ;
unsigned long int scanned = 0 ;
int ret ;
2018-07-20 22:28:48 -04:00
struct cl_scan_options options ;
memset ( & options , 0 , sizeof ( struct cl_scan_options ) ) ;
options . parse | = ~ 0 ;
options . general | = CL_SCAN_GENERAL_ALLMATCHES ;
2012-10-18 14:12:58 -07:00
int fd = get_test_file ( _i , file , sizeof ( file ) , & size ) ;
close ( fd ) ;
cli_dbgmsg ( " scanning (scanfile_allscan) %s \n " , file ) ;
2018-07-20 22:28:48 -04:00
ret = cl_scanfile ( file , & virname , & scanned , g_engine , & options ) ;
2012-10-18 14:12:58 -07:00
cli_dbgmsg ( " scan end (scanfile_allscan) %s \n " , file ) ;
2013-10-31 15:41:38 -04:00
if ( ! FALSE_NEGATIVE ) {
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ret = = CL_VIRUS , " cl_scanfile_allscan failed for %s: %s " , file , cl_strerror ( ret ) ) ;
ck_assert_msg ( virname & & ! strcmp ( virname , " ClamAV-Test-File.UNOFFICIAL " ) , " virusname: %s " , virname ) ;
2013-10-31 15:41:38 -04:00
}
2012-10-18 14:12:58 -07:00
}
END_TEST
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_scanfile_callback )
2011-06-15 12:21:50 +03:00
{
const char * virname = NULL ;
char file [ 256 ] ;
unsigned long size ;
unsigned long int scanned = 0 ;
int ret ;
2018-07-20 22:28:48 -04:00
struct cl_scan_options options ;
memset ( & options , 0 , sizeof ( struct cl_scan_options ) ) ;
options . parse | = ~ 0 ;
2011-06-15 12:21:50 +03:00
int fd = get_test_file ( _i , file , sizeof ( file ) , & size ) ;
close ( fd ) ;
cli_dbgmsg ( " scanning (scanfile_cb) %s \n " , file ) ;
/* TODO: test callbacks */
2018-07-20 22:28:48 -04:00
ret = cl_scanfile_callback ( file , & virname , & scanned , g_engine , & options , NULL ) ;
2011-06-15 12:21:50 +03:00
cli_dbgmsg ( " scan end (scanfile_cb) %s \n " , file ) ;
2013-10-31 15:41:38 -04:00
if ( ! FALSE_NEGATIVE ) {
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ret = = CL_VIRUS , " cl_scanfile_cb failed for %s: %s " , file , cl_strerror ( ret ) ) ;
ck_assert_msg ( virname & & ! strcmp ( virname , " ClamAV-Test-File.UNOFFICIAL " ) , " virusname: %s " , virname ) ;
2013-10-31 15:41:38 -04:00
}
2011-06-15 12:21:50 +03:00
}
END_TEST
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_scanfile_callback_allscan )
2012-10-18 14:12:58 -07:00
{
const char * virname = NULL ;
char file [ 256 ] ;
unsigned long size ;
unsigned long int scanned = 0 ;
int ret ;
2018-07-20 22:28:48 -04:00
struct cl_scan_options options ;
memset ( & options , 0 , sizeof ( struct cl_scan_options ) ) ;
options . parse | = ~ 0 ;
options . general | = CL_SCAN_GENERAL_ALLMATCHES ;
2012-10-18 14:12:58 -07:00
int fd = get_test_file ( _i , file , sizeof ( file ) , & size ) ;
close ( fd ) ;
cli_dbgmsg ( " scanning (scanfile_cb_allscan) %s \n " , file ) ;
/* TODO: test callbacks */
2018-07-20 22:28:48 -04:00
ret = cl_scanfile_callback ( file , & virname , & scanned , g_engine , & options , NULL ) ;
2012-10-18 14:12:58 -07:00
cli_dbgmsg ( " scan end (scanfile_cb_allscan) %s \n " , file ) ;
2013-10-31 15:41:38 -04:00
if ( ! FALSE_NEGATIVE ) {
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ret = = CL_VIRUS , " cl_scanfile_cb_allscan failed for %s: %s " , file , cl_strerror ( ret ) ) ;
ck_assert_msg ( virname & & ! strcmp ( virname , " ClamAV-Test-File.UNOFFICIAL " ) , " virusname: %s " , virname ) ;
2013-10-31 15:41:38 -04:00
}
2012-10-18 14:12:58 -07:00
}
END_TEST
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_scandesc_callback )
2011-06-15 12:21:50 +03:00
{
const char * virname = NULL ;
char file [ 256 ] ;
unsigned long size ;
unsigned long int scanned = 0 ;
int ret ;
2018-07-20 22:28:48 -04:00
struct cl_scan_options options ;
memset ( & options , 0 , sizeof ( struct cl_scan_options ) ) ;
options . parse | = ~ 0 ;
2011-06-15 12:21:50 +03:00
int fd = get_test_file ( _i , file , sizeof ( file ) , & size ) ;
cli_dbgmsg ( " scanning (scandesc_cb) %s \n " , file ) ;
/* TODO: test callbacks */
2018-07-30 20:19:28 -04:00
ret = cl_scandesc_callback ( fd , file , & virname , & scanned , g_engine , & options , NULL ) ;
2011-06-15 12:21:50 +03:00
cli_dbgmsg ( " scan end (scandesc_cb) %s \n " , file ) ;
2013-10-31 15:41:38 -04:00
if ( ! FALSE_NEGATIVE ) {
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ret = = CL_VIRUS , " cl_scanfile failed for %s: %s " , file , cl_strerror ( ret ) ) ;
ck_assert_msg ( virname & & ! strcmp ( virname , " ClamAV-Test-File.UNOFFICIAL " ) , " virusname: %s " , virname ) ;
2013-10-31 15:41:38 -04:00
}
2011-06-15 12:21:50 +03:00
close ( fd ) ;
}
2008-03-13 10:44:34 +00:00
END_TEST
2012-10-18 14:12:58 -07:00
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_scandesc_callback_allscan )
2012-10-18 14:12:58 -07:00
{
const char * virname = NULL ;
char file [ 256 ] ;
unsigned long size ;
unsigned long int scanned = 0 ;
int ret ;
2018-07-20 22:28:48 -04:00
struct cl_scan_options options ;
memset ( & options , 0 , sizeof ( struct cl_scan_options ) ) ;
options . parse | = ~ 0 ;
options . general | = CL_SCAN_GENERAL_ALLMATCHES ;
2012-10-18 14:12:58 -07:00
int fd = get_test_file ( _i , file , sizeof ( file ) , & size ) ;
cli_dbgmsg ( " scanning (scandesc_cb_allscan) %s \n " , file ) ;
/* TODO: test callbacks */
2018-07-30 20:19:28 -04:00
ret = cl_scandesc_callback ( fd , file , & virname , & scanned , g_engine , & options , NULL ) ;
2012-10-18 14:12:58 -07:00
cli_dbgmsg ( " scan end (scandesc_cb_allscan) %s \n " , file ) ;
2013-10-31 15:41:38 -04:00
if ( ! FALSE_NEGATIVE ) {
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ret = = CL_VIRUS , " cl_scanfile_allscan failed for %s: %s " , file , cl_strerror ( ret ) ) ;
ck_assert_msg ( virname & & ! strcmp ( virname , " ClamAV-Test-File.UNOFFICIAL " ) , " virusname: %s " , virname ) ;
2013-10-31 15:41:38 -04:00
}
2012-10-18 14:12:58 -07:00
close ( fd ) ;
}
END_TEST
2022-08-30 15:51:13 -07:00
/* cl_error_t cl_load(const char *path, struct cl_engine **engine, unsigned int *signo, unsigned int options) */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_load )
2020-02-29 18:28:39 -05:00
{
2022-08-30 15:51:13 -07:00
cl_error_t ret ;
struct cl_engine * engine ;
unsigned int sigs = 0 ;
const char * testfile ;
FIPS-compliant CVD signing and verification
Add X509 certificate chain based signing with PKCS7-PEM external
signatures distributed alongside CVD's in a custom .cvd.sign format.
This new signing and verification mechanism is primarily in support
of FIPS compliance.
Fixes: https://github.com/Cisco-Talos/clamav/issues/564
Add a Rust implementation for parsing, verifying, and unpacking CVD
files.
Now installs a 'certs' directory in the app config directory
(e.g. <prefix>/etc/certs). The install location is configurable.
The CMake option to configure the CVD certs directory is:
`-D CVD_CERTS_DIRECTORY=PATH`
New options to set an alternative CVD certs directory:
- Commandline for freshclam, clamd, clamscan, and sigtool is:
`--cvdcertsdir PATH`
- Env variable for freshclam, clamd, clamscan, and sigtool is:
`CVD_CERTS_DIR`
- Config option for freshclam and clamd is:
`CVDCertsDirectory PATH`
Sigtool:
- Add sign/verify commands.
- Also verify CDIFF external digital signatures when applying CDIFFs.
- Place commonly used commands at the top of --help string.
- Fix up manpage.
Freshclam:
- Will try to download .sign files to verify CVDs and CDIFFs.
- Fix an issue where making a CLD would only include the CFG file for
daily and not if patching any other database.
libclamav.so:
- Bump version to 13:0:1 (aka 12.1.0).
- Also remove libclamav.map versioning.
Resolves: https://github.com/Cisco-Talos/clamav/issues/1304
- Add two new API's to the public clamav.h header:
```c
extern cl_error_t cl_cvdverify_ex(const char *file,
const char *certs_directory);
extern cl_error_t cl_cvdunpack_ex(const char *file,
const char *dir,
bool dont_verify,
const char *certs_directory);
```
The original `cl_cvdverify` and `cl_cvdunpack` are deprecated.
- Add `cl_engine_field` enum option `CL_ENGINE_CVDCERTSDIR`.
You may set this option with `cl_engine_set_str` and get it
with `cl_engine_get_str`, to override the compiled in default
CVD certs directory.
libfreshclam.so: Bump version to 4:0:0 (aka 4.0.0).
Add sigtool sign/verify tests and test certs.
Make it so downloadFile doesn't throw a warning if the server
doesn't have the .sign file.
Replace use of md5-based FP signatures in the unit tests with
sha256-based FP signatures because the md5 implementation used
by Python may be disabled in FIPS mode.
Fixes: https://github.com/Cisco-Talos/clamav/issues/1411
CMake: Add logic to enable the Rust openssl-sys / openssl-rs crates
to build against the same OpenSSL library as is used for the C build.
The Rust unit test application must also link directly with libcrypto
and libssl.
Fix some log messages with missing new lines.
Fix missing environment variable notes in --help messages and manpages.
Deconflict CONFDIR/DATADIR/CERTSDIR variable names that are defined in
clamav-config.h.in for libclamav from variable that had the same name
for use in clamav applications that use the optparser.
The 'clamav-test' certs for the unit tests will live for 10 years.
The 'clamav-beta.crt' public cert will only live for 120 days and will
be replaced before the stable release with a production 'clamav.crt'.
2024-11-21 14:01:09 -05:00
const char * cvdcertsdir ;
2022-08-30 15:51:13 -07:00
ret = cl_init ( CL_INIT_DEFAULT ) ;
ck_assert_msg ( ret = = CL_SUCCESS , " cl_init failed: %s " , cl_strerror ( ret ) ) ;
engine = cl_engine_new ( ) ;
ck_assert_msg ( engine ! = NULL , " cl_engine_new failed " ) ;
/* load test cvd */
testfile = SRCDIR PATHSEP " input " PATHSEP " freshclam_testfiles " PATHSEP " test-5.cvd " ;
ret = cl_load ( testfile , engine , & sigs , CL_DB_STDOPT ) ;
ck_assert_msg ( ret = = CL_SUCCESS , " cl_load failed for: %s -- %s " , testfile , cl_strerror ( ret ) ) ;
ck_assert_msg ( sigs > 0 , " No signatures loaded " ) ;
cl_engine_free ( engine ) ;
2020-02-29 18:28:39 -05:00
}
2008-03-13 10:44:34 +00:00
END_TEST
FIPS & FIPS-like limits on hash algs for cryptographic uses
ClamAV will not function when using a FIPS-enabled OpenSSL 3.x.
This is because ClamAV uses MD5 and SHA1 algorithms for a variety of
purposes including matching for malware detection, matching to prevent
false positives on known-clean files, and for verification of MD5-based
RSA digital signatures for determining CVD (signature database archive)
authenticity.
Interestingly, FIPS had been intentionally bypassed when creating hashes
based whole buffers and whole files (by descriptor or `FILE`-pointer):
https://github.com/Cisco-Talos/clamav/commit/78d4a9985a06a418dd1338c94ee5db461035d75b
Note: this bypassed FIPS the 1.x way with:
`EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);`
It was NOT disabled when using `cl_hash_init()` / `cl_update_hash()` /
`cl_finish_hash()`. That likely worked by coincidence in that the hash
was already calculated most of the time. It certainly would have made
use of those functions if the hash had not been calculated prior:
https://github.com/Cisco-Talos/clamav/blob/78d4a9985a06a418dd1338c94ee5db461035d75b/libclamav/matcher.c#L743
Regardless, bypassing FIPS entirely is not the correct solution.
The FIPS restrictions against using MD5 and SHA1 are valid, particularly
when verifying CVD digital siganatures, but also I think when using a
hash to determine if the file is known-clean (i.e. the "clean cache" and
also MD5-based and SHA1-based FP signatures).
This commit extends the work to bypass FIPS using the newer 3.x method:
`md = EVP_MD_fetch(NULL, alg, "-fips");`
It does this for the legacy `cl_hash*()` functions including
`cl_hash_init()` / `cl_update_hash()` / `cl_finish_hash()`.
It also introduces extended versions that allow the caller to choose if
they want to bypass FIPS:
- `cl_hash_data_ex()`
- `cl_hash_init_ex()`
- `cl_update_hash_ex()`
- `cl_finish_hash_ex()`
- `cl_hash_destroy_ex()`
- `cl_hash_file_fd_ex()`
See the `flags` parameter for each.
Ironically, this commit does NOT use the new functions at this time.
The rational is that ClamAV may need MD5, SHA1, and SHA-256 hashes of
the same files both for determining if the file is malware, and for
determining if the file is clean.
So instead, this commit will do a checks when:
1. Creating a new ClamAV scanning engine. If FIPS-mode enabled, it will
automatically toggle the "FIPS limits" engine option.
When loading signatures, if the engine "FIPS limits" option is enabled,
then MD5 and SHA1 FP signatures will be skipped.
2. Before verifying a CVD (e.g. also for loading, unpacking when
verification enabled).
If "FIPS limits" or FIPS-mode are enabled, then the legacy MD5-based RSA
method is disabled.
Note: This commit also refactors the interface for `cl_cvdverify_ex()`
and `cl_cvdunpack_ex()` so they take a `flags` parameters, rather than a
single `bool`. As these functions are new in this version, it does not
break the ABI.
The cache was already switched to use SHA2-256, so that's not a concern
for checking FIPS-mode / FIPS limits options.
This adds an option for `freshclam.conf` and `clamd.conf`:
FIPSCryptoHashLimits yes
And an equivalent command-line option for `clamscan` and `sigtool`:
--fips-limits
You may programmatically enable FIPS-limits for a ClamAV engine like this:
```C
cl_engine_set_num(engine, CL_ENGINE_FIPS_LIMITS, 1);
```
CLAM-2792
2025-07-01 20:41:47 -04:00
/* cl_error_t cl_cvdverify_ex(const char *file, const char *certs_directory, uint32_t dboptions) */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_cvdverify )
2020-02-29 18:28:39 -05:00
{
2022-08-30 15:51:13 -07:00
cl_error_t ret ;
const char * testfile ;
char newtestfile [ PATH_MAX ] ;
FILE * orig_fs ;
FILE * new_fs ;
char cvd_bytes [ 5000 ] ;
FIPS-compliant CVD signing and verification
Add X509 certificate chain based signing with PKCS7-PEM external
signatures distributed alongside CVD's in a custom .cvd.sign format.
This new signing and verification mechanism is primarily in support
of FIPS compliance.
Fixes: https://github.com/Cisco-Talos/clamav/issues/564
Add a Rust implementation for parsing, verifying, and unpacking CVD
files.
Now installs a 'certs' directory in the app config directory
(e.g. <prefix>/etc/certs). The install location is configurable.
The CMake option to configure the CVD certs directory is:
`-D CVD_CERTS_DIRECTORY=PATH`
New options to set an alternative CVD certs directory:
- Commandline for freshclam, clamd, clamscan, and sigtool is:
`--cvdcertsdir PATH`
- Env variable for freshclam, clamd, clamscan, and sigtool is:
`CVD_CERTS_DIR`
- Config option for freshclam and clamd is:
`CVDCertsDirectory PATH`
Sigtool:
- Add sign/verify commands.
- Also verify CDIFF external digital signatures when applying CDIFFs.
- Place commonly used commands at the top of --help string.
- Fix up manpage.
Freshclam:
- Will try to download .sign files to verify CVDs and CDIFFs.
- Fix an issue where making a CLD would only include the CFG file for
daily and not if patching any other database.
libclamav.so:
- Bump version to 13:0:1 (aka 12.1.0).
- Also remove libclamav.map versioning.
Resolves: https://github.com/Cisco-Talos/clamav/issues/1304
- Add two new API's to the public clamav.h header:
```c
extern cl_error_t cl_cvdverify_ex(const char *file,
const char *certs_directory);
extern cl_error_t cl_cvdunpack_ex(const char *file,
const char *dir,
bool dont_verify,
const char *certs_directory);
```
The original `cl_cvdverify` and `cl_cvdunpack` are deprecated.
- Add `cl_engine_field` enum option `CL_ENGINE_CVDCERTSDIR`.
You may set this option with `cl_engine_set_str` and get it
with `cl_engine_get_str`, to override the compiled in default
CVD certs directory.
libfreshclam.so: Bump version to 4:0:0 (aka 4.0.0).
Add sigtool sign/verify tests and test certs.
Make it so downloadFile doesn't throw a warning if the server
doesn't have the .sign file.
Replace use of md5-based FP signatures in the unit tests with
sha256-based FP signatures because the md5 implementation used
by Python may be disabled in FIPS mode.
Fixes: https://github.com/Cisco-Talos/clamav/issues/1411
CMake: Add logic to enable the Rust openssl-sys / openssl-rs crates
to build against the same OpenSSL library as is used for the C build.
The Rust unit test application must also link directly with libcrypto
and libssl.
Fix some log messages with missing new lines.
Fix missing environment variable notes in --help messages and manpages.
Deconflict CONFDIR/DATADIR/CERTSDIR variable names that are defined in
clamav-config.h.in for libclamav from variable that had the same name
for use in clamav applications that use the optparser.
The 'clamav-test' certs for the unit tests will live for 10 years.
The 'clamav-beta.crt' public cert will only live for 120 days and will
be replaced before the stable release with a production 'clamav.crt'.
2024-11-21 14:01:09 -05:00
const char * cvdcertsdir ;
cvdcertsdir = getenv ( " CVD_CERTS_DIR " ) ;
ck_assert_msg ( cvdcertsdir ! = NULL , " CVD_CERTS_DIR not set " ) ;
2022-08-30 15:51:13 -07:00
// Should be able to verify this cvd
testfile = SRCDIR " /input/freshclam_testfiles/test-1.cvd " ;
FIPS & FIPS-like limits on hash algs for cryptographic uses
ClamAV will not function when using a FIPS-enabled OpenSSL 3.x.
This is because ClamAV uses MD5 and SHA1 algorithms for a variety of
purposes including matching for malware detection, matching to prevent
false positives on known-clean files, and for verification of MD5-based
RSA digital signatures for determining CVD (signature database archive)
authenticity.
Interestingly, FIPS had been intentionally bypassed when creating hashes
based whole buffers and whole files (by descriptor or `FILE`-pointer):
https://github.com/Cisco-Talos/clamav/commit/78d4a9985a06a418dd1338c94ee5db461035d75b
Note: this bypassed FIPS the 1.x way with:
`EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);`
It was NOT disabled when using `cl_hash_init()` / `cl_update_hash()` /
`cl_finish_hash()`. That likely worked by coincidence in that the hash
was already calculated most of the time. It certainly would have made
use of those functions if the hash had not been calculated prior:
https://github.com/Cisco-Talos/clamav/blob/78d4a9985a06a418dd1338c94ee5db461035d75b/libclamav/matcher.c#L743
Regardless, bypassing FIPS entirely is not the correct solution.
The FIPS restrictions against using MD5 and SHA1 are valid, particularly
when verifying CVD digital siganatures, but also I think when using a
hash to determine if the file is known-clean (i.e. the "clean cache" and
also MD5-based and SHA1-based FP signatures).
This commit extends the work to bypass FIPS using the newer 3.x method:
`md = EVP_MD_fetch(NULL, alg, "-fips");`
It does this for the legacy `cl_hash*()` functions including
`cl_hash_init()` / `cl_update_hash()` / `cl_finish_hash()`.
It also introduces extended versions that allow the caller to choose if
they want to bypass FIPS:
- `cl_hash_data_ex()`
- `cl_hash_init_ex()`
- `cl_update_hash_ex()`
- `cl_finish_hash_ex()`
- `cl_hash_destroy_ex()`
- `cl_hash_file_fd_ex()`
See the `flags` parameter for each.
Ironically, this commit does NOT use the new functions at this time.
The rational is that ClamAV may need MD5, SHA1, and SHA-256 hashes of
the same files both for determining if the file is malware, and for
determining if the file is clean.
So instead, this commit will do a checks when:
1. Creating a new ClamAV scanning engine. If FIPS-mode enabled, it will
automatically toggle the "FIPS limits" engine option.
When loading signatures, if the engine "FIPS limits" option is enabled,
then MD5 and SHA1 FP signatures will be skipped.
2. Before verifying a CVD (e.g. also for loading, unpacking when
verification enabled).
If "FIPS limits" or FIPS-mode are enabled, then the legacy MD5-based RSA
method is disabled.
Note: This commit also refactors the interface for `cl_cvdverify_ex()`
and `cl_cvdunpack_ex()` so they take a `flags` parameters, rather than a
single `bool`. As these functions are new in this version, it does not
break the ABI.
The cache was already switched to use SHA2-256, so that's not a concern
for checking FIPS-mode / FIPS limits options.
This adds an option for `freshclam.conf` and `clamd.conf`:
FIPSCryptoHashLimits yes
And an equivalent command-line option for `clamscan` and `sigtool`:
--fips-limits
You may programmatically enable FIPS-limits for a ClamAV engine like this:
```C
cl_engine_set_num(engine, CL_ENGINE_FIPS_LIMITS, 1);
```
CLAM-2792
2025-07-01 20:41:47 -04:00
ret = cl_cvdverify_ex ( testfile , cvdcertsdir , 0 ) ;
FIPS-compliant CVD signing and verification
Add X509 certificate chain based signing with PKCS7-PEM external
signatures distributed alongside CVD's in a custom .cvd.sign format.
This new signing and verification mechanism is primarily in support
of FIPS compliance.
Fixes: https://github.com/Cisco-Talos/clamav/issues/564
Add a Rust implementation for parsing, verifying, and unpacking CVD
files.
Now installs a 'certs' directory in the app config directory
(e.g. <prefix>/etc/certs). The install location is configurable.
The CMake option to configure the CVD certs directory is:
`-D CVD_CERTS_DIRECTORY=PATH`
New options to set an alternative CVD certs directory:
- Commandline for freshclam, clamd, clamscan, and sigtool is:
`--cvdcertsdir PATH`
- Env variable for freshclam, clamd, clamscan, and sigtool is:
`CVD_CERTS_DIR`
- Config option for freshclam and clamd is:
`CVDCertsDirectory PATH`
Sigtool:
- Add sign/verify commands.
- Also verify CDIFF external digital signatures when applying CDIFFs.
- Place commonly used commands at the top of --help string.
- Fix up manpage.
Freshclam:
- Will try to download .sign files to verify CVDs and CDIFFs.
- Fix an issue where making a CLD would only include the CFG file for
daily and not if patching any other database.
libclamav.so:
- Bump version to 13:0:1 (aka 12.1.0).
- Also remove libclamav.map versioning.
Resolves: https://github.com/Cisco-Talos/clamav/issues/1304
- Add two new API's to the public clamav.h header:
```c
extern cl_error_t cl_cvdverify_ex(const char *file,
const char *certs_directory);
extern cl_error_t cl_cvdunpack_ex(const char *file,
const char *dir,
bool dont_verify,
const char *certs_directory);
```
The original `cl_cvdverify` and `cl_cvdunpack` are deprecated.
- Add `cl_engine_field` enum option `CL_ENGINE_CVDCERTSDIR`.
You may set this option with `cl_engine_set_str` and get it
with `cl_engine_get_str`, to override the compiled in default
CVD certs directory.
libfreshclam.so: Bump version to 4:0:0 (aka 4.0.0).
Add sigtool sign/verify tests and test certs.
Make it so downloadFile doesn't throw a warning if the server
doesn't have the .sign file.
Replace use of md5-based FP signatures in the unit tests with
sha256-based FP signatures because the md5 implementation used
by Python may be disabled in FIPS mode.
Fixes: https://github.com/Cisco-Talos/clamav/issues/1411
CMake: Add logic to enable the Rust openssl-sys / openssl-rs crates
to build against the same OpenSSL library as is used for the C build.
The Rust unit test application must also link directly with libcrypto
and libssl.
Fix some log messages with missing new lines.
Fix missing environment variable notes in --help messages and manpages.
Deconflict CONFDIR/DATADIR/CERTSDIR variable names that are defined in
clamav-config.h.in for libclamav from variable that had the same name
for use in clamav applications that use the optparser.
The 'clamav-test' certs for the unit tests will live for 10 years.
The 'clamav-beta.crt' public cert will only live for 120 days and will
be replaced before the stable release with a production 'clamav.crt'.
2024-11-21 14:01:09 -05:00
ck_assert_msg ( CL_SUCCESS = = ret , " cl_cvdverify_ex failed for: %s -- %s " , testfile , cl_strerror ( ret ) ) ;
2022-08-30 15:51:13 -07:00
// Can't verify a cvd that doesn't exist
testfile = SRCDIR " /input/freshclam_testfiles/test-na.cvd " ;
FIPS & FIPS-like limits on hash algs for cryptographic uses
ClamAV will not function when using a FIPS-enabled OpenSSL 3.x.
This is because ClamAV uses MD5 and SHA1 algorithms for a variety of
purposes including matching for malware detection, matching to prevent
false positives on known-clean files, and for verification of MD5-based
RSA digital signatures for determining CVD (signature database archive)
authenticity.
Interestingly, FIPS had been intentionally bypassed when creating hashes
based whole buffers and whole files (by descriptor or `FILE`-pointer):
https://github.com/Cisco-Talos/clamav/commit/78d4a9985a06a418dd1338c94ee5db461035d75b
Note: this bypassed FIPS the 1.x way with:
`EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);`
It was NOT disabled when using `cl_hash_init()` / `cl_update_hash()` /
`cl_finish_hash()`. That likely worked by coincidence in that the hash
was already calculated most of the time. It certainly would have made
use of those functions if the hash had not been calculated prior:
https://github.com/Cisco-Talos/clamav/blob/78d4a9985a06a418dd1338c94ee5db461035d75b/libclamav/matcher.c#L743
Regardless, bypassing FIPS entirely is not the correct solution.
The FIPS restrictions against using MD5 and SHA1 are valid, particularly
when verifying CVD digital siganatures, but also I think when using a
hash to determine if the file is known-clean (i.e. the "clean cache" and
also MD5-based and SHA1-based FP signatures).
This commit extends the work to bypass FIPS using the newer 3.x method:
`md = EVP_MD_fetch(NULL, alg, "-fips");`
It does this for the legacy `cl_hash*()` functions including
`cl_hash_init()` / `cl_update_hash()` / `cl_finish_hash()`.
It also introduces extended versions that allow the caller to choose if
they want to bypass FIPS:
- `cl_hash_data_ex()`
- `cl_hash_init_ex()`
- `cl_update_hash_ex()`
- `cl_finish_hash_ex()`
- `cl_hash_destroy_ex()`
- `cl_hash_file_fd_ex()`
See the `flags` parameter for each.
Ironically, this commit does NOT use the new functions at this time.
The rational is that ClamAV may need MD5, SHA1, and SHA-256 hashes of
the same files both for determining if the file is malware, and for
determining if the file is clean.
So instead, this commit will do a checks when:
1. Creating a new ClamAV scanning engine. If FIPS-mode enabled, it will
automatically toggle the "FIPS limits" engine option.
When loading signatures, if the engine "FIPS limits" option is enabled,
then MD5 and SHA1 FP signatures will be skipped.
2. Before verifying a CVD (e.g. also for loading, unpacking when
verification enabled).
If "FIPS limits" or FIPS-mode are enabled, then the legacy MD5-based RSA
method is disabled.
Note: This commit also refactors the interface for `cl_cvdverify_ex()`
and `cl_cvdunpack_ex()` so they take a `flags` parameters, rather than a
single `bool`. As these functions are new in this version, it does not
break the ABI.
The cache was already switched to use SHA2-256, so that's not a concern
for checking FIPS-mode / FIPS limits options.
This adds an option for `freshclam.conf` and `clamd.conf`:
FIPSCryptoHashLimits yes
And an equivalent command-line option for `clamscan` and `sigtool`:
--fips-limits
You may programmatically enable FIPS-limits for a ClamAV engine like this:
```C
cl_engine_set_num(engine, CL_ENGINE_FIPS_LIMITS, 1);
```
CLAM-2792
2025-07-01 20:41:47 -04:00
ret = cl_cvdverify_ex ( testfile , cvdcertsdir , 0 ) ;
FIPS-compliant CVD signing and verification
Add X509 certificate chain based signing with PKCS7-PEM external
signatures distributed alongside CVD's in a custom .cvd.sign format.
This new signing and verification mechanism is primarily in support
of FIPS compliance.
Fixes: https://github.com/Cisco-Talos/clamav/issues/564
Add a Rust implementation for parsing, verifying, and unpacking CVD
files.
Now installs a 'certs' directory in the app config directory
(e.g. <prefix>/etc/certs). The install location is configurable.
The CMake option to configure the CVD certs directory is:
`-D CVD_CERTS_DIRECTORY=PATH`
New options to set an alternative CVD certs directory:
- Commandline for freshclam, clamd, clamscan, and sigtool is:
`--cvdcertsdir PATH`
- Env variable for freshclam, clamd, clamscan, and sigtool is:
`CVD_CERTS_DIR`
- Config option for freshclam and clamd is:
`CVDCertsDirectory PATH`
Sigtool:
- Add sign/verify commands.
- Also verify CDIFF external digital signatures when applying CDIFFs.
- Place commonly used commands at the top of --help string.
- Fix up manpage.
Freshclam:
- Will try to download .sign files to verify CVDs and CDIFFs.
- Fix an issue where making a CLD would only include the CFG file for
daily and not if patching any other database.
libclamav.so:
- Bump version to 13:0:1 (aka 12.1.0).
- Also remove libclamav.map versioning.
Resolves: https://github.com/Cisco-Talos/clamav/issues/1304
- Add two new API's to the public clamav.h header:
```c
extern cl_error_t cl_cvdverify_ex(const char *file,
const char *certs_directory);
extern cl_error_t cl_cvdunpack_ex(const char *file,
const char *dir,
bool dont_verify,
const char *certs_directory);
```
The original `cl_cvdverify` and `cl_cvdunpack` are deprecated.
- Add `cl_engine_field` enum option `CL_ENGINE_CVDCERTSDIR`.
You may set this option with `cl_engine_set_str` and get it
with `cl_engine_get_str`, to override the compiled in default
CVD certs directory.
libfreshclam.so: Bump version to 4:0:0 (aka 4.0.0).
Add sigtool sign/verify tests and test certs.
Make it so downloadFile doesn't throw a warning if the server
doesn't have the .sign file.
Replace use of md5-based FP signatures in the unit tests with
sha256-based FP signatures because the md5 implementation used
by Python may be disabled in FIPS mode.
Fixes: https://github.com/Cisco-Talos/clamav/issues/1411
CMake: Add logic to enable the Rust openssl-sys / openssl-rs crates
to build against the same OpenSSL library as is used for the C build.
The Rust unit test application must also link directly with libcrypto
and libssl.
Fix some log messages with missing new lines.
Fix missing environment variable notes in --help messages and manpages.
Deconflict CONFDIR/DATADIR/CERTSDIR variable names that are defined in
clamav-config.h.in for libclamav from variable that had the same name
for use in clamav applications that use the optparser.
The 'clamav-test' certs for the unit tests will live for 10 years.
The 'clamav-beta.crt' public cert will only live for 120 days and will
be replaced before the stable release with a production 'clamav.crt'.
2024-11-21 14:01:09 -05:00
ck_assert_msg ( CL_ECVD = = ret , " cl_cvdverify_ex should have failed for: %s -- %s " , testfile , cl_strerror ( ret ) ) ;
2022-08-30 15:51:13 -07:00
FIPS-compliant CVD signing and verification
Add X509 certificate chain based signing with PKCS7-PEM external
signatures distributed alongside CVD's in a custom .cvd.sign format.
This new signing and verification mechanism is primarily in support
of FIPS compliance.
Fixes: https://github.com/Cisco-Talos/clamav/issues/564
Add a Rust implementation for parsing, verifying, and unpacking CVD
files.
Now installs a 'certs' directory in the app config directory
(e.g. <prefix>/etc/certs). The install location is configurable.
The CMake option to configure the CVD certs directory is:
`-D CVD_CERTS_DIRECTORY=PATH`
New options to set an alternative CVD certs directory:
- Commandline for freshclam, clamd, clamscan, and sigtool is:
`--cvdcertsdir PATH`
- Env variable for freshclam, clamd, clamscan, and sigtool is:
`CVD_CERTS_DIR`
- Config option for freshclam and clamd is:
`CVDCertsDirectory PATH`
Sigtool:
- Add sign/verify commands.
- Also verify CDIFF external digital signatures when applying CDIFFs.
- Place commonly used commands at the top of --help string.
- Fix up manpage.
Freshclam:
- Will try to download .sign files to verify CVDs and CDIFFs.
- Fix an issue where making a CLD would only include the CFG file for
daily and not if patching any other database.
libclamav.so:
- Bump version to 13:0:1 (aka 12.1.0).
- Also remove libclamav.map versioning.
Resolves: https://github.com/Cisco-Talos/clamav/issues/1304
- Add two new API's to the public clamav.h header:
```c
extern cl_error_t cl_cvdverify_ex(const char *file,
const char *certs_directory);
extern cl_error_t cl_cvdunpack_ex(const char *file,
const char *dir,
bool dont_verify,
const char *certs_directory);
```
The original `cl_cvdverify` and `cl_cvdunpack` are deprecated.
- Add `cl_engine_field` enum option `CL_ENGINE_CVDCERTSDIR`.
You may set this option with `cl_engine_set_str` and get it
with `cl_engine_get_str`, to override the compiled in default
CVD certs directory.
libfreshclam.so: Bump version to 4:0:0 (aka 4.0.0).
Add sigtool sign/verify tests and test certs.
Make it so downloadFile doesn't throw a warning if the server
doesn't have the .sign file.
Replace use of md5-based FP signatures in the unit tests with
sha256-based FP signatures because the md5 implementation used
by Python may be disabled in FIPS mode.
Fixes: https://github.com/Cisco-Talos/clamav/issues/1411
CMake: Add logic to enable the Rust openssl-sys / openssl-rs crates
to build against the same OpenSSL library as is used for the C build.
The Rust unit test application must also link directly with libcrypto
and libssl.
Fix some log messages with missing new lines.
Fix missing environment variable notes in --help messages and manpages.
Deconflict CONFDIR/DATADIR/CERTSDIR variable names that are defined in
clamav-config.h.in for libclamav from variable that had the same name
for use in clamav applications that use the optparser.
The 'clamav-test' certs for the unit tests will live for 10 years.
The 'clamav-beta.crt' public cert will only live for 120 days and will
be replaced before the stable release with a production 'clamav.crt'.
2024-11-21 14:01:09 -05:00
// A cdiff is not a cvd. Cannot verify with cl_cvdverify_ex!
2022-08-30 15:51:13 -07:00
testfile = SRCDIR " /input/freshclam_testfiles/test-2.cdiff " ;
FIPS & FIPS-like limits on hash algs for cryptographic uses
ClamAV will not function when using a FIPS-enabled OpenSSL 3.x.
This is because ClamAV uses MD5 and SHA1 algorithms for a variety of
purposes including matching for malware detection, matching to prevent
false positives on known-clean files, and for verification of MD5-based
RSA digital signatures for determining CVD (signature database archive)
authenticity.
Interestingly, FIPS had been intentionally bypassed when creating hashes
based whole buffers and whole files (by descriptor or `FILE`-pointer):
https://github.com/Cisco-Talos/clamav/commit/78d4a9985a06a418dd1338c94ee5db461035d75b
Note: this bypassed FIPS the 1.x way with:
`EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);`
It was NOT disabled when using `cl_hash_init()` / `cl_update_hash()` /
`cl_finish_hash()`. That likely worked by coincidence in that the hash
was already calculated most of the time. It certainly would have made
use of those functions if the hash had not been calculated prior:
https://github.com/Cisco-Talos/clamav/blob/78d4a9985a06a418dd1338c94ee5db461035d75b/libclamav/matcher.c#L743
Regardless, bypassing FIPS entirely is not the correct solution.
The FIPS restrictions against using MD5 and SHA1 are valid, particularly
when verifying CVD digital siganatures, but also I think when using a
hash to determine if the file is known-clean (i.e. the "clean cache" and
also MD5-based and SHA1-based FP signatures).
This commit extends the work to bypass FIPS using the newer 3.x method:
`md = EVP_MD_fetch(NULL, alg, "-fips");`
It does this for the legacy `cl_hash*()` functions including
`cl_hash_init()` / `cl_update_hash()` / `cl_finish_hash()`.
It also introduces extended versions that allow the caller to choose if
they want to bypass FIPS:
- `cl_hash_data_ex()`
- `cl_hash_init_ex()`
- `cl_update_hash_ex()`
- `cl_finish_hash_ex()`
- `cl_hash_destroy_ex()`
- `cl_hash_file_fd_ex()`
See the `flags` parameter for each.
Ironically, this commit does NOT use the new functions at this time.
The rational is that ClamAV may need MD5, SHA1, and SHA-256 hashes of
the same files both for determining if the file is malware, and for
determining if the file is clean.
So instead, this commit will do a checks when:
1. Creating a new ClamAV scanning engine. If FIPS-mode enabled, it will
automatically toggle the "FIPS limits" engine option.
When loading signatures, if the engine "FIPS limits" option is enabled,
then MD5 and SHA1 FP signatures will be skipped.
2. Before verifying a CVD (e.g. also for loading, unpacking when
verification enabled).
If "FIPS limits" or FIPS-mode are enabled, then the legacy MD5-based RSA
method is disabled.
Note: This commit also refactors the interface for `cl_cvdverify_ex()`
and `cl_cvdunpack_ex()` so they take a `flags` parameters, rather than a
single `bool`. As these functions are new in this version, it does not
break the ABI.
The cache was already switched to use SHA2-256, so that's not a concern
for checking FIPS-mode / FIPS limits options.
This adds an option for `freshclam.conf` and `clamd.conf`:
FIPSCryptoHashLimits yes
And an equivalent command-line option for `clamscan` and `sigtool`:
--fips-limits
You may programmatically enable FIPS-limits for a ClamAV engine like this:
```C
cl_engine_set_num(engine, CL_ENGINE_FIPS_LIMITS, 1);
```
CLAM-2792
2025-07-01 20:41:47 -04:00
ret = cl_cvdverify_ex ( testfile , cvdcertsdir , 0 ) ;
FIPS-compliant CVD signing and verification
Add X509 certificate chain based signing with PKCS7-PEM external
signatures distributed alongside CVD's in a custom .cvd.sign format.
This new signing and verification mechanism is primarily in support
of FIPS compliance.
Fixes: https://github.com/Cisco-Talos/clamav/issues/564
Add a Rust implementation for parsing, verifying, and unpacking CVD
files.
Now installs a 'certs' directory in the app config directory
(e.g. <prefix>/etc/certs). The install location is configurable.
The CMake option to configure the CVD certs directory is:
`-D CVD_CERTS_DIRECTORY=PATH`
New options to set an alternative CVD certs directory:
- Commandline for freshclam, clamd, clamscan, and sigtool is:
`--cvdcertsdir PATH`
- Env variable for freshclam, clamd, clamscan, and sigtool is:
`CVD_CERTS_DIR`
- Config option for freshclam and clamd is:
`CVDCertsDirectory PATH`
Sigtool:
- Add sign/verify commands.
- Also verify CDIFF external digital signatures when applying CDIFFs.
- Place commonly used commands at the top of --help string.
- Fix up manpage.
Freshclam:
- Will try to download .sign files to verify CVDs and CDIFFs.
- Fix an issue where making a CLD would only include the CFG file for
daily and not if patching any other database.
libclamav.so:
- Bump version to 13:0:1 (aka 12.1.0).
- Also remove libclamav.map versioning.
Resolves: https://github.com/Cisco-Talos/clamav/issues/1304
- Add two new API's to the public clamav.h header:
```c
extern cl_error_t cl_cvdverify_ex(const char *file,
const char *certs_directory);
extern cl_error_t cl_cvdunpack_ex(const char *file,
const char *dir,
bool dont_verify,
const char *certs_directory);
```
The original `cl_cvdverify` and `cl_cvdunpack` are deprecated.
- Add `cl_engine_field` enum option `CL_ENGINE_CVDCERTSDIR`.
You may set this option with `cl_engine_set_str` and get it
with `cl_engine_get_str`, to override the compiled in default
CVD certs directory.
libfreshclam.so: Bump version to 4:0:0 (aka 4.0.0).
Add sigtool sign/verify tests and test certs.
Make it so downloadFile doesn't throw a warning if the server
doesn't have the .sign file.
Replace use of md5-based FP signatures in the unit tests with
sha256-based FP signatures because the md5 implementation used
by Python may be disabled in FIPS mode.
Fixes: https://github.com/Cisco-Talos/clamav/issues/1411
CMake: Add logic to enable the Rust openssl-sys / openssl-rs crates
to build against the same OpenSSL library as is used for the C build.
The Rust unit test application must also link directly with libcrypto
and libssl.
Fix some log messages with missing new lines.
Fix missing environment variable notes in --help messages and manpages.
Deconflict CONFDIR/DATADIR/CERTSDIR variable names that are defined in
clamav-config.h.in for libclamav from variable that had the same name
for use in clamav applications that use the optparser.
The 'clamav-test' certs for the unit tests will live for 10 years.
The 'clamav-beta.crt' public cert will only live for 120 days and will
be replaced before the stable release with a production 'clamav.crt'.
2024-11-21 14:01:09 -05:00
ck_assert_msg ( CL_ECVD = = ret , " cl_cvdverify_ex should have failed for: %s -- %s " , testfile , cl_strerror ( ret ) ) ;
2022-08-30 15:51:13 -07:00
// Can't verify an hdb file
testfile = SRCDIR " /input/clamav.hdb " ;
FIPS & FIPS-like limits on hash algs for cryptographic uses
ClamAV will not function when using a FIPS-enabled OpenSSL 3.x.
This is because ClamAV uses MD5 and SHA1 algorithms for a variety of
purposes including matching for malware detection, matching to prevent
false positives on known-clean files, and for verification of MD5-based
RSA digital signatures for determining CVD (signature database archive)
authenticity.
Interestingly, FIPS had been intentionally bypassed when creating hashes
based whole buffers and whole files (by descriptor or `FILE`-pointer):
https://github.com/Cisco-Talos/clamav/commit/78d4a9985a06a418dd1338c94ee5db461035d75b
Note: this bypassed FIPS the 1.x way with:
`EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);`
It was NOT disabled when using `cl_hash_init()` / `cl_update_hash()` /
`cl_finish_hash()`. That likely worked by coincidence in that the hash
was already calculated most of the time. It certainly would have made
use of those functions if the hash had not been calculated prior:
https://github.com/Cisco-Talos/clamav/blob/78d4a9985a06a418dd1338c94ee5db461035d75b/libclamav/matcher.c#L743
Regardless, bypassing FIPS entirely is not the correct solution.
The FIPS restrictions against using MD5 and SHA1 are valid, particularly
when verifying CVD digital siganatures, but also I think when using a
hash to determine if the file is known-clean (i.e. the "clean cache" and
also MD5-based and SHA1-based FP signatures).
This commit extends the work to bypass FIPS using the newer 3.x method:
`md = EVP_MD_fetch(NULL, alg, "-fips");`
It does this for the legacy `cl_hash*()` functions including
`cl_hash_init()` / `cl_update_hash()` / `cl_finish_hash()`.
It also introduces extended versions that allow the caller to choose if
they want to bypass FIPS:
- `cl_hash_data_ex()`
- `cl_hash_init_ex()`
- `cl_update_hash_ex()`
- `cl_finish_hash_ex()`
- `cl_hash_destroy_ex()`
- `cl_hash_file_fd_ex()`
See the `flags` parameter for each.
Ironically, this commit does NOT use the new functions at this time.
The rational is that ClamAV may need MD5, SHA1, and SHA-256 hashes of
the same files both for determining if the file is malware, and for
determining if the file is clean.
So instead, this commit will do a checks when:
1. Creating a new ClamAV scanning engine. If FIPS-mode enabled, it will
automatically toggle the "FIPS limits" engine option.
When loading signatures, if the engine "FIPS limits" option is enabled,
then MD5 and SHA1 FP signatures will be skipped.
2. Before verifying a CVD (e.g. also for loading, unpacking when
verification enabled).
If "FIPS limits" or FIPS-mode are enabled, then the legacy MD5-based RSA
method is disabled.
Note: This commit also refactors the interface for `cl_cvdverify_ex()`
and `cl_cvdunpack_ex()` so they take a `flags` parameters, rather than a
single `bool`. As these functions are new in this version, it does not
break the ABI.
The cache was already switched to use SHA2-256, so that's not a concern
for checking FIPS-mode / FIPS limits options.
This adds an option for `freshclam.conf` and `clamd.conf`:
FIPSCryptoHashLimits yes
And an equivalent command-line option for `clamscan` and `sigtool`:
--fips-limits
You may programmatically enable FIPS-limits for a ClamAV engine like this:
```C
cl_engine_set_num(engine, CL_ENGINE_FIPS_LIMITS, 1);
```
CLAM-2792
2025-07-01 20:41:47 -04:00
ret = cl_cvdverify_ex ( testfile , cvdcertsdir , 0 ) ;
FIPS-compliant CVD signing and verification
Add X509 certificate chain based signing with PKCS7-PEM external
signatures distributed alongside CVD's in a custom .cvd.sign format.
This new signing and verification mechanism is primarily in support
of FIPS compliance.
Fixes: https://github.com/Cisco-Talos/clamav/issues/564
Add a Rust implementation for parsing, verifying, and unpacking CVD
files.
Now installs a 'certs' directory in the app config directory
(e.g. <prefix>/etc/certs). The install location is configurable.
The CMake option to configure the CVD certs directory is:
`-D CVD_CERTS_DIRECTORY=PATH`
New options to set an alternative CVD certs directory:
- Commandline for freshclam, clamd, clamscan, and sigtool is:
`--cvdcertsdir PATH`
- Env variable for freshclam, clamd, clamscan, and sigtool is:
`CVD_CERTS_DIR`
- Config option for freshclam and clamd is:
`CVDCertsDirectory PATH`
Sigtool:
- Add sign/verify commands.
- Also verify CDIFF external digital signatures when applying CDIFFs.
- Place commonly used commands at the top of --help string.
- Fix up manpage.
Freshclam:
- Will try to download .sign files to verify CVDs and CDIFFs.
- Fix an issue where making a CLD would only include the CFG file for
daily and not if patching any other database.
libclamav.so:
- Bump version to 13:0:1 (aka 12.1.0).
- Also remove libclamav.map versioning.
Resolves: https://github.com/Cisco-Talos/clamav/issues/1304
- Add two new API's to the public clamav.h header:
```c
extern cl_error_t cl_cvdverify_ex(const char *file,
const char *certs_directory);
extern cl_error_t cl_cvdunpack_ex(const char *file,
const char *dir,
bool dont_verify,
const char *certs_directory);
```
The original `cl_cvdverify` and `cl_cvdunpack` are deprecated.
- Add `cl_engine_field` enum option `CL_ENGINE_CVDCERTSDIR`.
You may set this option with `cl_engine_set_str` and get it
with `cl_engine_get_str`, to override the compiled in default
CVD certs directory.
libfreshclam.so: Bump version to 4:0:0 (aka 4.0.0).
Add sigtool sign/verify tests and test certs.
Make it so downloadFile doesn't throw a warning if the server
doesn't have the .sign file.
Replace use of md5-based FP signatures in the unit tests with
sha256-based FP signatures because the md5 implementation used
by Python may be disabled in FIPS mode.
Fixes: https://github.com/Cisco-Talos/clamav/issues/1411
CMake: Add logic to enable the Rust openssl-sys / openssl-rs crates
to build against the same OpenSSL library as is used for the C build.
The Rust unit test application must also link directly with libcrypto
and libssl.
Fix some log messages with missing new lines.
Fix missing environment variable notes in --help messages and manpages.
Deconflict CONFDIR/DATADIR/CERTSDIR variable names that are defined in
clamav-config.h.in for libclamav from variable that had the same name
for use in clamav applications that use the optparser.
The 'clamav-test' certs for the unit tests will live for 10 years.
The 'clamav-beta.crt' public cert will only live for 120 days and will
be replaced before the stable release with a production 'clamav.crt'.
2024-11-21 14:01:09 -05:00
ck_assert_msg ( CL_ECVD = = ret , " cl_cvdverify_ex should have failed for: %s -- %s " , testfile , cl_strerror ( ret ) ) ;
2022-08-30 15:51:13 -07:00
// Modify the cvd to make it invalid
sprintf ( newtestfile , " %s/modified.cvd " , tmpdir ) ;
orig_fs = fopen ( SRCDIR " /input/freshclam_testfiles/test-1.cvd " , " rb " ) ;
ck_assert_msg ( orig_fs ! = NULL , " Failed to open %s " , testfile ) ;
new_fs = fopen ( newtestfile , " wb " ) ;
ck_assert_msg ( new_fs ! = NULL , " Failed to open %s " , newtestfile ) ;
// Copy the first 5000 bytes
fread ( cvd_bytes , 1 , 5000 , orig_fs ) ;
fwrite ( cvd_bytes , 1 , 5000 , new_fs ) ;
fclose ( orig_fs ) ;
fclose ( new_fs ) ;
// Now verify the modified cvd
FIPS & FIPS-like limits on hash algs for cryptographic uses
ClamAV will not function when using a FIPS-enabled OpenSSL 3.x.
This is because ClamAV uses MD5 and SHA1 algorithms for a variety of
purposes including matching for malware detection, matching to prevent
false positives on known-clean files, and for verification of MD5-based
RSA digital signatures for determining CVD (signature database archive)
authenticity.
Interestingly, FIPS had been intentionally bypassed when creating hashes
based whole buffers and whole files (by descriptor or `FILE`-pointer):
https://github.com/Cisco-Talos/clamav/commit/78d4a9985a06a418dd1338c94ee5db461035d75b
Note: this bypassed FIPS the 1.x way with:
`EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);`
It was NOT disabled when using `cl_hash_init()` / `cl_update_hash()` /
`cl_finish_hash()`. That likely worked by coincidence in that the hash
was already calculated most of the time. It certainly would have made
use of those functions if the hash had not been calculated prior:
https://github.com/Cisco-Talos/clamav/blob/78d4a9985a06a418dd1338c94ee5db461035d75b/libclamav/matcher.c#L743
Regardless, bypassing FIPS entirely is not the correct solution.
The FIPS restrictions against using MD5 and SHA1 are valid, particularly
when verifying CVD digital siganatures, but also I think when using a
hash to determine if the file is known-clean (i.e. the "clean cache" and
also MD5-based and SHA1-based FP signatures).
This commit extends the work to bypass FIPS using the newer 3.x method:
`md = EVP_MD_fetch(NULL, alg, "-fips");`
It does this for the legacy `cl_hash*()` functions including
`cl_hash_init()` / `cl_update_hash()` / `cl_finish_hash()`.
It also introduces extended versions that allow the caller to choose if
they want to bypass FIPS:
- `cl_hash_data_ex()`
- `cl_hash_init_ex()`
- `cl_update_hash_ex()`
- `cl_finish_hash_ex()`
- `cl_hash_destroy_ex()`
- `cl_hash_file_fd_ex()`
See the `flags` parameter for each.
Ironically, this commit does NOT use the new functions at this time.
The rational is that ClamAV may need MD5, SHA1, and SHA-256 hashes of
the same files both for determining if the file is malware, and for
determining if the file is clean.
So instead, this commit will do a checks when:
1. Creating a new ClamAV scanning engine. If FIPS-mode enabled, it will
automatically toggle the "FIPS limits" engine option.
When loading signatures, if the engine "FIPS limits" option is enabled,
then MD5 and SHA1 FP signatures will be skipped.
2. Before verifying a CVD (e.g. also for loading, unpacking when
verification enabled).
If "FIPS limits" or FIPS-mode are enabled, then the legacy MD5-based RSA
method is disabled.
Note: This commit also refactors the interface for `cl_cvdverify_ex()`
and `cl_cvdunpack_ex()` so they take a `flags` parameters, rather than a
single `bool`. As these functions are new in this version, it does not
break the ABI.
The cache was already switched to use SHA2-256, so that's not a concern
for checking FIPS-mode / FIPS limits options.
This adds an option for `freshclam.conf` and `clamd.conf`:
FIPSCryptoHashLimits yes
And an equivalent command-line option for `clamscan` and `sigtool`:
--fips-limits
You may programmatically enable FIPS-limits for a ClamAV engine like this:
```C
cl_engine_set_num(engine, CL_ENGINE_FIPS_LIMITS, 1);
```
CLAM-2792
2025-07-01 20:41:47 -04:00
ret = cl_cvdverify_ex ( newtestfile , cvdcertsdir , 0 ) ;
ck_assert_msg ( CL_EVERIFY = = ret , " cl_cvdverify_ex should have failed for: %s -- %s " , newtestfile , cl_strerror ( ret ) ) ;
2022-08-30 15:51:13 -07:00
}
END_TEST
FIPS & FIPS-like limits on hash algs for cryptographic uses
ClamAV will not function when using a FIPS-enabled OpenSSL 3.x.
This is because ClamAV uses MD5 and SHA1 algorithms for a variety of
purposes including matching for malware detection, matching to prevent
false positives on known-clean files, and for verification of MD5-based
RSA digital signatures for determining CVD (signature database archive)
authenticity.
Interestingly, FIPS had been intentionally bypassed when creating hashes
based whole buffers and whole files (by descriptor or `FILE`-pointer):
https://github.com/Cisco-Talos/clamav/commit/78d4a9985a06a418dd1338c94ee5db461035d75b
Note: this bypassed FIPS the 1.x way with:
`EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);`
It was NOT disabled when using `cl_hash_init()` / `cl_update_hash()` /
`cl_finish_hash()`. That likely worked by coincidence in that the hash
was already calculated most of the time. It certainly would have made
use of those functions if the hash had not been calculated prior:
https://github.com/Cisco-Talos/clamav/blob/78d4a9985a06a418dd1338c94ee5db461035d75b/libclamav/matcher.c#L743
Regardless, bypassing FIPS entirely is not the correct solution.
The FIPS restrictions against using MD5 and SHA1 are valid, particularly
when verifying CVD digital siganatures, but also I think when using a
hash to determine if the file is known-clean (i.e. the "clean cache" and
also MD5-based and SHA1-based FP signatures).
This commit extends the work to bypass FIPS using the newer 3.x method:
`md = EVP_MD_fetch(NULL, alg, "-fips");`
It does this for the legacy `cl_hash*()` functions including
`cl_hash_init()` / `cl_update_hash()` / `cl_finish_hash()`.
It also introduces extended versions that allow the caller to choose if
they want to bypass FIPS:
- `cl_hash_data_ex()`
- `cl_hash_init_ex()`
- `cl_update_hash_ex()`
- `cl_finish_hash_ex()`
- `cl_hash_destroy_ex()`
- `cl_hash_file_fd_ex()`
See the `flags` parameter for each.
Ironically, this commit does NOT use the new functions at this time.
The rational is that ClamAV may need MD5, SHA1, and SHA-256 hashes of
the same files both for determining if the file is malware, and for
determining if the file is clean.
So instead, this commit will do a checks when:
1. Creating a new ClamAV scanning engine. If FIPS-mode enabled, it will
automatically toggle the "FIPS limits" engine option.
When loading signatures, if the engine "FIPS limits" option is enabled,
then MD5 and SHA1 FP signatures will be skipped.
2. Before verifying a CVD (e.g. also for loading, unpacking when
verification enabled).
If "FIPS limits" or FIPS-mode are enabled, then the legacy MD5-based RSA
method is disabled.
Note: This commit also refactors the interface for `cl_cvdverify_ex()`
and `cl_cvdunpack_ex()` so they take a `flags` parameters, rather than a
single `bool`. As these functions are new in this version, it does not
break the ABI.
The cache was already switched to use SHA2-256, so that's not a concern
for checking FIPS-mode / FIPS limits options.
This adds an option for `freshclam.conf` and `clamd.conf`:
FIPSCryptoHashLimits yes
And an equivalent command-line option for `clamscan` and `sigtool`:
--fips-limits
You may programmatically enable FIPS-limits for a ClamAV engine like this:
```C
cl_engine_set_num(engine, CL_ENGINE_FIPS_LIMITS, 1);
```
CLAM-2792
2025-07-01 20:41:47 -04:00
/* cl_error_t cl_cvdunpack_ex(const char *file, const char *dir, const char *certs_directory, uint32_t dboptions) */
FIPS-compliant CVD signing and verification
Add X509 certificate chain based signing with PKCS7-PEM external
signatures distributed alongside CVD's in a custom .cvd.sign format.
This new signing and verification mechanism is primarily in support
of FIPS compliance.
Fixes: https://github.com/Cisco-Talos/clamav/issues/564
Add a Rust implementation for parsing, verifying, and unpacking CVD
files.
Now installs a 'certs' directory in the app config directory
(e.g. <prefix>/etc/certs). The install location is configurable.
The CMake option to configure the CVD certs directory is:
`-D CVD_CERTS_DIRECTORY=PATH`
New options to set an alternative CVD certs directory:
- Commandline for freshclam, clamd, clamscan, and sigtool is:
`--cvdcertsdir PATH`
- Env variable for freshclam, clamd, clamscan, and sigtool is:
`CVD_CERTS_DIR`
- Config option for freshclam and clamd is:
`CVDCertsDirectory PATH`
Sigtool:
- Add sign/verify commands.
- Also verify CDIFF external digital signatures when applying CDIFFs.
- Place commonly used commands at the top of --help string.
- Fix up manpage.
Freshclam:
- Will try to download .sign files to verify CVDs and CDIFFs.
- Fix an issue where making a CLD would only include the CFG file for
daily and not if patching any other database.
libclamav.so:
- Bump version to 13:0:1 (aka 12.1.0).
- Also remove libclamav.map versioning.
Resolves: https://github.com/Cisco-Talos/clamav/issues/1304
- Add two new API's to the public clamav.h header:
```c
extern cl_error_t cl_cvdverify_ex(const char *file,
const char *certs_directory);
extern cl_error_t cl_cvdunpack_ex(const char *file,
const char *dir,
bool dont_verify,
const char *certs_directory);
```
The original `cl_cvdverify` and `cl_cvdunpack` are deprecated.
- Add `cl_engine_field` enum option `CL_ENGINE_CVDCERTSDIR`.
You may set this option with `cl_engine_set_str` and get it
with `cl_engine_get_str`, to override the compiled in default
CVD certs directory.
libfreshclam.so: Bump version to 4:0:0 (aka 4.0.0).
Add sigtool sign/verify tests and test certs.
Make it so downloadFile doesn't throw a warning if the server
doesn't have the .sign file.
Replace use of md5-based FP signatures in the unit tests with
sha256-based FP signatures because the md5 implementation used
by Python may be disabled in FIPS mode.
Fixes: https://github.com/Cisco-Talos/clamav/issues/1411
CMake: Add logic to enable the Rust openssl-sys / openssl-rs crates
to build against the same OpenSSL library as is used for the C build.
The Rust unit test application must also link directly with libcrypto
and libssl.
Fix some log messages with missing new lines.
Fix missing environment variable notes in --help messages and manpages.
Deconflict CONFDIR/DATADIR/CERTSDIR variable names that are defined in
clamav-config.h.in for libclamav from variable that had the same name
for use in clamav applications that use the optparser.
The 'clamav-test' certs for the unit tests will live for 10 years.
The 'clamav-beta.crt' public cert will only live for 120 days and will
be replaced before the stable release with a production 'clamav.crt'.
2024-11-21 14:01:09 -05:00
START_TEST ( test_cl_cvdunpack_ex )
2022-08-30 15:51:13 -07:00
{
cl_error_t ret ;
char * utf8 = NULL ;
size_t utf8_size = 0 ;
const char * testfile ;
testfile = SRCDIR " /input/freshclam_testfiles/test-1.cvd " ;
FIPS & FIPS-like limits on hash algs for cryptographic uses
ClamAV will not function when using a FIPS-enabled OpenSSL 3.x.
This is because ClamAV uses MD5 and SHA1 algorithms for a variety of
purposes including matching for malware detection, matching to prevent
false positives on known-clean files, and for verification of MD5-based
RSA digital signatures for determining CVD (signature database archive)
authenticity.
Interestingly, FIPS had been intentionally bypassed when creating hashes
based whole buffers and whole files (by descriptor or `FILE`-pointer):
https://github.com/Cisco-Talos/clamav/commit/78d4a9985a06a418dd1338c94ee5db461035d75b
Note: this bypassed FIPS the 1.x way with:
`EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);`
It was NOT disabled when using `cl_hash_init()` / `cl_update_hash()` /
`cl_finish_hash()`. That likely worked by coincidence in that the hash
was already calculated most of the time. It certainly would have made
use of those functions if the hash had not been calculated prior:
https://github.com/Cisco-Talos/clamav/blob/78d4a9985a06a418dd1338c94ee5db461035d75b/libclamav/matcher.c#L743
Regardless, bypassing FIPS entirely is not the correct solution.
The FIPS restrictions against using MD5 and SHA1 are valid, particularly
when verifying CVD digital siganatures, but also I think when using a
hash to determine if the file is known-clean (i.e. the "clean cache" and
also MD5-based and SHA1-based FP signatures).
This commit extends the work to bypass FIPS using the newer 3.x method:
`md = EVP_MD_fetch(NULL, alg, "-fips");`
It does this for the legacy `cl_hash*()` functions including
`cl_hash_init()` / `cl_update_hash()` / `cl_finish_hash()`.
It also introduces extended versions that allow the caller to choose if
they want to bypass FIPS:
- `cl_hash_data_ex()`
- `cl_hash_init_ex()`
- `cl_update_hash_ex()`
- `cl_finish_hash_ex()`
- `cl_hash_destroy_ex()`
- `cl_hash_file_fd_ex()`
See the `flags` parameter for each.
Ironically, this commit does NOT use the new functions at this time.
The rational is that ClamAV may need MD5, SHA1, and SHA-256 hashes of
the same files both for determining if the file is malware, and for
determining if the file is clean.
So instead, this commit will do a checks when:
1. Creating a new ClamAV scanning engine. If FIPS-mode enabled, it will
automatically toggle the "FIPS limits" engine option.
When loading signatures, if the engine "FIPS limits" option is enabled,
then MD5 and SHA1 FP signatures will be skipped.
2. Before verifying a CVD (e.g. also for loading, unpacking when
verification enabled).
If "FIPS limits" or FIPS-mode are enabled, then the legacy MD5-based RSA
method is disabled.
Note: This commit also refactors the interface for `cl_cvdverify_ex()`
and `cl_cvdunpack_ex()` so they take a `flags` parameters, rather than a
single `bool`. As these functions are new in this version, it does not
break the ABI.
The cache was already switched to use SHA2-256, so that's not a concern
for checking FIPS-mode / FIPS limits options.
This adds an option for `freshclam.conf` and `clamd.conf`:
FIPSCryptoHashLimits yes
And an equivalent command-line option for `clamscan` and `sigtool`:
--fips-limits
You may programmatically enable FIPS-limits for a ClamAV engine like this:
```C
cl_engine_set_num(engine, CL_ENGINE_FIPS_LIMITS, 1);
```
CLAM-2792
2025-07-01 20:41:47 -04:00
ret = cl_cvdunpack_ex ( testfile , tmpdir , NULL , CL_DB_UNSIGNED ) ;
FIPS-compliant CVD signing and verification
Add X509 certificate chain based signing with PKCS7-PEM external
signatures distributed alongside CVD's in a custom .cvd.sign format.
This new signing and verification mechanism is primarily in support
of FIPS compliance.
Fixes: https://github.com/Cisco-Talos/clamav/issues/564
Add a Rust implementation for parsing, verifying, and unpacking CVD
files.
Now installs a 'certs' directory in the app config directory
(e.g. <prefix>/etc/certs). The install location is configurable.
The CMake option to configure the CVD certs directory is:
`-D CVD_CERTS_DIRECTORY=PATH`
New options to set an alternative CVD certs directory:
- Commandline for freshclam, clamd, clamscan, and sigtool is:
`--cvdcertsdir PATH`
- Env variable for freshclam, clamd, clamscan, and sigtool is:
`CVD_CERTS_DIR`
- Config option for freshclam and clamd is:
`CVDCertsDirectory PATH`
Sigtool:
- Add sign/verify commands.
- Also verify CDIFF external digital signatures when applying CDIFFs.
- Place commonly used commands at the top of --help string.
- Fix up manpage.
Freshclam:
- Will try to download .sign files to verify CVDs and CDIFFs.
- Fix an issue where making a CLD would only include the CFG file for
daily and not if patching any other database.
libclamav.so:
- Bump version to 13:0:1 (aka 12.1.0).
- Also remove libclamav.map versioning.
Resolves: https://github.com/Cisco-Talos/clamav/issues/1304
- Add two new API's to the public clamav.h header:
```c
extern cl_error_t cl_cvdverify_ex(const char *file,
const char *certs_directory);
extern cl_error_t cl_cvdunpack_ex(const char *file,
const char *dir,
bool dont_verify,
const char *certs_directory);
```
The original `cl_cvdverify` and `cl_cvdunpack` are deprecated.
- Add `cl_engine_field` enum option `CL_ENGINE_CVDCERTSDIR`.
You may set this option with `cl_engine_set_str` and get it
with `cl_engine_get_str`, to override the compiled in default
CVD certs directory.
libfreshclam.so: Bump version to 4:0:0 (aka 4.0.0).
Add sigtool sign/verify tests and test certs.
Make it so downloadFile doesn't throw a warning if the server
doesn't have the .sign file.
Replace use of md5-based FP signatures in the unit tests with
sha256-based FP signatures because the md5 implementation used
by Python may be disabled in FIPS mode.
Fixes: https://github.com/Cisco-Talos/clamav/issues/1411
CMake: Add logic to enable the Rust openssl-sys / openssl-rs crates
to build against the same OpenSSL library as is used for the C build.
The Rust unit test application must also link directly with libcrypto
and libssl.
Fix some log messages with missing new lines.
Fix missing environment variable notes in --help messages and manpages.
Deconflict CONFDIR/DATADIR/CERTSDIR variable names that are defined in
clamav-config.h.in for libclamav from variable that had the same name
for use in clamav applications that use the optparser.
The 'clamav-test' certs for the unit tests will live for 10 years.
The 'clamav-beta.crt' public cert will only live for 120 days and will
be replaced before the stable release with a production 'clamav.crt'.
2024-11-21 14:01:09 -05:00
ck_assert_msg ( CL_SUCCESS = = ret , " cl_cvdunpack_ex: failed for: %s -- %s " , testfile , cl_strerror ( ret ) ) ;
2022-08-30 15:51:13 -07:00
// Can't unpack a cdiff
testfile = SRCDIR " /input/freshclam_testfiles/test-2.cdiff " ;
FIPS & FIPS-like limits on hash algs for cryptographic uses
ClamAV will not function when using a FIPS-enabled OpenSSL 3.x.
This is because ClamAV uses MD5 and SHA1 algorithms for a variety of
purposes including matching for malware detection, matching to prevent
false positives on known-clean files, and for verification of MD5-based
RSA digital signatures for determining CVD (signature database archive)
authenticity.
Interestingly, FIPS had been intentionally bypassed when creating hashes
based whole buffers and whole files (by descriptor or `FILE`-pointer):
https://github.com/Cisco-Talos/clamav/commit/78d4a9985a06a418dd1338c94ee5db461035d75b
Note: this bypassed FIPS the 1.x way with:
`EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);`
It was NOT disabled when using `cl_hash_init()` / `cl_update_hash()` /
`cl_finish_hash()`. That likely worked by coincidence in that the hash
was already calculated most of the time. It certainly would have made
use of those functions if the hash had not been calculated prior:
https://github.com/Cisco-Talos/clamav/blob/78d4a9985a06a418dd1338c94ee5db461035d75b/libclamav/matcher.c#L743
Regardless, bypassing FIPS entirely is not the correct solution.
The FIPS restrictions against using MD5 and SHA1 are valid, particularly
when verifying CVD digital siganatures, but also I think when using a
hash to determine if the file is known-clean (i.e. the "clean cache" and
also MD5-based and SHA1-based FP signatures).
This commit extends the work to bypass FIPS using the newer 3.x method:
`md = EVP_MD_fetch(NULL, alg, "-fips");`
It does this for the legacy `cl_hash*()` functions including
`cl_hash_init()` / `cl_update_hash()` / `cl_finish_hash()`.
It also introduces extended versions that allow the caller to choose if
they want to bypass FIPS:
- `cl_hash_data_ex()`
- `cl_hash_init_ex()`
- `cl_update_hash_ex()`
- `cl_finish_hash_ex()`
- `cl_hash_destroy_ex()`
- `cl_hash_file_fd_ex()`
See the `flags` parameter for each.
Ironically, this commit does NOT use the new functions at this time.
The rational is that ClamAV may need MD5, SHA1, and SHA-256 hashes of
the same files both for determining if the file is malware, and for
determining if the file is clean.
So instead, this commit will do a checks when:
1. Creating a new ClamAV scanning engine. If FIPS-mode enabled, it will
automatically toggle the "FIPS limits" engine option.
When loading signatures, if the engine "FIPS limits" option is enabled,
then MD5 and SHA1 FP signatures will be skipped.
2. Before verifying a CVD (e.g. also for loading, unpacking when
verification enabled).
If "FIPS limits" or FIPS-mode are enabled, then the legacy MD5-based RSA
method is disabled.
Note: This commit also refactors the interface for `cl_cvdverify_ex()`
and `cl_cvdunpack_ex()` so they take a `flags` parameters, rather than a
single `bool`. As these functions are new in this version, it does not
break the ABI.
The cache was already switched to use SHA2-256, so that's not a concern
for checking FIPS-mode / FIPS limits options.
This adds an option for `freshclam.conf` and `clamd.conf`:
FIPSCryptoHashLimits yes
And an equivalent command-line option for `clamscan` and `sigtool`:
--fips-limits
You may programmatically enable FIPS-limits for a ClamAV engine like this:
```C
cl_engine_set_num(engine, CL_ENGINE_FIPS_LIMITS, 1);
```
CLAM-2792
2025-07-01 20:41:47 -04:00
ret = cl_cvdunpack_ex ( testfile , tmpdir , NULL , CL_DB_UNSIGNED ) ;
FIPS-compliant CVD signing and verification
Add X509 certificate chain based signing with PKCS7-PEM external
signatures distributed alongside CVD's in a custom .cvd.sign format.
This new signing and verification mechanism is primarily in support
of FIPS compliance.
Fixes: https://github.com/Cisco-Talos/clamav/issues/564
Add a Rust implementation for parsing, verifying, and unpacking CVD
files.
Now installs a 'certs' directory in the app config directory
(e.g. <prefix>/etc/certs). The install location is configurable.
The CMake option to configure the CVD certs directory is:
`-D CVD_CERTS_DIRECTORY=PATH`
New options to set an alternative CVD certs directory:
- Commandline for freshclam, clamd, clamscan, and sigtool is:
`--cvdcertsdir PATH`
- Env variable for freshclam, clamd, clamscan, and sigtool is:
`CVD_CERTS_DIR`
- Config option for freshclam and clamd is:
`CVDCertsDirectory PATH`
Sigtool:
- Add sign/verify commands.
- Also verify CDIFF external digital signatures when applying CDIFFs.
- Place commonly used commands at the top of --help string.
- Fix up manpage.
Freshclam:
- Will try to download .sign files to verify CVDs and CDIFFs.
- Fix an issue where making a CLD would only include the CFG file for
daily and not if patching any other database.
libclamav.so:
- Bump version to 13:0:1 (aka 12.1.0).
- Also remove libclamav.map versioning.
Resolves: https://github.com/Cisco-Talos/clamav/issues/1304
- Add two new API's to the public clamav.h header:
```c
extern cl_error_t cl_cvdverify_ex(const char *file,
const char *certs_directory);
extern cl_error_t cl_cvdunpack_ex(const char *file,
const char *dir,
bool dont_verify,
const char *certs_directory);
```
The original `cl_cvdverify` and `cl_cvdunpack` are deprecated.
- Add `cl_engine_field` enum option `CL_ENGINE_CVDCERTSDIR`.
You may set this option with `cl_engine_set_str` and get it
with `cl_engine_get_str`, to override the compiled in default
CVD certs directory.
libfreshclam.so: Bump version to 4:0:0 (aka 4.0.0).
Add sigtool sign/verify tests and test certs.
Make it so downloadFile doesn't throw a warning if the server
doesn't have the .sign file.
Replace use of md5-based FP signatures in the unit tests with
sha256-based FP signatures because the md5 implementation used
by Python may be disabled in FIPS mode.
Fixes: https://github.com/Cisco-Talos/clamav/issues/1411
CMake: Add logic to enable the Rust openssl-sys / openssl-rs crates
to build against the same OpenSSL library as is used for the C build.
The Rust unit test application must also link directly with libcrypto
and libssl.
Fix some log messages with missing new lines.
Fix missing environment variable notes in --help messages and manpages.
Deconflict CONFDIR/DATADIR/CERTSDIR variable names that are defined in
clamav-config.h.in for libclamav from variable that had the same name
for use in clamav applications that use the optparser.
The 'clamav-test' certs for the unit tests will live for 10 years.
The 'clamav-beta.crt' public cert will only live for 120 days and will
be replaced before the stable release with a production 'clamav.crt'.
2024-11-21 14:01:09 -05:00
ck_assert_msg ( CL_ECVD = = ret , " cl_cvdunpack_ex: should have failed for: %s -- %s " , testfile , cl_strerror ( ret ) ) ;
2020-02-29 18:28:39 -05:00
}
2008-03-13 10:44:34 +00:00
END_TEST
/* int cl_statinidir(const char *dirname, struct cl_stat *dbstat) */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_statinidir )
2020-02-29 18:28:39 -05:00
{
}
2008-03-13 10:44:34 +00:00
END_TEST
/* int cl_statchkdir(const struct cl_stat *dbstat) */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_statchkdir )
2020-02-29 18:28:39 -05:00
{
}
2008-03-13 10:44:34 +00:00
END_TEST
/* void cl_settempdir(const char *dir, short leavetemps) */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_settempdir )
2020-02-29 18:28:39 -05:00
{
}
2008-03-13 10:44:34 +00:00
END_TEST
/* const char *cl_strerror(int clerror) */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_strerror )
2020-02-29 18:28:39 -05:00
{
}
2008-03-13 10:44:34 +00:00
END_TEST
2018-12-03 12:40:13 -05:00
static char * * testfiles = NULL ;
2011-06-15 12:21:50 +03:00
static unsigned testfiles_n = 0 ;
2013-10-11 16:51:41 -04:00
ZIP: Fix infinite loop + significant code cleanup
An infinite loop may occur when scanning some malformed ZIP files.
I introduced this issue in 96c00b6d80a4cb16cb2d39111614733e4a62221d
with this line:
```c
// decrement coff by 1 to account for the increment at the end of the loop
coff -= 1;
```
The problem is that the function may return 0, which should
indicate that there are no more files. The result was that
`coff` would stay the same and the loop would repeat.
This issue is in 1.5 development and affects the 1.5.0 beta but
does not affect any production versions.
Fixes: https://github.com/Cisco-Talos/clamav/issues/1534
Special thanks to Sophie0x2E for an initial fix, proposed in
https://github.com/Cisco-Talos/clamav/pull/1539
In review, I was uncomfortable with other existing code and
decided to to a more significant overhaul of the error handling
in the ZIP module.
In addition to cleanup, this commit has some functional changes:
- When parsing a central directory file header inside of
`parse_central_directory_file_header()`, it will now fail out if the
"extra length" or "comment length" fields would exceced the length of
the archive. That doesn't mean the associated local file header won't
be parsed later, but it won't use the central directory file header
to find it. Instead, the ZIP module will have to find the local file
header by searching for extra records not listed in the central directory.
This change was mostly to tidy up complex error handling.
- Add two FTM new signatures to identify split ZIP archives.
This signature identifies the first segment (first file) in a split or
spanned ZIP archive. It may also be found on a single-segment "split"
archive, depending on the ZIP archiver.
```
0:0:504b0708504b0304:ZIP (First segment split/spanned):CL_TYPE_ANY:CL_TYPE_ZIP
```
Practically speaking, this new signature makes it so ClamAV identifies
the file as a ZIP right away without having to rely on SFX_ZIP detection.
Extraction is then handled by the ZIP `cli_unzip` function rather than
extracting each with `cli_unzip_single` which handles SFX_ZIP entries.
Note: ClamAV isn't capable of finding additional files on disk to support
handling the additional segments. So it doesn't make any difference with
handling those other files.
This signature is for single-segment split/spanned archives, depending
on the ZIP archiver.
```
0:0:504b0303504b0304:ZIP (Single-segment split/spanned):CL_TYPE_ANY:CL_TYPE_ZIP
```
Like the first one, this also means we won't rely on SFX_ZIP detection
and will treat this files as regular ZIPs.
- Added a test file to verify that ClamAV can extract a single-file
"split" ZIP.
- Added a clamscan test with test files to verify that scanning a split
archive across two segments correctly extracts the properly formed zip
file entries. Sadly, we can't join the segments to extract everything.
2025-08-04 22:50:48 -04:00
static const int expected_testfiles = 53 ;
2011-06-15 12:21:50 +03:00
2014-03-18 17:23:27 -04:00
static unsigned skip_files ( void )
2014-03-13 12:50:30 -04:00
{
2014-03-18 17:23:27 -04:00
unsigned skipped = 0 ;
/* skip .rar files if unrar is disabled */
2021-07-30 07:30:26 -07:00
# if HAVE_UNRAR
# else
skipped + = 2 ;
# endif
2014-03-18 17:23:27 -04:00
return skipped ;
2014-03-13 12:50:30 -04:00
}
2011-06-15 12:21:50 +03:00
static void init_testfiles ( void )
{
struct dirent * dirent ;
unsigned i = 0 ;
2013-11-04 12:14:19 -05:00
int expect = expected_testfiles ;
2011-06-15 12:21:50 +03:00
2021-07-16 13:43:28 -07:00
DIR * d = opendir ( OBJDIR PATHSEP " input " PATHSEP " clamav_hdb_scanfiles " ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ! ! d , " opendir " ) ;
2011-06-15 12:21:50 +03:00
if ( ! d )
2018-12-03 12:40:13 -05:00
return ;
testfiles = NULL ;
2011-06-15 12:21:50 +03:00
testfiles_n = 0 ;
while ( ( dirent = readdir ( d ) ) ) {
2018-12-03 12:40:13 -05:00
if ( strncmp ( dirent - > d_name , " clam " , 4 ) )
continue ;
2014-03-13 12:50:30 -04:00
i + + ;
Remove max-allocation limits where not required
The cli_max_malloc, cli_max_calloc, and cli_max_realloc functions
provide a way to protect against allocating too much memory
when the size of the allocation is derived from the untrusted input.
Specifically, we worry about values in the file being scanned being
manipulated to exhaust the RAM and crash the application.
There is no need to check the limits if the size of the allocation
is fixed, or if the size of the allocation is necessary for signature
loading, or the general operation of the applications.
E.g. checking the max-allocation limit for the size of a hash, or
for the size of the scan recursion stack, is a complete waste of
time.
Although we significantly increased the max-allocation limit in
a recent release, it is best not to check an allocation if the
allocation will be safe. It would be a waste of time.
I am also hopeful that if we can reduce the number allocations
that require a limit-check to those that require it for the safe
scan of a file, then eventually we can store the limit in the scan-
context, and make it configurable.
2024-01-08 22:48:28 -05:00
testfiles = cli_safer_realloc ( testfiles , i * sizeof ( * testfiles ) ) ;
ck_assert_msg ( ! ! testfiles , " cli_safer_realloc " ) ;
2018-12-03 12:40:13 -05:00
testfiles [ i - 1 ] = strdup ( dirent - > d_name ) ;
2011-06-15 12:21:50 +03:00
}
testfiles_n = i ;
2013-11-11 18:00:58 -05:00
if ( get_fpu_endian ( ) = = FPU_ENDIAN_UNKNOWN )
expect - - ;
2014-03-18 17:23:27 -04:00
expect - = skip_files ( ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( testfiles_n = = expect , " testfiles: %d != %d " , testfiles_n , expect ) ;
2011-06-15 12:21:50 +03:00
closedir ( d ) ;
}
static void free_testfiles ( void )
{
unsigned i ;
2018-12-03 12:40:13 -05:00
for ( i = 0 ; i < testfiles_n ; i + + ) {
free ( testfiles [ i ] ) ;
2011-06-15 12:21:50 +03:00
}
free ( testfiles ) ;
2018-12-03 12:40:13 -05:00
testfiles = NULL ;
2011-06-15 12:21:50 +03:00
testfiles_n = 0 ;
}
static int inited = 0 ;
static void engine_setup ( void )
{
unsigned int sigs = 0 ;
2021-07-16 13:43:28 -07:00
const char * hdb = OBJDIR PATHSEP " input " PATHSEP " clamav.hdb " ;
2011-06-15 12:21:50 +03:00
init_testfiles ( ) ;
if ( ! inited )
2020-01-15 08:14:23 -08:00
ck_assert_msg ( cl_init ( CL_INIT_DEFAULT ) = = 0 , " cl_init " ) ;
2018-12-03 12:40:13 -05:00
inited = 1 ;
2011-06-15 12:21:50 +03:00
g_engine = cl_engine_new ( ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ! ! g_engine , " engine " ) ;
ck_assert_msg ( cl_load ( hdb , g_engine , & sigs , CL_DB_STDOPT ) = = 0 , " cl_load %s " , hdb ) ;
ck_assert_msg ( sigs = = 1 , " sigs " ) ;
ck_assert_msg ( cl_engine_compile ( g_engine ) = = 0 , " cl_engine_compile " ) ;
2011-06-15 12:21:50 +03:00
}
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 ;
2012-07-16 15:36:49 -04:00
STATBUF st ;
2011-06-15 12:21:50 +03:00
2020-01-15 08:14:23 -08:00
ck_assert_msg ( i < testfiles_n , " %i < %i %s " , i , testfiles_n , file ) ;
2021-07-16 13:43:28 -07:00
snprintf ( file , fsize , OBJDIR PATHSEP " input " PATHSEP " clamav_hdb_scanfiles " PATHSEP " %s " , testfiles [ i ] ) ;
2011-06-15 12:21:50 +03:00
2020-12-07 15:18:29 -08:00
fd = open ( file , O_RDONLY | O_BINARY ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( fd > 0 , " open " ) ;
ck_assert_msg ( FSTAT ( fd , & st ) = = 0 , " fstat " ) ;
2011-06-15 12:21:50 +03:00
* size = st . st_size ;
return fd ;
}
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
# ifndef _WIN32
2012-11-06 10:35:10 -05:00
static off_t pread_cb ( void * handle , void * buf , size_t count , off_t offset )
2011-06-14 22:35:03 +03:00
{
2018-12-03 12:40:13 -05:00
return pread ( * ( ( int * ) handle ) , buf , count , offset ) ;
2011-06-14 22:35:03 +03:00
}
2018-12-03 12:40:13 -05:00
START_TEST ( test_cl_scanmap_callback_handle )
2011-06-14 22:35:03 +03:00
{
2018-12-03 12:40:13 -05:00
const char * virname = NULL ;
2011-06-14 22:54:44 +03:00
unsigned long int scanned = 0 ;
2011-06-14 22:35:03 +03:00
cl_fmap_t * map ;
int ret ;
2011-06-15 12:07:04 +03:00
char file [ 256 ] ;
unsigned long size ;
2018-07-20 22:28:48 -04:00
struct cl_scan_options options ;
memset ( & options , 0 , sizeof ( struct cl_scan_options ) ) ;
options . parse | = ~ 0 ;
2011-06-14 22:35:03 +03:00
2011-06-15 12:07:04 +03:00
int fd = get_test_file ( _i , file , sizeof ( file ) , & size ) ;
2011-06-14 22:35:03 +03:00
/* intentionally use different way than scanners.c for testing */
2011-06-15 12:07:04 +03:00
map = cl_fmap_open_handle ( & fd , 0 , size , pread_cb , 1 ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ! ! map , " cl_fmap_open_handle " ) ;
2011-06-14 22:35:03 +03:00
2011-06-14 22:54:44 +03:00
cli_dbgmsg ( " scanning (handle) %s \n " , file ) ;
2018-07-30 20:19:28 -04:00
ret = cl_scanmap_callback ( map , file , & virname , & scanned , g_engine , & options , NULL ) ;
2011-06-14 22:54:44 +03:00
cli_dbgmsg ( " scan end (handle) %s \n " , file ) ;
2013-10-31 15:41:38 -04:00
if ( ! FALSE_NEGATIVE ) {
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ret = = CL_VIRUS , " cl_scanmap_callback failed for %s: %s " , file , cl_strerror ( ret ) ) ;
ck_assert_msg ( virname & & ! strcmp ( virname , " ClamAV-Test-File.UNOFFICIAL " ) , " virusname: %s " , virname ) ;
2013-10-31 15:41:38 -04:00
}
2020-02-29 18:28:39 -05:00
cl_fmap_close ( map ) ;
2011-06-14 22:35:03 +03:00
close ( fd ) ;
}
END_TEST
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
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 ;
struct cl_scan_options options ;
memset ( & options , 0 , sizeof ( struct cl_scan_options ) ) ;
options . parse | = ~ 0 ;
options . general | = CL_SCAN_GENERAL_ALLMATCHES ;
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 ) ;
2021-10-03 14:13:55 -07:00
ck_assert ( ! ! map ) ;
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
cli_dbgmsg ( " scanning (handle) allscan %s \n " , file ) ;
ret = cl_scanmap_callback ( map , file , & virname , & scanned , g_engine , & options , NULL ) ;
cli_dbgmsg ( " scan end (handle) allscan %s \n " , file ) ;
if ( ! FALSE_NEGATIVE ) {
ck_assert_msg ( ret = = CL_VIRUS , " cl_scanmap_callback allscan failed for %s: %s " , file , cl_strerror ( ret ) ) ;
ck_assert_msg ( virname & & ! strcmp ( virname , " ClamAV-Test-File.UNOFFICIAL " ) , " virusname: %s " , virname ) ;
}
cl_fmap_close ( map ) ;
close ( fd ) ;
}
END_TEST
# endif
# ifdef HAVE_SYS_MMAN_H
START_TEST ( test_cl_scanmap_callback_mem )
{
const char * virname = NULL ;
unsigned long int scanned = 0 ;
cl_fmap_t * map ;
int ret ;
void * mem ;
unsigned long size ;
char file [ 256 ] ;
struct cl_scan_options options ;
memset ( & options , 0 , sizeof ( struct cl_scan_options ) ) ;
options . parse | = ~ 0 ;
int fd = get_test_file ( _i , file , sizeof ( file ) , & size ) ;
mem = mmap ( NULL , size , PROT_READ , MAP_PRIVATE , fd , 0 ) ;
ck_assert_msg ( mem ! = MAP_FAILED , " mmap " ) ;
/* intentionally use different way than scanners.c for testing */
map = cl_fmap_open_memory ( mem , size ) ;
ck_assert_msg ( ! ! map , " cl_fmap_open_mem " ) ;
cli_dbgmsg ( " scanning (mem) %s \n " , file ) ;
ret = cl_scanmap_callback ( map , file , & virname , & scanned , g_engine , & options , NULL ) ;
cli_dbgmsg ( " scan end (mem) %s \n " , file ) ;
if ( ! FALSE_NEGATIVE ) {
ck_assert_msg ( ret = = CL_VIRUS , " cl_scanmap_callback failed for %s: %s " , file , cl_strerror ( ret ) ) ;
ck_assert_msg ( virname & & ! strcmp ( virname , " ClamAV-Test-File.UNOFFICIAL " ) , " virusname: %s for %s " , virname , file ) ;
}
close ( fd ) ;
cl_fmap_close ( map ) ;
munmap ( mem , size ) ;
}
END_TEST
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 ] ;
struct cl_scan_options options ;
memset ( & options , 0 , sizeof ( struct cl_scan_options ) ) ;
options . parse | = ~ 0 ;
options . general | = CL_SCAN_GENERAL_ALLMATCHES ;
int fd = get_test_file ( _i , file , sizeof ( file ) , & size ) ;
mem = mmap ( NULL , size , PROT_READ , MAP_PRIVATE , fd , 0 ) ;
ck_assert_msg ( mem ! = MAP_FAILED , " mmap " ) ;
/* intentionally use different way than scanners.c for testing */
map = cl_fmap_open_memory ( mem , size ) ;
2021-10-03 14:13:55 -07:00
ck_assert ( ! ! map ) ;
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
cli_dbgmsg ( " scanning (mem) allscan %s \n " , file ) ;
ret = cl_scanmap_callback ( map , file , & virname , & scanned , g_engine , & options , NULL ) ;
cli_dbgmsg ( " scan end (mem) allscan %s \n " , file ) ;
if ( ! FALSE_NEGATIVE ) {
ck_assert_msg ( ret = = CL_VIRUS , " cl_scanmap_callback allscan failed for %s: %s " , file , cl_strerror ( ret ) ) ;
ck_assert_msg ( virname & & ! strcmp ( virname , " ClamAV-Test-File.UNOFFICIAL " ) , " virusname: %s for %s " , virname , file ) ;
}
close ( fd ) ;
cl_fmap_close ( map ) ;
munmap ( mem , size ) ;
}
END_TEST
# endif
2021-01-23 16:41:41 -08:00
START_TEST ( test_fmap_duplicate )
{
cl_fmap_t * map ;
cl_fmap_t * dup_map = NULL ;
cl_fmap_t * dup_dup_map = NULL ;
char map_data [ 6 ] = { ' a ' , ' b ' , ' c ' , ' d ' , ' e ' , ' f ' } ;
char tmp [ 6 ] ;
size_t bread = 0 ;
map = cl_fmap_open_memory ( map_data , sizeof ( map_data ) ) ;
ck_assert_msg ( ! ! map , " cl_fmap_open_handle failed " ) ;
/*
* Test duplicate of entire map
*/
cli_dbgmsg ( " duplicating complete map \n " ) ;
dup_map = fmap_duplicate ( map , 0 , map - > len , " complete duplicate " ) ;
ck_assert_msg ( ! ! dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_map - > nested_offset = = 0 , " dup_map nested_offset is incorrect: %zu " , dup_map - > nested_offset ) ;
ck_assert_msg ( dup_map - > len = = map - > len , " dup_map len is incorrect: %zu " , dup_map - > len ) ;
ck_assert_msg ( dup_map - > real_len = = map - > len , " dup_map real len is incorrect: %zu " , dup_map - > real_len ) ;
bread = fmap_readn ( dup_map , tmp , 0 , 6 ) ;
ck_assert ( bread = = 6 ) ;
ck_assert ( 0 = = memcmp ( map_data , tmp , 6 ) ) ;
cli_dbgmsg ( " freeing dup_map \n " ) ;
free_duplicate_fmap ( dup_map ) ;
dup_map = NULL ;
/*
* Test duplicate of map at offset 2
*/
cli_dbgmsg ( " duplicating 2 bytes into map \n " ) ;
dup_map = fmap_duplicate ( map , 2 , map - > len , " offset duplicate " ) ;
ck_assert_msg ( ! ! dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_map - > nested_offset = = 2 , " dup_map nested_offset is incorrect: %zu " , dup_map - > nested_offset ) ;
ck_assert_msg ( dup_map - > len = = 4 , " dup_map len is incorrect: %zu " , dup_map - > len ) ;
ck_assert_msg ( dup_map - > real_len = = 6 , " dup_map real len is incorrect: %zu " , dup_map - > real_len ) ;
bread = fmap_readn ( dup_map , tmp , 0 , 6 ) ;
ck_assert ( bread = = 4 ) ;
ck_assert ( 0 = = memcmp ( map_data + 2 , tmp , 4 ) ) ;
/*
* Test duplicate of duplicate map , also at offset 2 ( total 4 bytes in )
*/
cli_dbgmsg ( " duplicating 2 bytes into dup_map \n " ) ;
dup_dup_map = fmap_duplicate ( dup_map , 2 , dup_map - > len , " double offset duplicate " ) ;
ck_assert_msg ( ! ! dup_dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_dup_map - > nested_offset = = 4 , " dup_dup_map nested_offset is incorrect: %zu " , dup_dup_map - > nested_offset ) ;
ck_assert_msg ( dup_dup_map - > len = = 2 , " dup_dup_map len is incorrect: %zu " , dup_dup_map - > len ) ;
ck_assert_msg ( dup_dup_map - > real_len = = 6 , " dup_dup_map real len is incorrect: %zu " , dup_dup_map - > real_len ) ;
bread = fmap_readn ( dup_dup_map , tmp , 0 , 6 ) ;
ck_assert ( bread = = 2 ) ;
ck_assert ( 0 = = memcmp ( map_data + 4 , tmp , 2 ) ) ;
cli_dbgmsg ( " freeing dup_dup_map \n " ) ;
free_duplicate_fmap ( dup_dup_map ) ;
dup_dup_map = NULL ;
cli_dbgmsg ( " freeing dup_map \n " ) ;
free_duplicate_fmap ( dup_map ) ;
dup_map = NULL ;
/*
2023-11-26 15:01:19 -08:00
* Test duplicate of map omitting the last 2 bytes
2021-01-23 16:41:41 -08:00
*/
cli_dbgmsg ( " duplicating map with shorter len \n " ) ;
dup_map = fmap_duplicate ( map , 0 , map - > len - 2 , " short duplicate " ) ;
ck_assert_msg ( ! ! dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_map - > nested_offset = = 0 , " dup_map nested_offset is incorrect: %zu " , dup_map - > nested_offset ) ;
ck_assert_msg ( dup_map - > len = = 4 , " dup_map len is incorrect: %zu " , dup_map - > len ) ;
2021-10-03 14:13:55 -07:00
ck_assert_msg ( dup_map - > real_len = = 4 , " dup_map real len is incorrect: %zu " , dup_map - > real_len ) ;
2021-01-23 16:41:41 -08:00
bread = fmap_readn ( dup_map , tmp , 0 , 6 ) ;
ck_assert ( bread = = 4 ) ;
ck_assert ( 0 = = memcmp ( map_data , tmp , 4 ) ) ;
/*
2023-11-26 15:01:19 -08:00
* Test duplicate of the duplicate omitting the last 2 bytes again ( so just the first 2 bytes )
2021-01-23 16:41:41 -08:00
*/
cli_dbgmsg ( " duplicating dup_map with shorter len \n " ) ;
dup_dup_map = fmap_duplicate ( dup_map , 0 , dup_map - > len - 2 , " double short duplicate " ) ;
ck_assert_msg ( ! ! dup_dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_dup_map - > nested_offset = = 0 , " dup_dup_map nested_offset is incorrect: %zu " , dup_dup_map - > nested_offset ) ;
ck_assert_msg ( dup_dup_map - > len = = 2 , " dup_dup_map len is incorrect: %zu " , dup_dup_map - > len ) ;
2021-10-03 14:13:55 -07:00
ck_assert_msg ( dup_dup_map - > real_len = = 2 , " dup_dup_map real len is incorrect: %zu " , dup_dup_map - > real_len ) ;
2021-01-23 16:41:41 -08:00
bread = fmap_readn ( dup_dup_map , tmp , 0 , 6 ) ;
ck_assert ( bread = = 2 ) ;
ck_assert ( 0 = = memcmp ( map_data , tmp , 2 ) ) ;
cli_dbgmsg ( " freeing dup_dup_map \n " ) ;
free_duplicate_fmap ( dup_dup_map ) ;
dup_dup_map = NULL ;
cli_dbgmsg ( " freeing dup_map \n " ) ;
free_duplicate_fmap ( dup_map ) ;
dup_map = NULL ;
/*
* Test duplicate of map at offset 2
*/
cli_dbgmsg ( " duplicating 2 bytes into map \n " ) ;
dup_map = fmap_duplicate ( map , 2 , map - > len , " offset duplicate " ) ;
ck_assert_msg ( ! ! dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_map - > nested_offset = = 2 , " dup_map nested_offset is incorrect: %zu " , dup_map - > nested_offset ) ;
ck_assert_msg ( dup_map - > len = = 4 , " dup_map len is incorrect: %zu " , dup_map - > len ) ;
ck_assert_msg ( dup_map - > real_len = = 6 , " dup_map real len is incorrect: %zu " , dup_map - > real_len ) ;
bread = fmap_readn ( dup_map , tmp , 0 , 6 ) ;
ck_assert ( bread = = 4 ) ;
ck_assert ( 0 = = memcmp ( map_data + 2 , tmp , 4 ) ) ;
/*
2023-11-26 15:01:19 -08:00
* Test duplicate of the duplicate omitting the last 2 bytes again ( so just the middle 2 bytes )
2021-01-23 16:41:41 -08:00
*/
cli_dbgmsg ( " duplicating dup_map with shorter len \n " ) ;
dup_dup_map = fmap_duplicate ( dup_map , 0 , dup_map - > len - 2 , " offset short duplicate " ) ;
ck_assert_msg ( ! ! dup_dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_dup_map - > nested_offset = = 2 , " dup_dup_map nested_offset is incorrect: %zu " , dup_map - > nested_offset ) ;
ck_assert_msg ( dup_dup_map - > len = = 2 , " dup_dup_map len is incorrect: %zu " , dup_map - > len ) ;
2021-10-03 14:13:55 -07:00
ck_assert_msg ( dup_dup_map - > real_len = = 4 , " dup_dup_map real len is incorrect: %zu " , dup_map - > real_len ) ;
2021-01-23 16:41:41 -08:00
bread = fmap_readn ( dup_dup_map , tmp , 0 , 6 ) ;
ck_assert ( bread = = 2 ) ;
ck_assert ( 0 = = memcmp ( map_data + 2 , tmp , 2 ) ) ;
cli_dbgmsg ( " freeing dup_dup_map \n " ) ;
free_duplicate_fmap ( dup_dup_map ) ;
dup_dup_map = NULL ;
cli_dbgmsg ( " freeing dup_map \n " ) ;
free_duplicate_fmap ( dup_map ) ;
dup_map = NULL ;
cli_dbgmsg ( " freeing map \n " ) ;
cl_fmap_close ( map ) ;
}
END_TEST
START_TEST ( test_fmap_duplicate_out_of_bounds )
{
cl_fmap_t * map ;
cl_fmap_t * dup_map = NULL ;
cl_fmap_t * dup_dup_map = NULL ;
char map_data [ 6 ] = { ' a ' , ' b ' , ' c ' , ' d ' , ' e ' , ' f ' } ;
char tmp [ 6 ] ;
size_t bread = 0 ;
map = cl_fmap_open_memory ( map_data , sizeof ( map_data ) ) ;
2021-10-03 14:13:55 -07:00
ck_assert_msg ( ! ! map , " cl_fmap_open_memory failed " ) ;
2021-01-23 16:41:41 -08:00
/*
* Test 0 - byte duplicate
*/
cli_dbgmsg ( " duplicating 0 bytes of map \n " ) ;
dup_map = fmap_duplicate ( map , 0 , 0 , " zero-byte dup " ) ;
ck_assert_msg ( ! ! dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_map - > nested_offset = = 0 , " dup_map nested_offset is incorrect: %zu " , dup_map - > nested_offset ) ;
ck_assert_msg ( dup_map - > len = = 0 , " dup_map len is incorrect: %zu " , dup_map - > len ) ;
2021-10-03 14:13:55 -07:00
ck_assert_msg ( dup_map - > real_len = = 0 , " dup_map real len is incorrect: %zu " , dup_map - > real_len ) ;
2021-01-23 16:41:41 -08:00
bread = fmap_readn ( dup_map , tmp , 0 , 6 ) ;
ck_assert ( bread = = 0 ) ;
cli_dbgmsg ( " freeing dup_map \n " ) ;
free_duplicate_fmap ( dup_map ) ;
dup_map = NULL ;
/*
* Test duplicate of entire map + 1
*/
cli_dbgmsg ( " duplicating complete map + 1 byte \n " ) ;
dup_map = fmap_duplicate ( map , 0 , map - > len + 1 , " duplicate + 1 " ) ;
ck_assert_msg ( ! ! dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_map - > nested_offset = = 0 , " dup_map nested_offset is incorrect: %zu " , dup_map - > nested_offset ) ;
ck_assert_msg ( dup_map - > len = = map - > len , " dup_map len is incorrect: %zu " , dup_map - > len ) ;
ck_assert_msg ( dup_map - > real_len = = map - > len , " dup_map real len is incorrect: %zu " , dup_map - > real_len ) ;
bread = fmap_readn ( dup_map , tmp , 0 , 6 ) ;
ck_assert ( bread = = 6 ) ;
ck_assert ( 0 = = memcmp ( map_data , tmp , 6 ) ) ;
cli_dbgmsg ( " freeing dup_map \n " ) ;
free_duplicate_fmap ( dup_map ) ;
dup_map = NULL ;
/*
* Test duplicate of map at offset 4
*/
cli_dbgmsg ( " duplicating 4 bytes into map \n " ) ;
dup_map = fmap_duplicate ( map , 4 , map - > len , " offset duplicate " ) ;
ck_assert_msg ( ! ! dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_map - > nested_offset = = 4 , " dup_map nested_offset is incorrect: %zu " , dup_map - > nested_offset ) ;
ck_assert_msg ( dup_map - > len = = 2 , " dup_map len is incorrect: %zu " , dup_map - > len ) ;
ck_assert_msg ( dup_map - > real_len = = 6 , " dup_map real len is incorrect: %zu " , dup_map - > real_len ) ;
bread = fmap_readn ( dup_map , tmp , 0 , 6 ) ;
ck_assert ( bread = = 2 ) ;
ck_assert ( 0 = = memcmp ( map_data + 4 , tmp , 2 ) ) ;
/*
* Test duplicate of duplicate map , also at offset 4 ( total 8 bytes in , which is 2 bytes too far )
*/
cli_dbgmsg ( " duplicating 4 bytes into dup_map \n " ) ;
dup_dup_map = fmap_duplicate ( dup_map , 4 , dup_map - > len , " out of bounds offset duplicate " ) ;
ck_assert_msg ( NULL = = dup_dup_map , " fmap_duplicate should have failed! " ) ;
cli_dbgmsg ( " freeing dup_map \n " ) ;
free_duplicate_fmap ( dup_map ) ;
dup_map = NULL ;
/*
* Test duplicate just 2 bytes of the original
*/
cli_dbgmsg ( " duplicating map with shorter len \n " ) ;
dup_map = fmap_duplicate ( map , 0 , 2 , " short duplicate " ) ;
ck_assert_msg ( ! ! dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_map - > nested_offset = = 0 , " dup_map nested_offset is incorrect: %zu " , dup_map - > nested_offset ) ;
ck_assert_msg ( dup_map - > len = = 2 , " dup_map len is incorrect: %zu " , dup_map - > len ) ;
2021-10-03 14:13:55 -07:00
ck_assert_msg ( dup_map - > real_len = = 2 , " dup_map real len is incorrect: %zu " , dup_map - > real_len ) ;
2021-01-23 16:41:41 -08:00
bread = fmap_readn ( dup_map , tmp , 0 , 6 ) ;
ck_assert ( bread = = 2 ) ;
ck_assert ( 0 = = memcmp ( map_data , tmp , 2 ) ) ;
/* Note: Keeping the previous dup_map around for a sequence of double-dup tests. */
/*
* Test duplicate 1 bytes into the 2 - byte duplicate , requesting 2 bytes
* This should result in a 1 - byte double - dup
*/
cli_dbgmsg ( " duplicating 1 byte in, 1 too many \n " ) ;
dup_dup_map = fmap_duplicate ( dup_map , 1 , 2 , " 1 byte in, 1 too many " ) ;
ck_assert_msg ( ! ! dup_dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_dup_map - > nested_offset = = 1 , " dup_dup_map nested_offset is incorrect: %zu " , dup_dup_map - > nested_offset ) ;
ck_assert_msg ( dup_dup_map - > len = = 1 , " dup_dup_map len is incorrect: %zu " , dup_dup_map - > len ) ;
2021-10-03 14:13:55 -07:00
ck_assert_msg ( dup_dup_map - > real_len = = 2 , " dup_dup_map real len is incorrect: %zu " , dup_dup_map - > real_len ) ;
2021-01-23 16:41:41 -08:00
bread = fmap_readn ( dup_dup_map , tmp , 0 , 6 ) ;
ck_assert ( bread = = 1 ) ;
ck_assert ( 0 = = memcmp ( map_data + 1 , tmp , 1 ) ) ;
cli_dbgmsg ( " freeing dup_dup_map \n " ) ;
free_duplicate_fmap ( dup_dup_map ) ;
dup_dup_map = NULL ;
/*
* Test duplicate 2 bytes into the 2 - byte duplicate , requesting 2 bytes
* This should result in a 0 - byte double - dup
*/
cli_dbgmsg ( " duplicating 2 bytes in, 2 bytes too many \n " ) ;
dup_dup_map = fmap_duplicate ( dup_map , 2 , 2 , " 2 bytes in, 2 bytes too many " ) ;
ck_assert_msg ( ! ! dup_dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_dup_map - > nested_offset = = 2 , " dup_dup_map nested_offset is incorrect: %zu " , dup_dup_map - > nested_offset ) ;
ck_assert_msg ( dup_dup_map - > len = = 0 , " dup_dup_map len is incorrect: %zu " , dup_dup_map - > len ) ;
2021-10-03 14:13:55 -07:00
ck_assert_msg ( dup_dup_map - > real_len = = 2 , " dup_dup_map real len is incorrect: %zu " , dup_dup_map - > real_len ) ;
2021-01-23 16:41:41 -08:00
bread = fmap_readn ( dup_dup_map , tmp , 0 , 6 ) ;
ck_assert ( bread = = 0 ) ;
cli_dbgmsg ( " freeing dup_dup_map \n " ) ;
free_duplicate_fmap ( dup_dup_map ) ;
dup_dup_map = NULL ;
/*
* Test duplicate 3 bytes into the 2 - byte duplicate , requesting 2 bytes
*/
cli_dbgmsg ( " duplicating 0-byte of duplicate \n " ) ;
dup_dup_map = fmap_duplicate ( dup_map , 3 , 2 , " 2 bytes in, 3 bytes too many " ) ;
ck_assert_msg ( NULL = = dup_dup_map , " fmap_duplicate should have failed! " ) ;
/* Ok, we're done with this dup_map */
cli_dbgmsg ( " freeing dup_map \n " ) ;
free_duplicate_fmap ( dup_map ) ;
dup_map = NULL ;
cli_dbgmsg ( " freeing map \n " ) ;
cl_fmap_close ( map ) ;
}
END_TEST
2021-10-03 14:13:55 -07:00
# define FMAP_TEST_STRING_PART_1 "Hello, World!\0"
# define FMAP_TEST_STRING_PART_2 "Don't be a stranger!\nBe my friend!\0"
# define FMAP_TEST_STRING FMAP_TEST_STRING_PART_1 FMAP_TEST_STRING_PART_2
/**
* @ brief convenience function for testing
*
* the map data should :
* - be at least 6 bytes long
* - include a ' \n ' in the middle .
* - plus one ' \0 ' after that .
* - and end with ' \0 ' .
*
* @ param map The map .
* @ param map_data A copy of the expected map data .
* @ param map_data_len The length of the expected map data .
*/
static void fmap_api_tests ( cl_fmap_t * map , const char * map_data , size_t map_data_len , const char * msg )
{
char * tmp = NULL ;
size_t bread = 0 ;
const char * ptr , * ptr_2 ;
size_t at ;
size_t lenout ;
const char * ptr_after_newline ;
size_t offset_after_newline ;
tmp = calloc ( map_data_len + 1 , 1 ) ;
ck_assert_msg ( tmp ! = NULL , " %s " , msg ) ;
/*
* Test fmap_readn ( )
*/
bread = fmap_readn ( map , tmp , 0 , 5 ) ;
ck_assert_msg ( bread = = 5 , " %s: unexpected # bytes read: %zu " , msg , bread ) ;
ck_assert_msg ( 0 = = memcmp ( map_data , tmp , 5 ) , " %s: %s != %s " , msg , map_data , tmp ) ;
/*
* Test fmap_need_offstr ( )
*/
ptr = fmap_need_offstr ( map , 0 , 5 ) ;
ck_assert_msg ( ptr = = NULL , " %s: fmap_need_offstr should not have found a string terminator in the first 6 bytes: %s " , msg , ptr ) ;
/*
* Test fmap_need_offstr ( )
*/
// This API must find a NULL-terminating byte
ptr = fmap_need_offstr ( map , 0 , map_data_len + 5 ) ; // request at least as much as exists.
ck_assert_msg ( ptr ! = NULL , " %s: fmap_need_offstr failed to find a string. " , msg ) ;
ck_assert_msg ( * ptr = = map_data [ 0 ] , " %s: %c != %c " , msg , * ptr , map_data [ 0 ] ) ;
/*
* Test fmap_gets ( )
*/
// first lets find the offset of the '\n' in this data.
ptr_after_newline = memchr ( map_data , ' \n ' , map_data_len ) ;
ck_assert_msg ( ptr_after_newline ! = NULL , " %s " , msg ) ;
offset_after_newline = ( size_t ) ptr_after_newline - ( size_t ) map_data + 1 ;
// This API will stop after newline or EOF, but not a NULL byte.
memset ( tmp , 0xff , map_data_len + 1 ) ; // pre-load `tmp` with 0xff so our NULL check later is guaranteed to be meaningful.
at = 3 ; // start at offset 3
ptr = fmap_gets ( map , tmp , & at , map_data_len + 1 ) ;
ck_assert_msg ( ptr = = tmp , " %s: %zu != %zu " , msg , ( size_t ) ptr , ( size_t ) tmp ) ;
ck_assert_msg ( at = = offset_after_newline , " %s: %zu != %zu " , msg , at , offset_after_newline ) ; // at should point to the character after '\n'
ck_assert_msg ( 0 = = memcmp ( map_data + 3 , tmp , offset_after_newline - 3 ) , " %s: fmap_gets read: %s " , msg , tmp ) ;
ck_assert_msg ( tmp [ offset_after_newline - 3 ] = = ' \0 ' , " %s: data read by fmap_gets, but that value is '0x%02x' " , msg , tmp [ offset_after_newline - 3 ] ) ; // should have a null terminator afterwards.
memset ( tmp , 0xff , map_data_len + 1 ) ; // pre-load `tmp` with 0xff so our NULL check later is guaranteed to be meaningful.
// continue from previous read, ..
ptr = fmap_gets ( map , tmp , & at , map_data_len + 1 ) ; // read the rest of the string
ck_assert_msg ( ptr = = tmp , " %s: fmap_gets should return dst pointer but returned: %zu " , msg , ( size_t ) ptr ) ;
ck_assert_msg ( at = = map_data_len , " %s: %zu != %zu " , msg , at , map_data_len ) ; // at should point just past end of string
ck_assert_msg ( 0 = = memcmp ( map_data + offset_after_newline , tmp , map_data_len - offset_after_newline ) , " %s " , msg ) ;
ck_assert_msg ( tmp [ map_data_len - offset_after_newline ] = = ' \0 ' , " %s: data read by fmap_gets, but that value is '0x%02x' " , msg , tmp [ map_data_len - offset_after_newline ] ) ; // should have a null terminator afterwards.
/*
* Test fmap_need_off_once_len ( )
*/
ptr = fmap_need_off_once_len ( map , 0 , map_data_len + 50 , & lenout ) ; // request more bytes than is available
ck_assert_msg ( ptr ! = NULL , " %s: failed to get pointer into map :( " , msg ) ;
ck_assert_msg ( lenout = = map_data_len , " %s: %zu != %zu " , msg , lenout , map_data_len ) ;
ck_assert_msg ( 0 = = memcmp ( ptr , map_data , offset_after_newline ) , " %s " , msg ) ;
/*
* Test fmap_need_off_once ( )
*/
ptr = fmap_need_off_once ( map , 0 , map_data_len + 50 ) ; // request more bytes than is available
ck_assert_msg ( ptr = = NULL , " %s: should have failed to get pointer into map :( " , msg ) ;
ptr = fmap_need_off_once ( map , 0 , offset_after_newline ) ;
ck_assert_msg ( ptr ! = NULL , " %s: failed to get pointer into map :( " , msg ) ;
ck_assert_msg ( 0 = = memcmp ( ptr , map_data , offset_after_newline ) , " %s " , msg ) ;
/*
* Test fmap_need_ptr_once ( )
*/
ptr_2 = fmap_need_ptr_once ( map , ptr , map_data_len + 50 ) ; // request more bytes than is available
ck_assert_msg ( ptr_2 = = NULL , " %s: should have failed to get pointer into map :( " , msg ) ;
ptr_2 = fmap_need_ptr_once ( map , ptr , offset_after_newline ) ;
ck_assert_msg ( ptr_2 ! = NULL , " %s: failed to get pointer into map :( " , msg ) ;
ck_assert_msg ( 0 = = memcmp ( ptr_2 , map_data , offset_after_newline ) , " %s " , msg ) ;
free ( tmp ) ;
}
START_TEST ( test_fmap_assorted_api )
{
cl_fmap_t * mem_based_map = NULL ;
cl_fmap_t * fd_based_map = NULL ;
cl_fmap_t * fd_based_dup_map = NULL ;
cl_fmap_t * dup_map = NULL ;
char * fmap_dump_filepath = NULL ;
int fmap_dump_fd = - 1 ;
char * dup_fmap_dump_filepath = NULL ;
int dup_fmap_dump_fd = - 1 ;
mem_based_map = cl_fmap_open_memory ( FMAP_TEST_STRING , sizeof ( FMAP_TEST_STRING ) ) ;
ck_assert_msg ( ! ! mem_based_map , " cl_fmap_open_memory failed " ) ;
cli_dbgmsg ( " created fmap from memory/buffer \n " ) ;
/*
* Test a few things on the original map .
*/
fmap_api_tests ( mem_based_map , FMAP_TEST_STRING , sizeof ( FMAP_TEST_STRING ) , " mem map " ) ;
/*
* Test fmap_dump_to_file ( )
*/
fmap_dump_to_file ( mem_based_map , NULL , NULL , & fmap_dump_filepath , & fmap_dump_fd , 0 , mem_based_map - > len ) ;
ck_assert_msg ( fmap_dump_fd ! = - 1 , " fmap_dump_fd failed " ) ;
cli_dbgmsg ( " dumped map to %s \n " , fmap_dump_filepath ) ;
2025-06-08 01:12:33 -04:00
fd_based_map = fmap_new ( fmap_dump_fd , 0 , 0 , NULL , NULL ) ; // using fmap_new() instead of cl_fmap_open_handle() because I don't want to have to stat the file to figure out the len. fmap_new() does that for us.
2021-10-03 14:13:55 -07:00
ck_assert_msg ( ! ! fd_based_map , " cl_fmap_open_handle failed " ) ;
cli_dbgmsg ( " created fmap from file descriptor \n " ) ;
/*
2023-11-26 15:01:19 -08:00
* Test those same things on an fmap created with an fd that is a dumped copy of the original map .
2021-10-03 14:13:55 -07:00
*/
fmap_api_tests ( fd_based_map , FMAP_TEST_STRING , sizeof ( FMAP_TEST_STRING ) , " handle map " ) ;
/*
* Test duplicate of mem - based map at an offset
*/
cli_dbgmsg ( " duplicating part way into mem-based fmap \n " ) ;
dup_map = fmap_duplicate (
mem_based_map ,
sizeof ( FMAP_TEST_STRING_PART_1 ) - 1 , // minus automatic null terminator
mem_based_map - > len - ( sizeof ( FMAP_TEST_STRING_PART_1 ) - 1 ) ,
" offset duplicate " ) ;
ck_assert_msg ( ! ! dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_map - > nested_offset = = sizeof ( FMAP_TEST_STRING_PART_1 ) - 1 , " %zu != %zu " , dup_map - > nested_offset , sizeof ( FMAP_TEST_STRING_PART_1 ) - 1 ) ;
ck_assert_msg ( dup_map - > len = = sizeof ( FMAP_TEST_STRING_PART_2 ) , " %zu != %zu " , dup_map - > len , sizeof ( FMAP_TEST_STRING_PART_2 ) ) ;
ck_assert_msg ( dup_map - > real_len = = sizeof ( FMAP_TEST_STRING ) , " %zu != %zu " , dup_map - > real_len , sizeof ( FMAP_TEST_STRING ) ) ;
/*
2023-11-26 15:01:19 -08:00
* Test those same things on an fmap created with an fd that is a dumped copy of the original map .
2021-10-03 14:13:55 -07:00
*/
fmap_api_tests ( dup_map , FMAP_TEST_STRING_PART_2 , sizeof ( FMAP_TEST_STRING_PART_2 ) , " nested mem map " ) ;
/* Ok, we're done with this dup_map */
cli_dbgmsg ( " freeing dup_map \n " ) ;
free_duplicate_fmap ( dup_map ) ;
dup_map = NULL ;
/*
* Test duplicate of handle - based map at an offset
*/
cli_dbgmsg ( " duplicating part way into handle-based fmap \n " ) ;
dup_map = fmap_duplicate (
fd_based_map ,
sizeof ( FMAP_TEST_STRING_PART_1 ) - 1 , // minus automatic null terminator
fd_based_map - > len - ( sizeof ( FMAP_TEST_STRING_PART_1 ) - 1 ) ,
" offset duplicate " ) ;
ck_assert_msg ( ! ! dup_map , " fmap_duplicate failed " ) ;
ck_assert_msg ( dup_map - > nested_offset = = sizeof ( FMAP_TEST_STRING_PART_1 ) - 1 , " %zu != %zu " , dup_map - > nested_offset , sizeof ( FMAP_TEST_STRING_PART_1 ) - 1 ) ;
ck_assert_msg ( dup_map - > len = = sizeof ( FMAP_TEST_STRING_PART_2 ) , " %zu != %zu " , dup_map - > len , sizeof ( FMAP_TEST_STRING_PART_2 ) ) ;
ck_assert_msg ( dup_map - > real_len = = sizeof ( FMAP_TEST_STRING ) , " %zu != %zu " , dup_map - > real_len , sizeof ( FMAP_TEST_STRING ) ) ;
/*
2023-11-26 15:01:19 -08:00
* Test those same things on an fmap created with an fd that is a dumped copy of the original map .
2021-10-03 14:13:55 -07:00
*/
fmap_api_tests ( dup_map , FMAP_TEST_STRING_PART_2 , sizeof ( FMAP_TEST_STRING_PART_2 ) , " nested handle map " ) ;
/*
* Test fmap_dump_to_file ( ) on a nested fmap
*/
fmap_dump_to_file ( dup_map , NULL , NULL , & dup_fmap_dump_filepath , & dup_fmap_dump_fd , 0 , dup_map - > len ) ;
ck_assert_msg ( dup_fmap_dump_fd ! = - 1 , " fmap_dump_fd failed " ) ;
cli_dbgmsg ( " dumped map to %s \n " , dup_fmap_dump_filepath ) ;
/* Ok, we're done with this dup_map */
cli_dbgmsg ( " freeing dup_map \n " ) ;
free_duplicate_fmap ( dup_map ) ;
dup_map = NULL ;
2024-04-10 16:31:46 -07:00
/* We can close the fd-based map now that we're done with its duplicate */
2021-10-03 14:13:55 -07:00
cl_fmap_close ( fd_based_map ) ;
fd_based_map = NULL ;
close ( fmap_dump_fd ) ;
fmap_dump_fd = - 1 ;
cli_unlink ( fmap_dump_filepath ) ;
free ( fmap_dump_filepath ) ;
fmap_dump_filepath = NULL ;
/* And we can close the original mem-based map as well */
cl_fmap_close ( mem_based_map ) ;
mem_based_map = NULL ;
/*
* Let ' s make an fmap of the dumped nested map , and run the tests to verify that everything is as expected .
*/
2025-06-08 01:12:33 -04:00
fd_based_dup_map = fmap_new ( dup_fmap_dump_fd , 0 , 0 , NULL , NULL ) ; // using fmap_new() instead of cl_fmap_open_handle() because I don't want to have to stat the file to figure out the len. fmap_new() does that for us.
2021-10-03 14:13:55 -07:00
ck_assert_msg ( ! ! fd_based_dup_map , " cl_fmap_open_handle failed " ) ;
cli_dbgmsg ( " created fmap from file descriptor \n " ) ;
/*
2023-11-26 15:01:19 -08:00
* Test those same things on an fmap created with an fd that is a dumped copy of the original map .
2021-10-03 14:13:55 -07:00
*/
fmap_api_tests ( fd_based_dup_map , FMAP_TEST_STRING_PART_2 , sizeof ( FMAP_TEST_STRING_PART_2 ) , " dumped nested handle map " ) ;
/* Ok, we're done with the fmap based on the dumped dup_map */
cli_dbgmsg ( " freeing fmap of dumped dup_map \n " ) ;
cl_fmap_close ( fd_based_dup_map ) ;
fd_based_dup_map = NULL ;
close ( dup_fmap_dump_fd ) ;
dup_fmap_dump_fd = - 1 ;
cli_unlink ( dup_fmap_dump_filepath ) ;
free ( dup_fmap_dump_filepath ) ;
dup_fmap_dump_filepath = NULL ;
}
END_TEST
2008-04-07 13:43:16 +00:00
static Suite * test_cl_suite ( void )
2008-03-13 10:44:34 +00:00
{
2020-01-15 08:14:23 -08:00
Suite * s = suite_create ( " cl_suite " ) ;
TCase * tc_cl = tcase_create ( " cl_api " ) ;
TCase * tc_cl_scan = tcase_create ( " cl_scan_api " ) ;
2015-03-24 12:06:57 -04:00
char * user_timeout = NULL ;
2018-12-03 12:40:13 -05:00
int expect = expected_testfiles ;
suite_add_tcase ( s , tc_cl ) ;
2022-08-30 15:51:13 -07:00
tcase_add_checked_fixture ( tc_cl , cl_setup , cl_teardown ) ;
2008-03-13 10:44:34 +00:00
tcase_add_test ( tc_cl , test_cl_free ) ;
tcase_add_test ( tc_cl , test_cl_build ) ;
tcase_add_test ( tc_cl , test_cl_debug ) ;
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
# ifndef _WIN32
2008-03-13 10:44:34 +00:00
tcase_add_test ( tc_cl , test_cl_retdbdir ) ;
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
# endif
2008-03-13 10:44:34 +00:00
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 ) ;
2011-06-15 12:21:50 +03:00
suite_add_tcase ( s , tc_cl_scan ) ;
2018-12-03 12:40:13 -05:00
tcase_add_checked_fixture ( tc_cl_scan , engine_setup , engine_teardown ) ;
2020-01-15 08:14:23 -08:00
2013-11-11 18:00:58 -05:00
if ( get_fpu_endian ( ) = = FPU_ENDIAN_UNKNOWN )
expect - - ;
2014-03-18 17:23:27 -04:00
expect - = skip_files ( ) ;
2013-11-04 12:14:19 -05:00
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 ) ;
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
# ifndef _WIN32
2013-11-04 12:14:19 -05:00
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 ) ;
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
# endif
# ifdef HAVE_SYS_MMAN_H
2013-11-04 12:14:19 -05:00
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 ) ;
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
# endif
2021-01-23 16:41:41 -08:00
tcase_add_loop_test ( tc_cl_scan , test_fmap_duplicate , 0 , expect ) ;
tcase_add_loop_test ( tc_cl_scan , test_fmap_duplicate_out_of_bounds , 0 , expect ) ;
2021-10-03 14:13:55 -07:00
tcase_add_loop_test ( tc_cl_scan , test_fmap_assorted_api , 0 , expect ) ;
2015-03-24 12:06:57 -04:00
user_timeout = getenv ( " T " ) ;
if ( user_timeout ) {
int timeout = atoi ( user_timeout ) ;
tcase_set_timeout ( tc_cl_scan , timeout ) ;
2018-12-03 12:40:13 -05:00
printf ( " Using test case timeout of %d seconds set by user \n " , timeout ) ;
2015-07-28 16:17:59 -04:00
} else {
2018-12-03 12:40:13 -05:00
printf ( " Using default test timeout; alter by setting 'T' env var (in seconds) \n " ) ;
2015-03-24 12:06:57 -04:00
}
2008-03-13 10:44:34 +00:00
return s ;
}
2018-12-03 12:40:13 -05:00
static uint8_t le_data [ 4 ] = { 0x67 , 0x45 , 0x23 , 0x01 } ;
static int32_t le_expected [ 4 ] = { 0x01234567 , 0x67012345 , 0x45670123 , 0x23456701 } ;
uint8_t * data = NULL ;
uint8_t * data2 = NULL ;
2008-04-07 13:43:16 +00:00
# define DATA_REP 100
static void data_setup ( void )
{
2018-12-03 12:40:13 -05:00
uint8_t * p ;
size_t i ;
data = malloc ( sizeof ( le_data ) * DATA_REP ) ;
data2 = malloc ( sizeof ( le_data ) * DATA_REP ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ! ! data , " unable to allocate memory for fixture " ) ;
ck_assert_msg ( ! ! data2 , " unable to allocate memory for fixture " ) ;
2018-12-03 12:40:13 -05:00
p = data ;
/* make multiple copies of le_data, we need to run readint tests in a loop, so we need
2022-02-16 00:13:55 +01:00
* to give it some data to run it on */
2018-12-03 12:40:13 -05:00
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 ) ) ;
2008-04-07 13:43:16 +00:00
}
static void data_teardown ( void )
{
2018-12-03 12:40:13 -05:00
free ( data ) ;
free ( data2 ) ;
2008-04-07 13:43:16 +00:00
}
/* test reading with different alignments, _i is parameter from tcase_add_loop_test */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cli_readint16 )
2008-04-07 14:42:05 +00:00
{
size_t j ;
int16_t value ;
/* read 2 bytes apart, start is not always aligned*/
2018-12-03 12:40:13 -05:00
for ( j = _i ; j < = DATA_REP * sizeof ( le_data ) - 2 ; j + = 2 ) {
value = le_expected [ j & 3 ] ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( cli_readint16 ( & data [ j ] ) = = value , " (1) data read must be little endian " ) ;
2008-04-07 14:42:05 +00:00
}
/* read 2 bytes apart, always aligned*/
2018-12-03 12:40:13 -05:00
for ( j = 0 ; j < = DATA_REP * sizeof ( le_data ) - 2 ; j + = 2 ) {
value = le_expected [ j & 3 ] ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( cli_readint16 ( & data [ j ] ) = = value , " (2) data read must be little endian " ) ;
2008-04-07 14:42:05 +00:00
}
}
END_TEST
/* test reading with different alignments, _i is parameter from tcase_add_loop_test */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cli_readint32 )
2008-04-07 13:43:16 +00:00
{
size_t j ;
2018-12-03 12:40:13 -05:00
int32_t value = le_expected [ _i & 3 ] ;
2008-04-07 13:43:16 +00:00
/* read 4 bytes apart, start is not always aligned*/
2018-12-03 12:40:13 -05:00
for ( j = _i ; j < DATA_REP * sizeof ( le_data ) - 4 ; j + = 4 ) {
2020-01-15 08:14:23 -08:00
ck_assert_msg ( cli_readint32 ( & data [ j ] ) = = value , " (1) data read must be little endian " ) ;
2008-04-07 13:43:16 +00:00
}
value = le_expected [ 0 ] ;
/* read 4 bytes apart, always aligned*/
2018-12-03 12:40:13 -05:00
for ( j = 0 ; j < DATA_REP * sizeof ( le_data ) - 4 ; j + = 4 ) {
2020-01-15 08:14:23 -08:00
ck_assert_msg ( cli_readint32 ( & data [ j ] ) = = value , " (2) data read must be little endian " ) ;
2008-04-07 13:43:16 +00:00
}
}
END_TEST
/* test writing with different alignments, _i is parameter from tcase_add_loop_test */
2018-12-03 12:40:13 -05:00
START_TEST ( test_cli_writeint32 )
2008-04-07 13:43:16 +00:00
{
size_t j ;
/* write 4 bytes apart, start is not always aligned*/
2018-12-03 12:40:13 -05:00
for ( j = _i ; j < DATA_REP * sizeof ( le_data ) - 4 ; j + = 4 ) {
2008-04-07 13:43:16 +00:00
cli_writeint32 ( & data2 [ j ] , 0x12345678 ) ;
}
2018-12-03 12:40:13 -05:00
for ( j = _i ; j < DATA_REP * sizeof ( le_data ) - 4 ; j + = 4 ) {
2020-01-15 08:14:23 -08:00
ck_assert_msg ( cli_readint32 ( & data2 [ j ] ) = = 0x12345678 , " write/read mismatch " ) ;
2008-04-07 13:43:16 +00:00
}
/* write 4 bytes apart, always aligned*/
2018-12-03 12:40:13 -05:00
for ( j = 0 ; j < DATA_REP * sizeof ( le_data ) - 4 ; j + = 4 ) {
2008-04-07 13:43:16 +00:00
cli_writeint32 ( & data2 [ j ] , 0x12345678 ) ;
}
2018-12-03 12:40:13 -05:00
for ( j = 0 ; j < DATA_REP * sizeof ( le_data ) - 4 ; j + = 4 ) {
2020-01-15 08:14:23 -08:00
ck_assert_msg ( cli_readint32 ( & data2 [ j ] ) = = 0x12345678 , " write/read mismatch " ) ;
2008-04-07 13:43:16 +00:00
}
}
END_TEST
2009-01-27 10:57:54 +00:00
static struct dsig_test {
const char * md5 ;
const char * dsig ;
int result ;
2018-12-03 12:40:13 -05:00
} dsig_tests [ ] = {
{ " ae307614434715274c60854c931a26de " , " 60uhCFmiN48J8r6c7coBv9Q1mehAWEGh6GPYA+60VhQcuXfb0iV1O+sCEyMiRXt/iYF6vXtPXHVd6DiuZ4Gfrry7sVQqNTt3o1/KwU1rc0l5FHgX/nC99fdr/fjaFtinMtRnUXHLeu0j8e6HK+7JLBpD37fZ60GC9YY86EclYGe " ,
CL_SUCCESS } ,
2009-01-27 10:57:54 +00:00
{ " 96b7feb3b2a863846438809fe481906f " , " Zh5gmf09Zfj6V4gmRKu/NURzhFiE9VloI7w1G33BgDdGSs0Xhscx6sjPUpFSCPsjOalyS4L8q7RS+NdGvNCsLymiIH6RYItlOZsygFhcGuH4jt15KAaAkvEg2TwmqR8z41nUaMlZ0c8q1MXYCLvQJyFARsfzIxS3PAoN2Y3HPoe " ,
2018-12-03 12:40:13 -05:00
CL_SUCCESS } ,
2009-01-27 10:57:54 +00:00
{ " ae307614434715274c60854c931a26de " , " Zh5gmf09Zfj6V4gmRKu/NURzhFiE9VloI7w1G33BgDdGSs0Xhscx6sjPUpFSCPsjOalyS4L8q7RS+NdGvNCsLymiIH6RYItlOZsygFhcGuH4jt15KAaAkvEg2TwmqR8z41nUaMlZ0c8q1MXYCLvQJyFARsfzIxS3PAoN2Y3HPoe " ,
2018-12-03 12:40:13 -05:00
CL_EVERIFY } ,
2009-01-27 10:57:54 +00:00
{ " 96b7feb3b2a863846438809fe481906f " , " 60uhCFmiN48J8r6c7coBv9Q1mehAWEGh6GPYA+60VhQcuXfb0iV1O+sCEyMiRXt/iYF6vXtPXHVd6DiuZ4Gfrry7sVQqNTt3o1/KwU1rc0l5FHgX/nC99fdr/fjaFtinMtRnUXHLeu0j8e6HK+7JLBpD37fZ60GC9YY86EclYGe " ,
2018-12-03 12:40:13 -05:00
CL_EVERIFY } ,
2009-01-27 10:57:54 +00:00
{ " ae307614434715274060854c931a26de " , " 60uhCFmiN48J8r6c7coBv9Q1mehAWEGh6GPYA+60VhQcuXfb0iV1O+sCEyMiRXt/iYF6vXtPXHVd6DiuZ4Gfrry7sVQqNTt3o1/KwU1rc0l5FHgX/nC99fdr/fjaFtinMtRnUXHLeu0j8e6HK+7JLBpD37fZ60GC9YY86EclYGe " ,
2018-12-03 12:40:13 -05:00
CL_EVERIFY } ,
2009-01-27 10:57:54 +00:00
{ " ae307614434715274c60854c931a26de " , " 60uhCFmiN48J8r6c7coBv9Q1mehAWEGh6GPYA+60VhQcuXfb0iV1O+sCEyMiRXt/iYF6vXtPXHVd6DiuZ4Gfrry7sVQqNTt3o1/KwU1rc0l5FHgX/nC99fdr/fjaatinMtRnUXHLeu0j8e6HK+7JLBpD37fZ60GC9YY86EclYGe " ,
2018-12-03 12:40:13 -05:00
CL_EVERIFY } ,
2009-01-27 10:57:54 +00:00
{ " 96b7feb3b2a863846438809fe481906f " , " Zh5gmf09Zfj6V4gmRKu/NURzhFiE9VloI7w1G33BgDdGSs0Xhscx6sjPUpFSCPsjOalyS4L8q7RS+NdGvNCsLymiIH6RYItlOZsygFhcGuH4jt15KAaAkvEg2TwmqR8z41nUaMlZ0c8q1MYYCLvQJyFARsfzIxS3PAoN2Y3HPoe " ,
2018-12-03 12:40:13 -05:00
CL_EVERIFY } ,
{ " ge307614434715274c60854c931a26dee " , " 60uhCFmiN48J8r6c7coBv9Q1mehAWEGh6GPYA+60VhQcuXfb0iV1O+sCEyMiRXt/iYF6vXtPXHVd6DiuZ4Gfrry7sVQqNTt3o1/KwU1rc0l5FHgX/nC99fdr/fjaFtinMtRnUXHLeu0j8e6HK+7JLBpD37fZ60GC9YY86EclYGe " ,
CL_EVERIFY } ,
{ " ae307614434715274c60854c931a26de " , " 60uhCFmiN48J8r6c7coBv9Q1mehAWEGh6GPYA+60VhQcuXfb0iV1O+sCEyMiRXt/iYF6vXtPXHVd6DiuZ4Gfrry7sVQqNTt3o1/KwU1rc0l5FHgX/nC99fdr/fjaFtinMtRnUXHLeu0j8e6HK+7JLBpD37fZ60GC9YY86EclYGee " ,
CL_EVERIFY } ,
{ " ae307614434715274c60854c931a26de " , " 60uhCFmiN48J8r6c7coBv9Q1mehAWEGh6GPYA+ " ,
CL_EVERIFY } } ;
static const size_t dsig_tests_cnt = sizeof ( dsig_tests ) / sizeof ( dsig_tests [ 0 ] ) ;
START_TEST ( test_cli_dsig )
2009-01-27 10:57:54 +00:00
{
2020-01-15 08:14:23 -08:00
ck_assert_msg ( cli_versig ( dsig_tests [ _i ] . md5 , dsig_tests [ _i ] . dsig ) = = dsig_tests [ _i ] . result ,
2020-02-29 18:28:39 -05:00
" digital signature verification test failed " ) ;
2009-01-27 10:57:54 +00:00
}
END_TEST
2009-02-18 14:54:16 +00:00
static uint8_t tv1 [ 3 ] = {
2018-12-03 12:40:13 -05:00
0x61 , 0x62 , 0x63 } ;
2009-02-18 14:54:16 +00:00
static uint8_t tv2 [ 56 ] = {
2018-12-03 12:40:13 -05:00
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 } ;
2009-02-18 14:54:16 +00:00
static uint8_t res256 [ 3 ] [ SHA256_HASH_SIZE ] = {
2018-12-03 12:40:13 -05:00
{ 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 } } ;
2025-06-03 19:03:20 -04:00
START_TEST ( test_sha2_256 )
2009-02-18 14:54:16 +00:00
{
2025-06-03 19:03:20 -04:00
void * sha2_256 ;
uint8_t h_sha2_256 [ SHA256_HASH_SIZE ] ;
2009-02-18 14:54:16 +00:00
uint8_t buf [ 1000 ] ;
int i ;
2018-12-03 12:40:13 -05:00
memset ( buf , 0x61 , sizeof ( buf ) ) ;
2009-02-18 14:54:16 +00:00
2025-06-03 19:03:20 -04:00
cl_sha256 ( tv1 , sizeof ( tv1 ) , h_sha2_256 , NULL ) ;
ck_assert_msg ( ! memcmp ( h_sha2_256 , res256 [ 0 ] , sizeof ( h_sha2_256 ) ) , " sha2-256 test vector #1 failed " ) ;
2009-02-18 14:54:16 +00:00
2025-06-03 19:03:20 -04:00
cl_sha256 ( tv2 , sizeof ( tv2 ) , h_sha2_256 , NULL ) ;
ck_assert_msg ( ! memcmp ( h_sha2_256 , res256 [ 1 ] , sizeof ( h_sha2_256 ) ) , " sha2-256 test vector #2 failed " ) ;
2009-02-18 14:54:16 +00:00
2025-06-03 19:03:20 -04:00
sha2_256 = cl_hash_init ( " sha2-256 " ) ;
ck_assert_msg ( sha2_256 ! = NULL , " Could not create EVP_MD_CTX for sha2-256 " ) ;
2014-02-13 13:05:50 -05:00
2009-02-18 14:54:16 +00:00
for ( i = 0 ; i < 1000 ; i + + )
2025-06-03 19:03:20 -04:00
cl_update_hash ( sha2_256 , buf , sizeof ( buf ) ) ;
cl_finish_hash ( sha2_256 , h_sha2_256 ) ;
ck_assert_msg ( ! memcmp ( h_sha2_256 , res256 [ 2 ] , sizeof ( h_sha2_256 ) ) , " sha2-256 test vector #3 failed " ) ;
2009-02-18 14:54:16 +00:00
}
END_TEST
2019-03-02 13:05:17 -05:00
START_TEST ( test_sanitize_path )
{
2020-08-08 21:02:47 -07:00
const char * unsanitized = NULL ;
char * sanitized = NULL ;
char * sanitized_base = NULL ;
const char * expected = NULL ;
const char * expected_base = NULL ;
2019-03-02 13:05:17 -05:00
unsanitized = " " ;
2020-08-08 21:02:47 -07:00
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
ck_assert_msg ( NULL = = sanitized , " Expected: NULL, Found: \" %s \" " , sanitized ) ;
unsanitized = " " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
ck_assert_msg ( NULL = = sanitized , " Expected: NULL, Found: \" %s \" " , sanitized ) ;
ck_assert_msg ( NULL = = sanitized_base , " Expected: NULL, Found: \" %s \" " , sanitized_base ) ;
unsanitized = NULL ;
sanitized = cli_sanitize_filepath ( unsanitized , 0 , NULL ) ;
ck_assert_msg ( NULL = = sanitized , " Expected: NULL, Found: \" %s \" " , sanitized ) ;
2019-03-02 13:05:17 -05:00
unsanitized = NULL ;
2020-08-08 21:02:47 -07:00
sanitized = cli_sanitize_filepath ( unsanitized , 0 , & sanitized_base ) ;
ck_assert_msg ( NULL = = sanitized , " Expected: NULL, Found: \" %s \" " , sanitized ) ;
ck_assert_msg ( NULL = = sanitized_base , " Expected: NULL, Found: \" %s \" " , sanitized_base ) ;
2019-03-02 13:05:17 -05:00
unsanitized = NULL ;
2020-08-08 21:02:47 -07:00
sanitized = cli_sanitize_filepath ( unsanitized , 50 , NULL ) ;
ck_assert_msg ( NULL = = sanitized , " Expected: NULL, Found: \" %s \" " , sanitized ) ;
unsanitized = NULL ;
sanitized = cli_sanitize_filepath ( unsanitized , 50 , & sanitized_base ) ;
ck_assert_msg ( NULL = = sanitized , " Expected: NULL, Found: \" %s \" " , sanitized ) ;
ck_assert_msg ( NULL = = sanitized_base , " Expected: NULL, Found: \" %s \" " , sanitized_base ) ;
unsanitized = " badlen " ;
sanitized = cli_sanitize_filepath ( unsanitized , 0 , NULL ) ;
ck_assert_msg ( NULL = = sanitized , " Expected: NULL, Found: \" %s \" " , sanitized ) ;
2019-03-02 13:05:17 -05:00
unsanitized = " badlen " ;
2020-08-08 21:02:47 -07:00
sanitized = cli_sanitize_filepath ( unsanitized , 0 , & sanitized_base ) ;
ck_assert_msg ( NULL = = sanitized , " Expected: NULL, Found: \" %s \" " , sanitized ) ;
ck_assert_msg ( NULL = = sanitized_base , " Expected: NULL, Found: \" %s \" " , sanitized_base ) ;
unsanitized = " .. " PATHSEP ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
ck_assert_msg ( NULL = = sanitized , " Expected: NULL, Found: \" %s \" " , sanitized ) ;
2019-03-02 13:05:17 -05:00
unsanitized = " .. " PATHSEP ;
2020-08-08 21:02:47 -07:00
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
ck_assert_msg ( NULL = = sanitized , " Expected: NULL, Found: \" %s \" " , sanitized ) ;
ck_assert_msg ( NULL = = sanitized_base , " Expected: NULL, Found: \" %s \" " , sanitized_base ) ;
2019-03-02 13:05:17 -05:00
unsanitized = " . " PATHSEP ;
2020-08-08 21:02:47 -07:00
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
ck_assert_msg ( NULL = = sanitized , " Expected: NULL, Found: \" %s \" " , sanitized ) ;
unsanitized = " . " PATHSEP ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
ck_assert_msg ( NULL = = sanitized , " Expected: NULL, Found: \" %s \" " , sanitized ) ;
ck_assert_msg ( NULL = = sanitized_base , " Expected: NULL, Found: \" %s \" " , sanitized_base ) ;
2019-03-02 13:05:17 -05:00
unsanitized = PATHSEP ;
2020-08-08 21:02:47 -07:00
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( NULL = = sanitized , " sanitize_path: sanitized path should have been NULL (3) " ) ;
2019-03-02 13:05:17 -05:00
2020-08-08 21:02:47 -07:00
unsanitized = PATHSEP ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
ck_assert_msg ( NULL = = sanitized , " Expected: NULL, Found: \" %s \" " , sanitized ) ;
ck_assert_msg ( NULL = = sanitized_base , " Expected: NULL, Found: \" %s \" " , sanitized_base ) ;
2019-03-02 13:05:17 -05:00
unsanitized = " .. " PATHSEP " relative_bad_1 " ;
2020-08-08 21:02:47 -07:00
expected = " relative_bad_1 " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
2020-01-15 08:14:23 -08:00
ck_assert ( NULL ! = sanitized ) ;
2020-08-08 21:02:47 -07:00
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
free ( sanitized ) ;
unsanitized = " .. " PATHSEP " relative_bad_1 " ;
expected = " relative_bad_1 " ;
expected_base = " relative_bad_1 " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
ck_assert ( NULL ! = sanitized ) ;
ck_assert ( NULL ! = sanitized_base ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
ck_assert_msg ( ! strcmp ( expected_base , sanitized_base ) , " Expected: \" %s \" , Found: \" %s \" " , expected_base , sanitized_base ) ;
2019-03-02 13:05:17 -05:00
free ( sanitized ) ;
unsanitized = " relative " PATHSEP " .. " PATHSEP " good " ;
2020-08-08 21:02:47 -07:00
expected = " relative " PATHSEP " .. " PATHSEP " good " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
2020-01-15 08:14:23 -08:00
ck_assert ( NULL ! = sanitized ) ;
2020-08-08 21:02:47 -07:00
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
free ( sanitized ) ;
unsanitized = " relative " PATHSEP " .. " PATHSEP " good " ;
expected = " relative " PATHSEP " .. " PATHSEP " good " ;
expected_base = " good " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
ck_assert ( NULL ! = sanitized ) ;
ck_assert ( NULL ! = sanitized_base ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
ck_assert_msg ( ! strcmp ( expected_base , sanitized_base ) , " Expected: \" %s \" , Found: \" %s \" " , expected_base , sanitized_base ) ;
2019-03-02 13:05:17 -05:00
free ( sanitized ) ;
unsanitized = " relative " PATHSEP " .. " PATHSEP " .. " PATHSEP " bad_2 " ;
2020-08-08 21:02:47 -07:00
expected = " relative " PATHSEP " .. " PATHSEP " bad_2 " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
ck_assert ( NULL ! = sanitized ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
free ( sanitized ) ;
unsanitized = " relative " PATHSEP " .. " PATHSEP " .. " PATHSEP " bad_2 " ;
expected = " relative " PATHSEP " .. " PATHSEP " bad_2 " ;
expected_base = " bad_2 " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
2020-01-15 08:14:23 -08:00
ck_assert ( NULL ! = sanitized ) ;
2020-08-08 21:02:47 -07:00
ck_assert ( NULL ! = sanitized_base ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
ck_assert_msg ( ! strcmp ( expected_base , sanitized_base ) , " Expected: \" %s \" , Found: \" %s \" " , expected_base , sanitized_base ) ;
2019-03-02 13:05:17 -05:00
free ( sanitized ) ;
unsanitized = " relative " PATHSEP " . " PATHSEP " .. " PATHSEP " .. " PATHSEP " bad_current " ;
2020-08-08 21:02:47 -07:00
expected = " relative " PATHSEP " .. " PATHSEP " bad_current " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
2020-01-15 08:14:23 -08:00
ck_assert ( NULL ! = sanitized ) ;
ck_assert_msg ( ! strcmp ( sanitized , " relative " PATHSEP " .. " PATHSEP " bad_current " ) , " sanitize_path: bad relative current path test failed " ) ;
2020-08-08 21:02:47 -07:00
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
free ( sanitized ) ;
unsanitized = " relative " PATHSEP " . " PATHSEP " .. " PATHSEP " .. " PATHSEP " bad_current " ;
expected = " relative " PATHSEP " .. " PATHSEP " bad_current " ;
expected_base = " bad_current " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
ck_assert ( NULL ! = sanitized ) ;
ck_assert ( NULL ! = sanitized_base ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
ck_assert_msg ( ! strcmp ( expected_base , sanitized_base ) , " Expected: \" %s \" , Found: \" %s \" " , expected_base , sanitized_base ) ;
2019-03-02 13:05:17 -05:00
free ( sanitized ) ;
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
unsanitized = " relative/../../bad_win_posix_path " ; // <-- posix paths intentionally specified -- should still work on Windows)
expected = " relative " PATHSEP " .. " PATHSEP " bad_win_posix_path " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
2020-01-15 08:14:23 -08:00
ck_assert ( NULL ! = sanitized ) ;
2020-08-08 21:02:47 -07:00
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
free ( sanitized ) ;
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
unsanitized = " relative/../../bad_win_posix_path " ; // <-- posix paths intentionally specified -- should still work on Windows)
expected = " relative " PATHSEP " .. " PATHSEP " bad_win_posix_path " ;
2020-08-08 21:02:47 -07:00
expected_base = " bad_win_posix_path " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
ck_assert ( NULL ! = sanitized ) ;
ck_assert ( NULL ! = sanitized_base ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
ck_assert_msg ( ! strcmp ( expected_base , sanitized_base ) , " Expected: \" %s \" , Found: \" %s \" " , expected_base , sanitized_base ) ;
2019-03-02 13:05:17 -05:00
free ( sanitized ) ;
unsanitized = " " PATHSEP " absolute " PATHSEP " .. " PATHSEP " .. " PATHSEP " bad " ;
2020-08-08 21:02:47 -07:00
expected = " absolute " PATHSEP " .. " PATHSEP " bad " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
ck_assert ( NULL ! = sanitized ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
free ( sanitized ) ;
unsanitized = " " PATHSEP " absolute " PATHSEP " .. " PATHSEP " .. " PATHSEP " bad " ;
expected = " absolute " PATHSEP " .. " PATHSEP " bad " ;
expected_base = " bad " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
2020-01-15 08:14:23 -08:00
ck_assert ( NULL ! = sanitized ) ;
2020-08-08 21:02:47 -07:00
ck_assert ( NULL ! = sanitized_base ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
ck_assert_msg ( ! strcmp ( expected_base , sanitized_base ) , " Expected: \" %s \" , Found: \" %s \" " , expected_base , sanitized_base ) ;
2019-03-02 13:05:17 -05:00
free ( sanitized ) ;
unsanitized = " " PATHSEP " absolute " PATHSEP " .. " PATHSEP " good " ;
2020-08-08 21:02:47 -07:00
expected = " absolute " PATHSEP " .. " PATHSEP " good " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
2020-01-15 08:14:23 -08:00
ck_assert ( NULL ! = sanitized ) ;
2020-08-08 21:02:47 -07:00
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
free ( sanitized ) ;
unsanitized = " " PATHSEP " absolute " PATHSEP " .. " PATHSEP " good " ;
expected = " absolute " PATHSEP " .. " PATHSEP " good " ;
expected_base = " good " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
ck_assert ( NULL ! = sanitized ) ;
ck_assert ( NULL ! = sanitized_base ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
ck_assert_msg ( ! strcmp ( expected_base , sanitized_base ) , " Expected: \" %s \" , Found: \" %s \" " , expected_base , sanitized_base ) ;
2019-03-02 13:05:17 -05:00
free ( sanitized ) ;
unsanitized = " relative " PATHSEP " normal " ;
2020-08-08 21:02:47 -07:00
expected = " relative " PATHSEP " normal " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
2020-01-15 08:14:23 -08:00
ck_assert ( NULL ! = sanitized ) ;
2020-08-08 21:02:47 -07:00
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
free ( sanitized ) ;
unsanitized = " relative " PATHSEP " normal " ;
expected = " relative " PATHSEP " normal " ;
expected_base = " normal " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
ck_assert ( NULL ! = sanitized ) ;
ck_assert ( NULL ! = sanitized_base ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
ck_assert_msg ( ! strcmp ( expected_base , sanitized_base ) , " Expected: \" %s \" , Found: \" %s \" " , expected_base , sanitized_base ) ;
2019-03-02 13:05:17 -05:00
free ( sanitized ) ;
unsanitized = " relative " PATHSEP PATHSEP " doublesep " ;
2020-08-08 21:02:47 -07:00
expected = " relative " PATHSEP " doublesep " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
ck_assert ( NULL ! = sanitized ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
free ( sanitized ) ;
unsanitized = " relative " PATHSEP PATHSEP " doublesep " ;
expected = " relative " PATHSEP " doublesep " ;
expected_base = " doublesep " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
2020-01-15 08:14:23 -08:00
ck_assert ( NULL ! = sanitized ) ;
2020-08-08 21:02:47 -07:00
ck_assert ( NULL ! = sanitized_base ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
ck_assert_msg ( ! strcmp ( expected_base , sanitized_base ) , " Expected: \" %s \" , Found: \" %s \" " , expected_base , sanitized_base ) ;
2019-03-02 13:05:17 -05:00
free ( sanitized ) ;
unsanitized = " relative " PATHSEP " shortname " PATHSEP " 1 " ;
2020-08-08 21:02:47 -07:00
expected = " relative " PATHSEP " shortname " PATHSEP " 1 " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
ck_assert ( NULL ! = sanitized ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
free ( sanitized ) ;
unsanitized = " relative " PATHSEP " shortname " PATHSEP " 1 " ;
expected = " relative " PATHSEP " shortname " PATHSEP " 1 " ;
expected_base = " 1 " ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
ck_assert ( NULL ! = sanitized ) ;
ck_assert ( NULL ! = sanitized_base ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
ck_assert_msg ( ! strcmp ( expected_base , sanitized_base ) , " Expected: \" %s \" , Found: \" %s \" " , expected_base , sanitized_base ) ;
free ( sanitized ) ;
unsanitized = " relative " PATHSEP " noname " PATHSEP ;
expected = " relative " PATHSEP " noname " PATHSEP ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , NULL ) ;
ck_assert ( NULL ! = sanitized ) ;
ck_assert_msg ( ! strcmp ( sanitized , " relative " PATHSEP " noname " PATHSEP ) , " sanitize_path: relative no name path test failed " ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
free ( sanitized ) ;
unsanitized = " relative " PATHSEP " noname " PATHSEP ;
expected = " relative " PATHSEP " noname " PATHSEP ;
sanitized = cli_sanitize_filepath ( unsanitized , strlen ( unsanitized ) , & sanitized_base ) ;
2020-01-15 08:14:23 -08:00
ck_assert ( NULL ! = sanitized ) ;
2020-08-08 21:02:47 -07:00
ck_assert ( NULL = = sanitized_base ) ;
ck_assert_msg ( ! strcmp ( expected , sanitized ) , " Expected: \" %s \" , Found: \" %s \" " , expected , sanitized ) ;
2019-03-02 13:05:17 -05:00
free ( sanitized ) ;
}
END_TEST
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
START_TEST ( test_cli_codepage_to_utf8_jis )
2020-07-24 14:45:44 -07:00
{
cl_error_t ret ;
char * utf8 = NULL ;
size_t utf8_size = 0 ;
ret = cli_codepage_to_utf8 ( " \x82 \xB1 \x82 \xF1 \x82 \xC9 \x82 \xBF \x82 \xCD " , 10 , CODEPAGE_JAPANESE_SHIFT_JIS , & utf8 , & utf8_size ) ;
ck_assert_msg ( CL_SUCCESS = = ret , " test_cli_codepage_to_utf8: Failed to convert CODEPAGE_JAPANESE_SHIFT_JIS to UTF8: ret != SUCCESS! " ) ;
ck_assert_msg ( NULL ! = utf8 , " sanitize_path: Failed to convert CODEPAGE_JAPANESE_SHIFT_JIS to UTF8: utf8 pointer is NULL! " ) ;
ck_assert_msg ( 0 = = strcmp ( utf8 , " こんにちは " ) , " sanitize_path: '%s' doesn't match '%s' " , utf8 , " こんにちは " ) ;
if ( NULL ! = utf8 ) {
free ( utf8 ) ;
utf8 = NULL ;
}
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
}
END_TEST
START_TEST ( test_cli_codepage_to_utf8_utf16be_null_term )
{
cl_error_t ret ;
char * utf8 = NULL ;
size_t utf8_size = 0 ;
2020-07-24 14:45:44 -07:00
ret = cli_codepage_to_utf8 ( " \x00 \x48 \x00 \x65 \x00 \x6c \x00 \x6c \x00 \x6f \x00 \x20 \x00 \x77 \x00 \x6f \x00 \x72 \x00 \x6c \x00 \x64 \x00 \x21 \x00 \x00 " , 26 , CODEPAGE_UTF16_BE , & utf8 , & utf8_size ) ;
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
ck_assert_msg ( CL_SUCCESS = = ret , " test_cli_codepage_to_utf8: Failed to convert CODEPAGE_UTF16_BE to UTF8: ret != SUCCESS! " ) ;
ck_assert_msg ( NULL ! = utf8 , " sanitize_path: Failed to convert CODEPAGE_UTF16_BE to UTF8: utf8 pointer is NULL! " ) ;
2020-07-24 14:45:44 -07:00
ck_assert_msg ( 0 = = strcmp ( utf8 , " Hello world! " ) , " sanitize_path: '%s' doesn't match '%s' " , utf8 , " Hello world! " ) ;
if ( NULL ! = utf8 ) {
free ( utf8 ) ;
utf8 = NULL ;
}
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
}
END_TEST
START_TEST ( test_cli_codepage_to_utf8_utf16be_no_null_term )
{
cl_error_t ret ;
char * utf8 = NULL ;
size_t utf8_size = 0 ;
2020-07-24 14:45:44 -07:00
ret = cli_codepage_to_utf8 ( " \x00 \x48 \x00 \x65 \x00 \x6c \x00 \x6c \x00 \x6f \x00 \x20 \x00 \x77 \x00 \x6f \x00 \x72 \x00 \x6c \x00 \x64 \x00 \x21 " , 24 , CODEPAGE_UTF16_BE , & utf8 , & utf8_size ) ;
ck_assert_msg ( CL_SUCCESS = = ret , " test_cli_codepage_to_utf8: Failed to convert CODEPAGE_UTF16_BE to UTF8: ret != SUCCESS! " ) ;
ck_assert_msg ( NULL ! = utf8 , " sanitize_path: Failed to convert CODEPAGE_UTF16_BE to UTF8: utf8 pointer is NULL! " ) ;
ck_assert_msg ( 0 = = strcmp ( utf8 , " Hello world! " ) , " sanitize_path: '%s' doesn't match '%s' " , utf8 , " Hello world! " ) ;
if ( NULL ! = utf8 ) {
free ( utf8 ) ;
utf8 = NULL ;
}
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
}
END_TEST
START_TEST ( test_cli_codepage_to_utf8_utf16le )
{
cl_error_t ret ;
char * utf8 = NULL ;
size_t utf8_size = 0 ;
2020-07-24 14:45:44 -07:00
ret = cli_codepage_to_utf8 ( " \x48 \x00 \x65 \x00 \x6c \x00 \x6c \x00 \x6f \x00 \x20 \x00 \x77 \x00 \x6f \x00 \x72 \x00 \x6c \x00 \x64 \x00 \x21 \x00 \x00 \x00 " , 26 , CODEPAGE_UTF16_LE , & utf8 , & utf8_size ) ;
ck_assert_msg ( CL_SUCCESS = = ret , " test_cli_codepage_to_utf8: Failed to convert CODEPAGE_UTF16_LE to UTF8: ret != SUCCESS! " ) ;
ck_assert_msg ( NULL ! = utf8 , " sanitize_path: Failed to convert CODEPAGE_UTF16_LE to UTF8: utf8 pointer is NULL! " ) ;
ck_assert_msg ( 0 = = strcmp ( utf8 , " Hello world! " ) , " sanitize_path: '%s' doesn't match '%s' " , utf8 , " Hello world! " ) ;
if ( NULL ! = utf8 ) {
free ( utf8 ) ;
utf8 = NULL ;
}
}
END_TEST
2008-04-07 13:43:16 +00:00
static Suite * test_cli_suite ( void )
{
2019-03-02 13:05:17 -05:00
Suite * s = suite_create ( " cli " ) ;
TCase * tc_cli_others = tcase_create ( " byteorder_macros " ) ;
TCase * tc_cli_dsig = tcase_create ( " digital signatures " ) ;
TCase * tc_cli_assorted = tcase_create ( " assorted functions " ) ;
2008-04-07 13:43:16 +00:00
2018-12-03 12:40:13 -05:00
suite_add_tcase ( s , tc_cli_others ) ;
tcase_add_checked_fixture ( tc_cli_others , data_setup , data_teardown ) ;
2009-01-27 10:57:54 +00:00
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 ) ;
2018-12-03 12:40:13 -05:00
suite_add_tcase ( s , tc_cli_dsig ) ;
2009-01-27 10:57:54 +00:00
tcase_add_loop_test ( tc_cli_dsig , test_cli_dsig , 0 , dsig_tests_cnt ) ;
2025-06-03 19:03:20 -04:00
tcase_add_test ( tc_cli_dsig , test_sha2_256 ) ;
2008-04-07 13:43:16 +00:00
2019-03-02 13:05:17 -05:00
suite_add_tcase ( s , tc_cli_assorted ) ;
tcase_add_test ( tc_cli_assorted , test_sanitize_path ) ;
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
tcase_add_test ( tc_cli_assorted , test_cli_codepage_to_utf8_jis ) ;
tcase_add_test ( tc_cli_assorted , test_cli_codepage_to_utf8_utf16be_null_term ) ;
tcase_add_test ( tc_cli_assorted , test_cli_codepage_to_utf8_utf16be_no_null_term ) ;
tcase_add_test ( tc_cli_assorted , test_cli_codepage_to_utf8_utf16le ) ;
2019-03-02 13:05:17 -05:00
2008-04-07 13:43:16 +00:00
return s ;
}
2008-07-24 18:48:31 +00:00
void errmsg_expected ( void )
{
2018-12-03 12:40:13 -05:00
fputs ( " cli_errmsg() expected here \n " , stderr ) ;
2008-07-24 18:48:31 +00:00
}
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
int open_testfile ( const char * name , int flags )
2008-07-25 16:03:04 +00:00
{
2018-12-03 12:40:13 -05:00
int fd ;
char * str ;
2025-02-03 13:25:31 -05:00
str = malloc ( strlen ( name ) + strlen ( SRCDIR ) + 2 ) ;
Remove max-allocation limits where not required
The cli_max_malloc, cli_max_calloc, and cli_max_realloc functions
provide a way to protect against allocating too much memory
when the size of the allocation is derived from the untrusted input.
Specifically, we worry about values in the file being scanned being
manipulated to exhaust the RAM and crash the application.
There is no need to check the limits if the size of the allocation
is fixed, or if the size of the allocation is necessary for signature
loading, or the general operation of the applications.
E.g. checking the max-allocation limit for the size of a hash, or
for the size of the scan recursion stack, is a complete waste of
time.
Although we significantly increased the max-allocation limit in
a recent release, it is best not to check an allocation if the
allocation will be safe. It would be a waste of time.
I am also hopeful that if we can reduce the number allocations
that require a limit-check to those that require it for the safe
scan of a file, then eventually we can store the limit in the scan-
context, and make it configurable.
2024-01-08 22:48:28 -05:00
ck_assert_msg ( ! ! str , " malloc " ) ;
2025-02-03 13:25:31 -05:00
sprintf ( str , " %s " PATHSEP " %s " , SRCDIR , name ) ;
2018-12-03 12:40:13 -05:00
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
fd = open ( str , flags ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( fd > = 0 , " open() failed: %s " , str ) ;
2018-12-03 12:40:13 -05:00
free ( str ) ;
return fd ;
2008-07-25 16:03:04 +00:00
}
2008-09-23 20:52:22 +00:00
void diff_file_mem ( int fd , const char * ref , size_t len )
{
2018-12-03 12:40:13 -05:00
char c1 , c2 ;
size_t p , reflen = len ;
Remove max-allocation limits where not required
The cli_max_malloc, cli_max_calloc, and cli_max_realloc functions
provide a way to protect against allocating too much memory
when the size of the allocation is derived from the untrusted input.
Specifically, we worry about values in the file being scanned being
manipulated to exhaust the RAM and crash the application.
There is no need to check the limits if the size of the allocation
is fixed, or if the size of the allocation is necessary for signature
loading, or the general operation of the applications.
E.g. checking the max-allocation limit for the size of a hash, or
for the size of the scan recursion stack, is a complete waste of
time.
Although we significantly increased the max-allocation limit in
a recent release, it is best not to check an allocation if the
allocation will be safe. It would be a waste of time.
I am also hopeful that if we can reduce the number allocations
that require a limit-check to those that require it for the safe
scan of a file, then eventually we can store the limit in the scan-
context, and make it configurable.
2024-01-08 22:48:28 -05:00
char * buf = malloc ( len ) ;
2018-12-03 12:40:13 -05:00
2021-10-03 14:13:55 -07:00
ck_assert_msg ( ! ! buf , " unable to malloc buffer: %zu " , len ) ;
2018-12-03 12:40:13 -05:00
p = read ( fd , buf , len ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( p = = len , " file is smaller: %lu, expected: %lu " , p , len ) ;
2018-12-03 12:40:13 -05:00
p = 0 ;
while ( len > 0 ) {
c1 = ref [ p ] ;
c2 = buf [ p ] ;
if ( c1 ! = c2 )
break ;
p + + ;
len - - ;
}
if ( len > 0 )
2020-01-15 08:14:23 -08:00
ck_assert_msg ( c1 = = c2 , " file contents mismatch at byte: %lu, was: %c, expected: %c " , p , c2 , c1 ) ;
2018-12-03 12:40:13 -05:00
free ( buf ) ;
p = lseek ( fd , 0 , SEEK_END ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( p = = reflen , " trailing garbage, file size: %ld, expected: %ld " , p , reflen ) ;
2018-12-03 12:40:13 -05:00
close ( fd ) ;
2008-09-23 20:52:22 +00:00
}
void diff_files ( int fd , int ref_fd )
{
2018-12-03 12:40:13 -05:00
char * ref ;
ssize_t nread ;
off_t siz = lseek ( ref_fd , 0 , SEEK_END ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( siz ! = - 1 , " lseek failed " ) ;
2018-12-03 12:40:13 -05:00
Remove max-allocation limits where not required
The cli_max_malloc, cli_max_calloc, and cli_max_realloc functions
provide a way to protect against allocating too much memory
when the size of the allocation is derived from the untrusted input.
Specifically, we worry about values in the file being scanned being
manipulated to exhaust the RAM and crash the application.
There is no need to check the limits if the size of the allocation
is fixed, or if the size of the allocation is necessary for signature
loading, or the general operation of the applications.
E.g. checking the max-allocation limit for the size of a hash, or
for the size of the scan recursion stack, is a complete waste of
time.
Although we significantly increased the max-allocation limit in
a recent release, it is best not to check an allocation if the
allocation will be safe. It would be a waste of time.
I am also hopeful that if we can reduce the number allocations
that require a limit-check to those that require it for the safe
scan of a file, then eventually we can store the limit in the scan-
context, and make it configurable.
2024-01-08 22:48:28 -05:00
ref = malloc ( siz ) ;
2021-10-03 14:13:55 -07:00
ck_assert_msg ( ! ! ref , " unable to malloc buffer: " STDi64 , ( int64_t ) siz ) ;
2018-12-03 12:40:13 -05:00
2020-01-15 08:14:23 -08:00
ck_assert_msg ( lseek ( ref_fd , 0 , SEEK_SET ) = = 0 , " lseek failed " ) ;
2018-12-03 12:40:13 -05:00
nread = read ( ref_fd , ref , siz ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( nread = = siz , " short read, expected: %ld, was: %ld " , siz , nread ) ;
2018-12-03 12:40:13 -05:00
close ( ref_fd ) ;
diff_file_mem ( fd , ref , siz ) ;
free ( ref ) ;
2008-09-23 20:52:22 +00:00
}
2008-11-04 10:40:24 +00:00
# ifdef USE_MPOOL
2009-01-26 19:47:02 +00:00
static mpool_t * pool ;
2008-11-03 19:26:57 +00:00
# else
static void * pool ;
# endif
struct cli_dconf * dconf ;
void dconf_setup ( void )
{
2018-12-03 12:40:13 -05:00
pool = NULL ;
dconf = NULL ;
2008-11-04 10:40:24 +00:00
# ifdef USE_MPOOL
2018-12-03 12:40:13 -05:00
pool = mpool_create ( ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ! ! pool , " unable to create pool " ) ;
2008-11-03 19:26:57 +00:00
# endif
2018-12-03 12:40:13 -05:00
dconf = cli_mpool_dconf_init ( pool ) ;
2020-01-15 08:14:23 -08:00
ck_assert_msg ( ! ! dconf , " failed to init dconf " ) ;
2008-11-03 19:26:57 +00:00
}
void dconf_teardown ( void )
{
2019-05-03 18:16:03 -04:00
MPOOL_FREE ( pool , dconf ) ;
2008-11-04 10:40:24 +00:00
# ifdef USE_MPOOL
2018-12-03 12:40:13 -05:00
if ( pool )
mpool_destroy ( pool ) ;
2008-11-03 19:26:57 +00:00
# endif
}
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
# ifndef _WIN32
2010-01-20 18:12:10 +02:00
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 ) | |
2018-12-03 12:40:13 -05:00
( check_minor_version ! = CHECK_MINOR_VERSION ) | |
( check_micro_version ! = CHECK_MICRO_VERSION ) ) {
fprintf ( stderr , " ERROR: check version mismatch! \n "
" \t Version from header: %u.%u.%u \n "
" \t Version from library: %u.%u.%u \n "
" \t Make 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 ) ;
2010-01-20 18:12:10 +02:00
}
}
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
# endif
2008-11-03 19:26:57 +00:00
Windows: Fix C/Rust FFI compat issue + Windows compile warnings
Primarily this commit fixes an issue with the size of the parameters
passed to cli_checklimits(). The parameters were "unsigned long", which
varies in size depending on platform.
I've switched them to uint64_t / u64.
While working on this, I observed some concerning warnigns on Windows,
and some less serious ones, primarily regarding inconsistencies with
`const` parameters.
Finally, in `scanmem.c`, there is a warning regarding use of `wchar_t *`
with `GetModuleFileNameEx()` instead of `GetModuleFileNameExW()`.
This made me realize this code assumes we're not defining `UNICODE`,
which would have such macros use the 'A' variant.
I have fixed it the best I can, although I'm still a little
uncomfortable with some of this code that uses `char` or `wchar_t`
instead of TCHAR.
I also remove the `if (GetModuleFileNameEx) {` conditional, because this
macro/function will always be defined. The original code was checking a
function pointer, and so this was a bug when integrating into ClamAV.
Regarding the changes to `rijndael.c`, I found that this module assumes
`unsigned long` == 32bits. It does not.
I have corrected it to use `uint32_t`.
2024-03-20 12:21:40 -04:00
int main ( int argc , char * * argv )
2008-03-13 10:44:34 +00:00
{
2008-04-07 13:43:16 +00:00
int nf ;
2010-01-20 18:12:10 +02:00
Suite * s ;
SRunner * sr ;
2025-09-09 12:35:14 -04:00
FILE * log_file = NULL ;
2010-01-20 18:12:10 +02:00
Windows: Fix C/Rust FFI compat issue + Windows compile warnings
Primarily this commit fixes an issue with the size of the parameters
passed to cli_checklimits(). The parameters were "unsigned long", which
varies in size depending on platform.
I've switched them to uint64_t / u64.
While working on this, I observed some concerning warnigns on Windows,
and some less serious ones, primarily regarding inconsistencies with
`const` parameters.
Finally, in `scanmem.c`, there is a warning regarding use of `wchar_t *`
with `GetModuleFileNameEx()` instead of `GetModuleFileNameExW()`.
This made me realize this code assumes we're not defining `UNICODE`,
which would have such macros use the 'A' variant.
I have fixed it the best I can, although I'm still a little
uncomfortable with some of this code that uses `char` or `wchar_t`
instead of TCHAR.
I also remove the `if (GetModuleFileNameEx) {` conditional, because this
macro/function will always be defined. The original code was checking a
function pointer, and so this was a bug when integrating into ClamAV.
Regarding the changes to `rijndael.c`, I found that this module assumes
`unsigned long` == 32bits. It does not.
I have corrected it to use `uint32_t`.
2024-03-20 12:21:40 -04:00
UNUSEDPARAM ( argc ) ;
UNUSEDPARAM ( argv ) ;
2014-05-09 17:09:29 -04:00
cl_initialize_crypto ( ) ;
2018-12-03 12:40:13 -05:00
fpu_words = get_fpu_endian ( ) ;
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
# ifndef _WIN32
2010-01-20 18:12:10 +02:00
check_version_compatible ( ) ;
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
# endif
2018-12-03 12:40:13 -05:00
s = test_cl_suite ( ) ;
2010-01-20 18:12:10 +02:00
sr = srunner_create ( s ) ;
2020-01-15 08:14:23 -08:00
2008-04-07 13:43:16 +00:00
srunner_add_suite ( sr , test_cli_suite ( ) ) ;
2008-07-08 19:02:15 +00:00
srunner_add_suite ( sr , test_jsnorm_suite ( ) ) ;
2008-07-10 10:29:29 +00:00
srunner_add_suite ( sr , test_str_suite ( ) ) ;
2008-07-29 10:36:26 +00:00
srunner_add_suite ( sr , test_regex_suite ( ) ) ;
2008-07-28 19:22:15 +00:00
srunner_add_suite ( sr , test_disasm_suite ( ) ) ;
2008-08-04 00:01:14 +00:00
srunner_add_suite ( sr , test_uniq_suite ( ) ) ;
2008-08-07 12:40:41 +00:00
srunner_add_suite ( sr , test_matchers_suite ( ) ) ;
2008-09-23 20:52:22 +00:00
srunner_add_suite ( sr , test_htmlnorm_suite ( ) ) ;
2009-07-13 19:34:12 +03:00
srunner_add_suite ( sr , test_bytecode_suite ( ) ) ;
2008-03-13 10:44:34 +00:00
CMake: Add CTest support to match Autotools checks
An ENABLE_TESTS CMake option is provided so that users can disable
testing if they don't want it. Instructions for how to use this
included in the INSTALL.cmake.md file.
If you run `ctest`, each testcase will write out a log file to the
<build>/unit_tests directory.
As with Autotools' make check, the test files are from test/.split
and unit_tests/.split files, but for CMake these are generated at
build time instead of at test time.
On Posix systems, sets the LD_LIBRARY_PATH so that ClamAV-compiled
libraries can be loaded when running tests.
On Windows systems, CTest will identify and collect all library
dependencies and assemble a temporarily install under the
build/unit_tests directory so that the libraries can be loaded when
running tests.
The same feature is used on Windows when using CMake to install to
collect all DLL dependencies so that users don't have to install them
manually afterwards.
Each of the CTest tests are run using a custom wrapper around Python's
unittest framework, which is also responsible for finding and inserting
valgrind into the valgrind tests on Posix systems.
Unlike with Autotools, the CMake CTest Valgrind-tests are enabled by
default, if Valgrind can be found. There's no need to set VG=1.
CTest's memcheck module is NOT supported, because we use Python to
orchestrate our tests.
Added a bunch of Windows compatibility changes to the unit tests.
These were primarily changing / to PATHSEP and making adjustments
to use Win32 C headers and ifdef out the POSIX ones which aren't
available on Windows. Also disabled a bunch of tests on Win32
that don't work on Windows, notably the mmap ones and FD-passing
(i.e. FILEDES) ones.
Add JSON_C_HAVE_INTTYPES_H definition to clamav-config.h to eliminate
warnings on Windows where json.h is included after inttypes.h because
json-c's inttypes replacement relies on it.
This is a it of a hack and may be removed if json-c fixes their
inttypes header stuff in the future.
Add preprocessor definitions on Windows to disable MSVC warnings about
CRT secure and nonstandard functions. While there may be a better
solution, this is needed to be able to see other more serious warnings.
Add missing file comment block and copyright statement for clamsubmit.c.
Also change json-c/json.h include filename to json.h in clamsubmit.c.
The directory name is not required.
Changed the hash table data integer type from long, which is poorly
defined, to size_t -- which is capable of storing a pointer. Fixed a
bunch of casts regarding this variable to eliminate warnings.
Fixed two bugs causing utf8 encoding unit tests to fail on Windows:
- The in_size variable should be the number of bytes, not the character
count. This was was causing the SHIFT_JIS (japanese codepage) to UTF8
transcoding test to only transcode half the bytes.
- It turns out that the MultiByteToWideChar() API can't transcode
UTF16-BE to UTF16-LE. The solution is to just iterate over the buffer
and flip the bytes on each uint16_t. This but was causing the UTF16-BE
to UTF8 tests to fail.
I also split up the utf8 transcoding tests into separate tests so I
could see all of the failures instead of just the first one.
Added a flags parameter to the unit test function to open testfiles
because it turns out that on Windows if a file contains the \r\n it will
replace it with just \n if you opened the file as a text file instead of
as binary. However, if we open the CBC files as binary, then a bunch of
bytecode tests fail. So I've changed the tests to open the CBC files in
the bytecode tests as text files and open all other files as binary.
Ported the feature tests from shell scripts to Python using a modified
version of our QA test-framework, which is largely compatible and will
allow us to migrate some QA tests into this repo. I'd like to add GitHub
Actions pipelines in the future so that all public PR's get some testing
before anyone has to manually review them.
The clamd --log option was missing from the help string, though it
definitely works. I've added it in this commit.
It appears that clamd.c was never clang-format'd, so this commit also
reformats clamd.c.
Some of the check_clamd tests expected the path returned by clamd to
match character for character with original path sent to clamd. However,
as we now evaluate real paths before a scan, the path returned by clamd
isn't going to match the relative (and possibly symlink-ridden) path
passed to clamdscan. I fixed this test by changing the test to search
for the basename: <signature> FOUND within the response instead of
matching the exact path.
Autotools: Link check_clamd with libclamav so we can use our utility
functions in check_clamd.c.
2020-08-25 23:14:23 -07:00
srunner_set_log ( sr , OBJDIR PATHSEP " test.log " ) ;
2025-09-09 12:35:14 -04:00
log_file = freopen ( OBJDIR PATHSEP " test-stderr.log " , " w+ " , stderr ) ;
if ( log_file = = NULL ) {
2023-04-18 14:53:57 -07:00
// The stderr FILE pointer may be closed by `freopen()` even if redirecting to the log file files.
// So we will output the error message to stdout instead.
fputs ( " Unable to redirect stderr! \n " , stdout ) ;
2008-07-29 10:59:21 +00:00
}
2008-08-21 20:21:43 +00:00
cl_debug ( ) ;
2008-07-24 18:48:31 +00:00
2008-03-13 10:44:34 +00:00
srunner_run_all ( sr , CK_NORMAL ) ;
nf = srunner_ntests_failed ( sr ) ;
2015-07-28 16:17:59 -04:00
if ( nf )
2018-12-03 12:40:13 -05:00
printf ( " NOTICE: Use the 'T' environment variable to adjust testcase timeout \n " ) ;
2008-03-13 10:44:34 +00:00
srunner_free ( sr ) ;
2011-06-14 22:35:03 +03:00
2014-06-30 16:35:48 -04:00
xmlCleanupParser ( ) ;
2014-05-09 17:09:29 -04:00
2025-09-09 12:35:14 -04:00
if ( log_file ) {
fclose ( log_file ) ;
}
2008-03-13 10:44:34 +00:00
return ( nf = = 0 ) ? EXIT_SUCCESS : EXIT_FAILURE ;
}