mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00

When counting chunks for the purpose of a Valid check, only count up to chunk_count_limit + 1 chunks. This speeds up the skipping of the 70,000 chunk test file considerably. Before: Processed 1 inputs in 0.025517s After: Processed 1 inputs in 0.000620s
88 lines
1.9 KiB
C++
88 lines
1.9 KiB
C++
#if !defined(_GNU_SOURCE)
|
|
#define _GNU_SOURCE
|
|
#endif
|
|
|
|
#include <string.h>
|
|
|
|
#include "FuzzBuffer.h"
|
|
|
|
bool zeek::detail::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 ( ChunkCount(chunk_count_limit + 1) > chunk_count_limit )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
int zeek::detail::FuzzBuffer::ChunkCount(int chunk_count_limit) const
|
|
{
|
|
auto pos = begin;
|
|
int chunks = 0;
|
|
|
|
while ( pos < end && (chunk_count_limit == 0 || chunks < chunk_count_limit) )
|
|
{
|
|
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<zeek::detail::FuzzBuffer::Chunk> zeek::detail::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 {};
|
|
}
|