|
// Suggested regression tests for PcapDirectoryDispatchForTimeRange() in
|
|
// src/source-pcap-file-directory-helper.c.
|
|
//
|
|
// source-pcap-file-directory-helper.c has no unit tests in oisf/main today, so
|
|
// three pieces are needed:
|
|
//
|
|
// 1. The tests, appended at the end of source-pcap-file-directory-helper.c
|
|
// together with their registration function:
|
|
|
|
#ifdef UNITTESTS
|
|
|
|
/** \test CleanupPcapFileDirectoryVars(NULL) must not crash. */
|
|
static int PcapDirectoryHelperCleanupNullTest(void)
|
|
{
|
|
CleanupPcapFileDirectoryVars(NULL);
|
|
PASS;
|
|
}
|
|
|
|
/** \test CleanupPendingFile(NULL) must not crash. */
|
|
static int PcapDirectoryHelperCleanupPendingFileNullTest(void)
|
|
{
|
|
CleanupPendingFile(NULL);
|
|
PASS;
|
|
}
|
|
|
|
/**
|
|
* \test After CleanupPcapFileFileVars() the pointer
|
|
* must be NULLed before any early return so that
|
|
* CleanupPcapFileDirectoryVars() cannot double-free it on teardown.
|
|
*
|
|
* Simulates the FAILED branch of PcapDirectoryDispatchForTimeRange():
|
|
* pv->current_file = pftv;
|
|
* PcapFileDispatch(pftv); -- returns TM_ECODE_FAILED
|
|
* CleanupPcapFileFileVars(pftv); -- frees pftv
|
|
* pv->current_file = NULL; -- the fix
|
|
* ... early return ...
|
|
* Then thread teardown calls CleanupPcapFileDirectoryVars(pv).
|
|
* Without the fix, current_file would still point at freed memory and
|
|
* CleanupPcapFileDirectoryVars would call CleanupPcapFileFileVars again
|
|
* (double-free / use-after-free).
|
|
*/
|
|
static int PcapDirectoryHelperCurrentFileNullAfterFileCleanupTest(void)
|
|
{
|
|
PcapFileDirectoryVars *pv = SCCalloc(1, sizeof(PcapFileDirectoryVars));
|
|
FAIL_IF_NULL(pv);
|
|
TAILQ_INIT(&pv->directory_content);
|
|
|
|
PcapFileFileVars *pftv = SCCalloc(1, sizeof(PcapFileFileVars));
|
|
if (unlikely(pftv == NULL)) {
|
|
SCFree(pv);
|
|
FAIL;
|
|
}
|
|
|
|
pv->current_file = pftv;
|
|
|
|
/* mirror the fixed code path in PcapDirectoryDispatchForTimeRange */
|
|
CleanupPcapFileFileVars(pftv);
|
|
pv->current_file = NULL;
|
|
|
|
/* verify the invariant the fix establishes */
|
|
FAIL_IF_NOT_NULL(pv->current_file);
|
|
|
|
/* teardown must not double-free; hands ownership of pv to the callee */
|
|
CleanupPcapFileDirectoryVars(pv);
|
|
PASS;
|
|
}
|
|
|
|
void PcapDirectoryHelperRegisterTests(void)
|
|
{
|
|
UtRegisterTest("PcapDirectoryHelperCleanupNullTest",
|
|
PcapDirectoryHelperCleanupNullTest);
|
|
UtRegisterTest("PcapDirectoryHelperCleanupPendingFileNullTest",
|
|
PcapDirectoryHelperCleanupPendingFileNullTest);
|
|
UtRegisterTest("PcapDirectoryHelperCurrentFileNullAfterFileCleanupTest",
|
|
PcapDirectoryHelperCurrentFileNullAfterFileCleanupTest);
|
|
}
|
|
#endif /* UNITTESTS */
|
|
|
|
// 2. The declaration, in src/source-pcap-file-directory-helper.h before the
|
|
// final #endif:
|
|
//
|
|
// #ifdef UNITTESTS
|
|
// void PcapDirectoryHelperRegisterTests(void);
|
|
// #endif
|
|
//
|
|
// 3. The call, in src/runmode-unittests.c right after
|
|
// SourcePcapFileHelperRegisterTests():
|
|
//
|
|
// PcapDirectoryHelperRegisterTests();
|
|
//
|
|
// and, next to the existing `#include "source-pcap-file-helper.h"`:
|
|
//
|
|
// #include "source-pcap-file-directory-helper.h"
|