mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 10:38: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
|
||||
auto re = new RE_Matcher(val.re_val->PatternText(), val.re_val->AnywherePatternText());
|
||||
re->Compile();
|
||||
return new PatternVal(re);
|
||||
}
|
||||
|
||||
|
@ -2557,7 +2558,14 @@ Val* TableVal::DoClone(CloneState* state)
|
|||
while ( (val = tbl->NextEntry(key, cookie)) )
|
||||
{
|
||||
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);
|
||||
|
||||
if ( subnets )
|
||||
|
@ -3175,17 +3183,22 @@ void RecordVal::DescribeReST(ODesc* d) const
|
|||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return rv;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
{
|
||||
local expect_msg = (equal ? "ok" : "FAIL0");
|
||||
|
@ -11,17 +61,126 @@ function check(o1: any, o2: any, equal: bool, expect_same: bool)
|
|||
|
||||
if ( ! expect_same && same )
|
||||
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()
|
||||
{
|
||||
local i1 = -42;
|
||||
local i2 = copy(i1);
|
||||
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 s2 = copy(s1);
|
||||
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