zeek/src/fuzzers/FuzzBuffer.cc
Elad Solomon 3a80b79497 Compile Zeek with MSVC
Allow Zeek to be embedded in another project
2022-11-09 18:15:30 +02:00

94 lines
1.8 KiB
C++

#if ! defined(_GNU_SOURCE)
#define _GNU_SOURCE
#endif
#ifdef _MSC_VER
#include <mem.h>
#endif
#include "zeek/fuzzers/FuzzBuffer.h"
#include <cstring>
namespace zeek::detail
{
bool FuzzBuffer::Valid(int chunk_count_limit) const
{
if ( end - begin < PKT_MAGIC_LEN + 2 )
return false;
if ( memcmp(begin, PKT_MAGIC, PKT_MAGIC_LEN) != 0 )
return false;
if ( ExceedsChunkLimit(chunk_count_limit) )
return false;
return true;
}
int FuzzBuffer::ChunkCount(int chunk_count_limit) const
{
auto pos = begin;
int chunks = 0;
while ( pos < end && (chunks < chunk_count_limit || chunk_count_limit == 0) )
{
pos = (const unsigned char*)memmem(pos, end - pos, PKT_MAGIC, PKT_MAGIC_LEN);
if ( ! pos )
break;
pos += PKT_MAGIC_LEN + 1;
chunks++;
}
return chunks;
}
std::optional<FuzzBuffer::Chunk> FuzzBuffer::Next()
{
if ( begin == end )
return {};
auto pos = (const unsigned char*)memmem(begin, end - begin, PKT_MAGIC, PKT_MAGIC_LEN);
if ( ! pos )
return {};
begin += PKT_MAGIC_LEN;
auto remaining = end - begin;
if ( remaining < 2 )
return {};
Chunk rval;
rval.is_orig = begin[0] & 0x01;
begin += 1;
auto chunk_begin = begin;
auto next = (const unsigned char*)memmem(begin, end - begin, PKT_MAGIC, PKT_MAGIC_LEN);
if ( next )
begin = next;
else
begin = end;
rval.size = begin - chunk_begin;
if ( rval.size )
{
// The point of allocating a new buffer here is to better detect
// analyzers that may over-read within a chunk -- ASan wouldn't
// complain if that happens to land within the full input buffer
// provided by the fuzzing engine, but will if we allocate a new buffer
// for each chunk.
rval.data = std::make_unique<unsigned char[]>(rval.size);
memcpy(rval.data.get(), chunk_begin, rval.size);
return {std::move(rval)};
}
return {};
}
} // namespace zeek::detail