mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
enable predicate modification of index of value which is currently being added/removed
Todo: test if this works for removal ( I think it should ).
This commit is contained in:
parent
f73de0bc8c
commit
94d439b0cb
4 changed files with 95 additions and 5 deletions
|
@ -692,6 +692,31 @@ bool Manager::ForceUpdate(const string &name)
|
||||||
return true; // update is async :(
|
return true; // update is async :(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Val* Manager::RecordValToIndexVal(RecordVal *r) {
|
||||||
|
Val* idxval;
|
||||||
|
|
||||||
|
RecordType *type = r->Type()->AsRecordType();
|
||||||
|
|
||||||
|
int num_fields = type->NumFields();
|
||||||
|
|
||||||
|
if ( num_fields == 1 && type->FieldDecl(0)->type->Tag() != TYPE_RECORD ) {
|
||||||
|
idxval = r->Lookup(0);
|
||||||
|
} else {
|
||||||
|
ListVal *l = new ListVal(TYPE_ANY);
|
||||||
|
for ( int j = 0 ; j < num_fields; j++ ) {
|
||||||
|
Val* rval = r->Lookup(j);
|
||||||
|
assert(rval != 0);
|
||||||
|
l->Append(r->LookupWithDefault(j));
|
||||||
|
}
|
||||||
|
idxval = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return idxval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Val* Manager::ValueToIndexVal(int num_fields, const RecordType *type, const Value* const *vals) {
|
Val* Manager::ValueToIndexVal(int num_fields, const RecordType *type, const Value* const *vals) {
|
||||||
Val* idxval;
|
Val* idxval;
|
||||||
int position = 0;
|
int position = 0;
|
||||||
|
@ -788,8 +813,8 @@ int Manager::SendEntryTable(Filter* i, const Value* const *vals) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Val* idxval = ValueToIndexVal(filter->num_idx_fields, filter->itype, vals);
|
|
||||||
Val* valval;
|
Val* valval;
|
||||||
|
RecordVal* predidx = 0;
|
||||||
|
|
||||||
int position = filter->num_idx_fields;
|
int position = filter->num_idx_fields;
|
||||||
if ( filter->num_val_fields == 0 ) {
|
if ( filter->num_val_fields == 0 ) {
|
||||||
|
@ -806,8 +831,10 @@ int Manager::SendEntryTable(Filter* i, const Value* const *vals) {
|
||||||
if ( filter->pred ) {
|
if ( filter->pred ) {
|
||||||
EnumVal* ev;
|
EnumVal* ev;
|
||||||
//Ref(idxval);
|
//Ref(idxval);
|
||||||
int startpos = 0;
|
int startpos = 0;
|
||||||
Val* predidx = ValueToRecordVal(vals, filter->itype, &startpos);
|
//Val* predidx = ListValToRecordVal(idxval->AsListVal(), filter->itype, &startpos);
|
||||||
|
predidx = ValueToRecordVal(vals, filter->itype, &startpos);
|
||||||
|
//ValueToRecordVal(vals, filter->itype, &startpos);
|
||||||
Ref(valval);
|
Ref(valval);
|
||||||
|
|
||||||
if ( updated ) {
|
if ( updated ) {
|
||||||
|
@ -818,13 +845,14 @@ int Manager::SendEntryTable(Filter* i, const Value* const *vals) {
|
||||||
|
|
||||||
bool result;
|
bool result;
|
||||||
if ( filter->num_val_fields > 0 ) { // we have values
|
if ( filter->num_val_fields > 0 ) { // we have values
|
||||||
result = CallPred(filter->pred, 3, ev, predidx, valval);
|
result = CallPred(filter->pred, 3, ev, predidx->Ref(), valval);
|
||||||
} else {
|
} else {
|
||||||
// no values
|
// no values
|
||||||
result = CallPred(filter->pred, 2, ev, predidx);
|
result = CallPred(filter->pred, 2, ev, predidx->Ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( result == false ) {
|
if ( result == false ) {
|
||||||
|
Unref(predidx);
|
||||||
if ( !updated ) {
|
if ( !updated ) {
|
||||||
// throw away. Hence - we quit. And remove the entry from the current dictionary...
|
// throw away. Hence - we quit. And remove the entry from the current dictionary...
|
||||||
delete(filter->currDict->RemoveEntry(idxhash));
|
delete(filter->currDict->RemoveEntry(idxhash));
|
||||||
|
@ -839,6 +867,13 @@ int Manager::SendEntryTable(Filter* i, const Value* const *vals) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Val* idxval;
|
||||||
|
if ( predidx != 0 ) {
|
||||||
|
idxval = RecordValToIndexVal(predidx);
|
||||||
|
Unref(predidx);
|
||||||
|
} else {
|
||||||
|
idxval = ValueToIndexVal(filter->num_idx_fields, filter->itype, vals);
|
||||||
|
}
|
||||||
Val* oldval = 0;
|
Val* oldval = 0;
|
||||||
if ( updated == true ) {
|
if ( updated == true ) {
|
||||||
assert(filter->num_val_fields > 0);
|
assert(filter->num_val_fields > 0);
|
||||||
|
|
|
@ -158,6 +158,7 @@ private:
|
||||||
|
|
||||||
// Converts a threading::value to a record type. mostly used by ValueToVal
|
// Converts a threading::value to a record type. mostly used by ValueToVal
|
||||||
RecordVal* ValueToRecordVal(const threading::Value* const *vals, RecordType *request_type, int* position);
|
RecordVal* ValueToRecordVal(const threading::Value* const *vals, RecordType *request_type, int* position);
|
||||||
|
Val* RecordValToIndexVal(RecordVal *r);
|
||||||
|
|
||||||
// Converts a Bro ListVal to a RecordVal given the record type
|
// Converts a Bro ListVal to a RecordVal given the record type
|
||||||
RecordVal* ListValToRecordVal(ListVal* list, RecordType *request_type, int* position);
|
RecordVal* ListValToRecordVal(ListVal* list, RecordType *request_type, int* position);
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
[2, idxmodified] = [b=T, s=test2],
|
||||||
|
[1, idx1] = [b=T, s=testmodified]
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: bro -b %INPUT >out
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
|
||||||
|
@TEST-START-FILE input.log
|
||||||
|
#separator \x09
|
||||||
|
#path ssh
|
||||||
|
#fields i b s ss
|
||||||
|
#types int bool string string
|
||||||
|
1 T test1 idx1
|
||||||
|
2 T test2 idx2
|
||||||
|
@TEST-END-FILE
|
||||||
|
|
||||||
|
redef InputAscii::empty_field = "EMPTY";
|
||||||
|
|
||||||
|
module A;
|
||||||
|
|
||||||
|
type Idx: record {
|
||||||
|
i: int;
|
||||||
|
ss: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Val: record {
|
||||||
|
b: bool;
|
||||||
|
s: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
global servers: table[int, string] of Val = table();
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
# first read in the old stuff into the table...
|
||||||
|
Input::add_table([$source="input.log", $name="input", $idx=Idx, $val=Val, $destination=servers,
|
||||||
|
$pred(typ: Input::Event, left: Idx, right: Val) = {
|
||||||
|
if ( left$i == 1 ) {
|
||||||
|
right$s = "testmodified";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( left$i == 2 ) {
|
||||||
|
left$ss = "idxmodified";
|
||||||
|
}
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
Input::remove("input");
|
||||||
|
}
|
||||||
|
|
||||||
|
event Input::update_finished(name: string, source: string) {
|
||||||
|
print servers;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue