mirror of
https://github.com/zeek/zeek.git
synced 2025-10-14 12:38:20 +00:00
Merge branch 'paraglob' of https://github.com/ZekeMedley/zeek
* 'paraglob' of https://github.com/ZekeMedley/zeek: Add leak test to paraglob. Catch paraglob serialization errors in DoClone. Update paraglob serialization. Stop execution on paraglob error. Update paraglob submodule Change C++11 detection in paraglob. Make paraglob serializable and copyable. Initial paraglob integration. I made a bunch of small changes: * paraglob now deals better with \0 characters * I rolled back the changes to Binary Serialization format, * there were some small formatting issue * the error output was slightly unsafe * build_unique is now in util.h. and perhaps a few more small things.
This commit is contained in:
commit
5f9a9bbcbe
22 changed files with 432 additions and 4 deletions
|
@ -281,4 +281,3 @@ string IPPrefix::AsString() const
|
|||
|
||||
return prefix.AsString() +"/" + l;
|
||||
}
|
||||
|
||||
|
|
|
@ -1024,3 +1024,88 @@ bool CardinalityVal::DoUnserialize(const broker::data& data)
|
|||
c = cu.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
ParaglobVal::ParaglobVal(std::unique_ptr<paraglob::Paraglob> p)
|
||||
: OpaqueVal(paraglob_type)
|
||||
{
|
||||
this->internal_paraglob = std::move(p);
|
||||
}
|
||||
|
||||
VectorVal* ParaglobVal::Get(StringVal* &pattern)
|
||||
{
|
||||
VectorVal* rval = new VectorVal(internal_type("string_vec")->AsVectorType());
|
||||
std::string string_pattern (reinterpret_cast<const char*>(pattern->Bytes()), pattern->Len());
|
||||
|
||||
std::vector<std::string> matches = this->internal_paraglob->get(string_pattern);
|
||||
for (unsigned int i = 0; i < matches.size(); i++)
|
||||
rval->Assign(i, new StringVal(matches.at(i)));
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool ParaglobVal::operator==(const ParaglobVal& other) const
|
||||
{
|
||||
return *(this->internal_paraglob) == *(other.internal_paraglob);
|
||||
}
|
||||
|
||||
IMPLEMENT_OPAQUE_VALUE(ParaglobVal)
|
||||
|
||||
broker::expected<broker::data> ParaglobVal::DoSerialize() const
|
||||
{
|
||||
broker::vector d;
|
||||
std::unique_ptr<std::vector<uint8_t>> iv = this->internal_paraglob->serialize();
|
||||
for (uint8_t a : *(iv.get()))
|
||||
d.emplace_back(static_cast<uint64_t>(a));
|
||||
return {std::move(d)};
|
||||
}
|
||||
|
||||
bool ParaglobVal::DoUnserialize(const broker::data& data)
|
||||
{
|
||||
auto d = caf::get_if<broker::vector>(&data);
|
||||
if ( ! d )
|
||||
return false;
|
||||
|
||||
std::unique_ptr<std::vector<uint8_t>> iv (new std::vector<uint8_t>);
|
||||
iv->resize(d->size());
|
||||
|
||||
for (std::vector<broker::data>::size_type i = 0; i < d->size(); ++i)
|
||||
{
|
||||
if ( ! get_vector_idx<uint64_t>(*d, i, iv.get()->data() + i) )
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this->internal_paraglob = build_unique<paraglob::Paraglob>(std::move(iv));
|
||||
}
|
||||
catch (const paraglob::underflow_error& e)
|
||||
{
|
||||
reporter->Error("Paraglob underflow error -> %s", e.what());
|
||||
return false;
|
||||
}
|
||||
catch (const paraglob::overflow_error& e)
|
||||
{
|
||||
reporter->Error("Paraglob overflow error -> %s", e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Val* ParaglobVal::DoClone(CloneState* state)
|
||||
{
|
||||
try {
|
||||
return new ParaglobVal
|
||||
(build_unique<paraglob::Paraglob>(this->internal_paraglob->serialize()));
|
||||
}
|
||||
catch (const paraglob::underflow_error& e)
|
||||
{
|
||||
reporter->Error("Paraglob underflow error while cloning -> %s", e.what());
|
||||
return nullptr;
|
||||
}
|
||||
catch (const paraglob::overflow_error& e)
|
||||
{
|
||||
reporter->Error("Paraglob overflow error while cloning -> %s", e.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,18 @@
|
|||
#ifndef OPAQUEVAL_H
|
||||
#define OPAQUEVAL_H
|
||||
|
||||
|
||||
|
||||
#include <memory> // std::unique_ptr
|
||||
|
||||
#include <broker/data.hh>
|
||||
#include <broker/expected.hh>
|
||||
|
||||
|
||||
#include "RandTest.h"
|
||||
#include "Val.h"
|
||||
#include "digest.h"
|
||||
#include "src/paraglob.h"
|
||||
|
||||
class OpaqueVal;
|
||||
|
||||
|
@ -319,4 +325,20 @@ private:
|
|||
probabilistic::CardinalityCounter* c;
|
||||
};
|
||||
|
||||
class ParaglobVal : public OpaqueVal {
|
||||
public:
|
||||
explicit ParaglobVal(std::unique_ptr<paraglob::Paraglob> p);
|
||||
VectorVal* Get(StringVal* &pattern);
|
||||
Val* DoClone(CloneState* state) override;
|
||||
bool operator==(const ParaglobVal& other) const;
|
||||
|
||||
protected:
|
||||
ParaglobVal() : OpaqueVal(paraglob_type) {}
|
||||
|
||||
DECLARE_OPAQUE_VALUE(ParaglobVal)
|
||||
|
||||
private:
|
||||
std::unique_ptr<paraglob::Paraglob> internal_paraglob;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -635,6 +635,7 @@ extern OpaqueType* topk_type;
|
|||
extern OpaqueType* bloomfilter_type;
|
||||
extern OpaqueType* x509_opaque_type;
|
||||
extern OpaqueType* ocsp_resp_opaque_type;
|
||||
extern OpaqueType* paraglob_type;
|
||||
|
||||
// Returns the Bro basic (non-parameterized) type with the given type.
|
||||
// The reference count of the type is not increased.
|
||||
|
|
|
@ -118,6 +118,7 @@ OpaqueType* topk_type = 0;
|
|||
OpaqueType* bloomfilter_type = 0;
|
||||
OpaqueType* x509_opaque_type = 0;
|
||||
OpaqueType* ocsp_resp_opaque_type = 0;
|
||||
OpaqueType* paraglob_type = 0;
|
||||
|
||||
// Keep copy of command line
|
||||
int bro_argc;
|
||||
|
@ -786,6 +787,7 @@ int main(int argc, char** argv)
|
|||
bloomfilter_type = new OpaqueType("bloomfilter");
|
||||
x509_opaque_type = new OpaqueType("x509");
|
||||
ocsp_resp_opaque_type = new OpaqueType("ocsp_resp");
|
||||
paraglob_type = new OpaqueType("paraglob");
|
||||
|
||||
// The leak-checker tends to produce some false
|
||||
// positives (memory which had already been
|
||||
|
|
|
@ -555,4 +555,13 @@ void bro_strerror_r(int bro_errno, char* buf, size_t buflen);
|
|||
*/
|
||||
char* zeekenv(const char* name);
|
||||
|
||||
/**
|
||||
* Small convenience function. Does what std::make_unique does in C++14. Will not
|
||||
* work on arrays.
|
||||
*/
|
||||
template <typename T, typename ... Args>
|
||||
std::unique_ptr<T> build_unique (Args&&... args) {
|
||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
70
src/zeek.bif
70
src/zeek.bif
|
@ -789,6 +789,74 @@ function sha256_hash_finish%(handle: opaque of sha256%): string
|
|||
return static_cast<HashVal*>(handle)->Get();
|
||||
%}
|
||||
|
||||
## Initializes and returns a new paraglob.
|
||||
##
|
||||
## v: Vector of patterns to initialize the paraglob with.
|
||||
##
|
||||
## Returns: A new, compiled, paraglob with the patterns in *v*
|
||||
##
|
||||
## .. zeek:see::paraglob_get paraglob_equals paraglob_add
|
||||
function paraglob_init%(v: any%) : opaque of paraglob
|
||||
%{
|
||||
if ( v->Type()->Tag() != TYPE_VECTOR ||
|
||||
v->Type()->YieldType()->Tag() != TYPE_STRING )
|
||||
{
|
||||
// reporter->Error will throw an exception.
|
||||
reporter->Error("paraglob requires a vector of strings for initialization.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::string> patterns;
|
||||
VectorVal* vv = v->AsVectorVal();
|
||||
for ( unsigned int i = 0; i < vv->Size(); ++i )
|
||||
{
|
||||
const BroString* s = vv->Lookup(i)->AsString();
|
||||
patterns.push_back(std::string(reinterpret_cast<const char*>(s->Bytes()), s->Len()));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
std::unique_ptr<paraglob::Paraglob> p (new paraglob::Paraglob(patterns));
|
||||
return new ParaglobVal(std::move(p));
|
||||
}
|
||||
// Thrown if paraglob fails to add a pattern.
|
||||
catch (const paraglob::add_error& e)
|
||||
{
|
||||
reporter->Error("Paraglob failed to add pattern: %s", e.what());
|
||||
return nullptr;
|
||||
}
|
||||
%}
|
||||
|
||||
## Gets all the strings inside the handle associated with an input pattern.
|
||||
##
|
||||
## handle: A compiled paraglob.
|
||||
##
|
||||
## pattern: A glob style pattern.
|
||||
##
|
||||
## Returns: A vector of strings matching the input pattern
|
||||
##
|
||||
## ## .. zeek:see::paraglob_add paraglob_equals paraglob_init
|
||||
function paraglob_get%(handle: opaque of paraglob, pat: string%): string_vec
|
||||
%{
|
||||
return static_cast<ParaglobVal*>(handle)->Get(pat);
|
||||
%}
|
||||
|
||||
## Compares two paraglobs for equality.
|
||||
##
|
||||
## p_one: A compiled paraglob.
|
||||
##
|
||||
## p_two: A compiled paraglob.
|
||||
##
|
||||
## Returns: True if both paraglobs contain the same patterns, false otherwise.
|
||||
##
|
||||
## ## .. zeek:see::paraglob_add paraglob_get paraglob_init
|
||||
function paraglob_equals%(p_one: opaque of paraglob, p_two: opaque of paraglob%) : bool
|
||||
%{
|
||||
return val_mgr->GetBool(
|
||||
*(static_cast<ParaglobVal*>(p_one)) == *(static_cast<ParaglobVal*>(p_two))
|
||||
);
|
||||
%}
|
||||
|
||||
## Returns 32-bit digest of arbitrary input values using FNV-1a hash algorithm.
|
||||
## See `<https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function>`_.
|
||||
##
|
||||
|
@ -3077,7 +3145,7 @@ function strptime%(fmt: string, d: string%) : time
|
|||
const time_t timeval = time_t();
|
||||
struct tm t;
|
||||
|
||||
if ( ! localtime_r(&timeval, &t) ||
|
||||
if ( ! localtime_r(&timeval, &t) ||
|
||||
! strptime(d->CheckString(), fmt->CheckString(), &t) )
|
||||
{
|
||||
reporter->Warning("strptime conversion failed: fmt:%s d:%s", fmt->CheckString(), d->CheckString());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue