mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 18:48:20 +00:00
Checkpoint - all non-opaque-types can be cloned.
This commit is contained in:
parent
d13c939233
commit
2efbe76920
2 changed files with 180 additions and 8 deletions
21
src/Val.cc
21
src/Val.cc
|
@ -1216,6 +1216,7 @@ Val* PatternVal::DoClone(CloneState* state)
|
||||||
{
|
{
|
||||||
// TODO: Double-check
|
// TODO: Double-check
|
||||||
auto re = new RE_Matcher(val.re_val->PatternText(), val.re_val->AnywherePatternText());
|
auto re = new RE_Matcher(val.re_val->PatternText(), val.re_val->AnywherePatternText());
|
||||||
|
re->Compile();
|
||||||
return new PatternVal(re);
|
return new PatternVal(re);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2557,7 +2558,14 @@ Val* TableVal::DoClone(CloneState* state)
|
||||||
while ( (val = tbl->NextEntry(key, cookie)) )
|
while ( (val = tbl->NextEntry(key, cookie)) )
|
||||||
{
|
{
|
||||||
Val* idx = RecoverIndex(key);
|
Val* idx = RecoverIndex(key);
|
||||||
TableEntryVal* nval = val ? new TableEntryVal(*val) : nullptr;
|
TableEntryVal* nval = nullptr;
|
||||||
|
if ( val )
|
||||||
|
{
|
||||||
|
if ( val->Value() )
|
||||||
|
nval = new TableEntryVal(val->Value()->Clone());
|
||||||
|
else
|
||||||
|
nval = new TableEntryVal(nullptr);
|
||||||
|
}
|
||||||
tv->AsNonConstTable()->Insert(key, nval);
|
tv->AsNonConstTable()->Insert(key, nval);
|
||||||
|
|
||||||
if ( subnets )
|
if ( subnets )
|
||||||
|
@ -3175,17 +3183,22 @@ void RecordVal::DescribeReST(ODesc* d) const
|
||||||
|
|
||||||
Val* RecordVal::DoClone(CloneState* state)
|
Val* RecordVal::DoClone(CloneState* state)
|
||||||
{
|
{
|
||||||
// TODO: We leave origin unset, ok?
|
// We set origin to 0 here.
|
||||||
|
// Origin only seems to be used for exactly one purpose - to find the connection record that is associated
|
||||||
|
// with a record. As we cannot guarantee that it will ber zeroed out at the approproate time (as it seems to be
|
||||||
|
// guaranteed for the original record) we don't touch it.
|
||||||
::Ref(record_type);
|
::Ref(record_type);
|
||||||
auto rv = new RecordVal(record_type);
|
auto rv = new RecordVal(record_type);
|
||||||
|
rv->origin = nullptr;
|
||||||
|
rv->val.val_list_val = new val_list(val.val_list_val->length());
|
||||||
|
|
||||||
loop_over_list(*val.val_list_val, i)
|
loop_over_list(*val.val_list_val, i)
|
||||||
{
|
{
|
||||||
Val* v = (*val.val_list_val)[i]->Clone(state);
|
Val* v = (*val.val_list_val)[i] ? (*val.val_list_val)[i]->Clone(state) : nullptr;
|
||||||
rv->val.val_list_val->append(v);
|
rv->val.val_list_val->append(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_SERIAL(RecordVal, SER_RECORD_VAL);
|
IMPLEMENT_SERIAL(RecordVal, SER_RECORD_VAL);
|
||||||
|
|
|
@ -1,6 +1,56 @@
|
||||||
# @TEST-EXEC: bro -b %INPUT >out
|
# @TEST-EXEC: zeek -b %INPUT >out
|
||||||
# @TEST-EXEC: btest-diff out
|
# @TEST-EXEC: btest-diff out
|
||||||
|
|
||||||
|
type MyEnum: enum { ENUMME };
|
||||||
|
|
||||||
|
type InnerTestRecord: record {
|
||||||
|
a: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type TestRecord: record {
|
||||||
|
s1: string;
|
||||||
|
s2: string;
|
||||||
|
i1: InnerTestRecord;
|
||||||
|
i2: InnerTestRecord &optional;
|
||||||
|
donotset: InnerTestRecord &optional;
|
||||||
|
def: count &default=5;
|
||||||
|
};
|
||||||
|
|
||||||
|
function join_count_set(ss: set[count], j: string): string
|
||||||
|
{
|
||||||
|
local output="";
|
||||||
|
local i=0;
|
||||||
|
for ( s in ss )
|
||||||
|
{
|
||||||
|
if ( i > 0 )
|
||||||
|
output = cat(output, j);
|
||||||
|
|
||||||
|
output = cat(output, s);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_format(i: any): any
|
||||||
|
{
|
||||||
|
local tpe = type_name(i);
|
||||||
|
|
||||||
|
switch ( tpe )
|
||||||
|
{
|
||||||
|
case "set[count]":
|
||||||
|
return join_count_set(i, ",");
|
||||||
|
case "table[string] of string":
|
||||||
|
local cast: table[string] of string = i;
|
||||||
|
local vout: vector of string = vector();
|
||||||
|
for ( el in cast )
|
||||||
|
{
|
||||||
|
vout += cat(el, "=", cast[el]);
|
||||||
|
}
|
||||||
|
return join_string_vec(vout, ";");
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
function check(o1: any, o2: any, equal: bool, expect_same: bool)
|
function check(o1: any, o2: any, equal: bool, expect_same: bool)
|
||||||
{
|
{
|
||||||
local expect_msg = (equal ? "ok" : "FAIL0");
|
local expect_msg = (equal ? "ok" : "FAIL0");
|
||||||
|
@ -12,16 +62,125 @@ function check(o1: any, o2: any, equal: bool, expect_same: bool)
|
||||||
if ( ! expect_same && same )
|
if ( ! expect_same && same )
|
||||||
expect_msg = "FAIL2";
|
expect_msg = "FAIL2";
|
||||||
|
|
||||||
print fmt("orig=%s (%s) clone=%s (%s) equal=%s same_object=%s (%s)", o1, type_name(o1), o2, type_name(o2), equal, same, expect_msg);
|
print fmt("orig=%s (%s) clone=%s (%s) equal=%s same_object=%s (%s)", do_format(o1), type_name(o1), do_format(o2), type_name(o2), equal, same, expect_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function check_vector_equal(a: vector of count, b: vector of count): bool
|
||||||
|
{
|
||||||
|
if ( |a| != |b| )
|
||||||
|
return F;
|
||||||
|
|
||||||
|
for ( i in a )
|
||||||
|
{
|
||||||
|
if ( a[i] != b[i] )
|
||||||
|
return F;
|
||||||
|
}
|
||||||
|
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_string_table_equal(a: table[string] of string, b: table[string] of string): bool
|
||||||
|
{
|
||||||
|
if ( |a| != |b| )
|
||||||
|
return F;
|
||||||
|
|
||||||
|
for ( i in a )
|
||||||
|
{
|
||||||
|
if ( a[i] != b[i] )
|
||||||
|
return F;
|
||||||
|
}
|
||||||
|
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
|
||||||
|
function compare_otr(a: TestRecord, b: TestRecord): bool
|
||||||
|
{
|
||||||
|
if ( a$s1 != b$s1 )
|
||||||
|
return F;
|
||||||
|
if ( a$s2 != b$s2 )
|
||||||
|
return F;
|
||||||
|
if ( a$i1$a != b$i1$a )
|
||||||
|
return F;
|
||||||
|
if ( a$i2$a != b$i2$a )
|
||||||
|
return F;
|
||||||
|
|
||||||
|
if ( same_object(a$i1, b$i1) )
|
||||||
|
return F;
|
||||||
|
if ( same_object(a$i2, b$i2) )
|
||||||
|
return F;
|
||||||
|
|
||||||
|
# check that we restroe that i1 & i2 point to same object
|
||||||
|
if ( ! same_object(a$i1, a$i2) )
|
||||||
|
return F;
|
||||||
|
if ( ! same_object(b$i1, b$i2) )
|
||||||
|
return F;
|
||||||
|
|
||||||
|
if ( a$def != b$def )
|
||||||
|
return F;
|
||||||
|
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
event zeek_init()
|
event zeek_init()
|
||||||
{
|
{
|
||||||
local i1 = -42;
|
local i1 = -42;
|
||||||
local i2 = copy(i1);
|
local i2 = copy(i1);
|
||||||
check(i1, i2, i1 == i2, T);
|
check(i1, i2, i1 == i2, T);
|
||||||
|
|
||||||
|
local c1 : count = 42;
|
||||||
|
local c2 = copy(c1);
|
||||||
|
check(c1, c2, c1 == c2, T);
|
||||||
|
|
||||||
|
local a1 = 127.0.0.1;
|
||||||
|
local a2 = copy(a1);
|
||||||
|
check(a1, a2, a1 == a2, T);
|
||||||
|
|
||||||
|
local p1 = 42/tcp;
|
||||||
|
local p2 = copy(p1);
|
||||||
|
check(p1, p2, p1 == p2, T);
|
||||||
|
|
||||||
|
local sn1 = 127.0.0.1/24;
|
||||||
|
local sn2 = copy(sn1);
|
||||||
|
check(sn1, sn2, sn1 == sn2, T);
|
||||||
|
|
||||||
local s1 = "Foo";
|
local s1 = "Foo";
|
||||||
local s2 = copy(s1);
|
local s2 = copy(s1);
|
||||||
check(s1, s2, s1 == s2, F);
|
check(s1, s2, s1 == s2, F);
|
||||||
|
|
||||||
|
local pat1 = /.*PATTERN.*/;
|
||||||
|
local pat2 = copy(pat1);
|
||||||
|
# patterns cannot be directoy compared
|
||||||
|
if ( same_object(pat1, pat2) )
|
||||||
|
print "FAIL P1";
|
||||||
|
if ( ! ( pat1 == "PATTERN" ) )
|
||||||
|
print "FAIL P2";
|
||||||
|
if ( ! ( pat2 == "PATTERN" ) )
|
||||||
|
print "FAIL P3";
|
||||||
|
if ( pat2 == "PATERN" )
|
||||||
|
print "FAIL P4";
|
||||||
|
print fmt("orig=%s (%s) clone=%s (%s) same_object=%s", pat1, type_name(pat1), pat2, type_name(pat2), same_object(pat1, pat2));
|
||||||
|
|
||||||
|
local set1 = [1, 2, 3, 4, 5];
|
||||||
|
local set2 = copy(set1);
|
||||||
|
check(set1, set2, set1 == set2, F);
|
||||||
|
|
||||||
|
local v1 = vector(1, 2, 3, 4, 5);
|
||||||
|
local v2 = copy(v1);
|
||||||
|
check(v1, v2, check_vector_equal(v1, v2), F);
|
||||||
|
|
||||||
|
local t1 : table[string] of string = table();
|
||||||
|
t1["a"] = "va";
|
||||||
|
t1["b"] = "vb";
|
||||||
|
local t2 = copy(t1);
|
||||||
|
check(t1, t2, check_string_table_equal(t1, t2), F);
|
||||||
|
|
||||||
|
local e1 = ENUMME;
|
||||||
|
local e2 = copy(ENUMME);
|
||||||
|
check(e1, e2, e1 == e2, T);
|
||||||
|
|
||||||
|
local itr = InnerTestRecord($a="a");
|
||||||
|
local otr1 = TestRecord($s1="s1", $s2="s2", $i1=itr, $i2=itr);
|
||||||
|
local otr2 = copy(otr1);
|
||||||
|
check(otr1, otr2, compare_otr(otr1, otr2), F);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue