mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
CompositeHash: Skip record initialization when recovering vals
Initializing fields of recovered records caused running &default expression of fields just so that they are re-assigned in the next step with the recovered fields. The second test case still shows that the loop var is initialized as well even though that's not needed. Add tests for iterating over records with &default attributes for both, tables and vectors. Fixes #3267
This commit is contained in:
parent
057bc673a8
commit
aaa81cae5d
9 changed files with 229 additions and 2 deletions
|
@ -359,10 +359,11 @@ bool CompositeHash::RecoverOneVal(const HashKey& hk, Type* t, ValPtr* pval, bool
|
||||||
|
|
||||||
ASSERT(int(values.size()) == num_fields);
|
ASSERT(int(values.size()) == num_fields);
|
||||||
|
|
||||||
auto rv = make_intrusive<RecordVal>(IntrusivePtr{NewRef{}, rt});
|
auto rv = make_intrusive<RecordVal>(IntrusivePtr{NewRef{}, rt},
|
||||||
|
false /* init_fields */);
|
||||||
|
|
||||||
for ( int i = 0; i < num_fields; ++i )
|
for ( int i = 0; i < num_fields; ++i )
|
||||||
rv->Assign(i, std::move(values[i]));
|
rv->AppendField(std::move(values[i]), rt->GetFieldType(i));
|
||||||
|
|
||||||
*pval = std::move(rv);
|
*pval = std::move(rv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1444,6 +1444,7 @@ protected:
|
||||||
friend class zeek::detail::ValTrace;
|
friend class zeek::detail::ValTrace;
|
||||||
friend class zeek::detail::ZBody;
|
friend class zeek::detail::ZBody;
|
||||||
friend class zeek::detail::CPPRuntime;
|
friend class zeek::detail::CPPRuntime;
|
||||||
|
friend class zeek::detail::CompositeHash;
|
||||||
|
|
||||||
RecordValPtr DoCoerceTo(RecordTypePtr other, bool allow_orphaning) const;
|
RecordValPtr DoCoerceTo(RecordTypePtr other, bool allow_orphaning) const;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
0, done parsing
|
||||||
|
0, my_seq() invoked
|
||||||
|
1, populating table, expecting 4 my_seq() invocations
|
||||||
|
1, my_seq() invoked
|
||||||
|
2, my_seq() invoked
|
||||||
|
3, my_seq() invoked
|
||||||
|
4, my_seq() invoked
|
||||||
|
5, iterating table, expecting no my_seq() invocations
|
||||||
|
5, it, [id=4], 3
|
||||||
|
5, it, [id=5], 4
|
||||||
|
5, it, [id=3], 2
|
||||||
|
5, it, [id=2], 1
|
||||||
|
5, done
|
|
@ -0,0 +1,19 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
0, done parsing
|
||||||
|
0, my_seq() invoked
|
||||||
|
1, my_seq() invoked
|
||||||
|
2, populating table, expecting 8 my_seq() invocations
|
||||||
|
2, my_seq() invoked
|
||||||
|
3, my_seq() invoked
|
||||||
|
4, my_seq() invoked
|
||||||
|
5, my_seq() invoked
|
||||||
|
6, my_seq() invoked
|
||||||
|
7, my_seq() invoked
|
||||||
|
8, my_seq() invoked
|
||||||
|
9, my_seq() invoked
|
||||||
|
10, iterating table, expecting no my_seq() invocations
|
||||||
|
10, it, [id=8], [id=7]
|
||||||
|
10, it, [id=6], [id=5]
|
||||||
|
10, it, [id=4], [id=3]
|
||||||
|
10, it, [id=10], [id=9]
|
||||||
|
10, done
|
|
@ -0,0 +1,12 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
0, populating table, expecting 4 my_seq() invocations
|
||||||
|
0, my_seq() invoked
|
||||||
|
1, my_seq() invoked
|
||||||
|
2, my_seq() invoked
|
||||||
|
3, my_seq() invoked
|
||||||
|
4, iterating table, expecting no my_seq() invocations
|
||||||
|
4, it, [id=1], 1
|
||||||
|
4, it, [id=4], 4
|
||||||
|
4, it, [id=3], 3
|
||||||
|
4, it, [id=2], 2
|
||||||
|
4, done
|
|
@ -0,0 +1,14 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
0, done parsing
|
||||||
|
0, my_seq() invoked
|
||||||
|
1, populating vector, expecting 4 my_seq() invocations
|
||||||
|
1, my_seq() invoked
|
||||||
|
2, my_seq() invoked
|
||||||
|
3, my_seq() invoked
|
||||||
|
4, my_seq() invoked
|
||||||
|
5, iterating vector, expecting no my_seq() invocations
|
||||||
|
5, it, 0, [id=2]
|
||||||
|
5, it, 1, [id=3]
|
||||||
|
5, it, 2, [id=4]
|
||||||
|
5, it, 3, [id=5]
|
||||||
|
5, done
|
|
@ -0,0 +1,12 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
0, populating vector, expecting 4 my_seq() invocations
|
||||||
|
0, my_seq() invoked
|
||||||
|
1, my_seq() invoked
|
||||||
|
2, my_seq() invoked
|
||||||
|
3, my_seq() invoked
|
||||||
|
4, iterating vector, expecting no my_seq() invocations
|
||||||
|
4, it, 0, [id=1]
|
||||||
|
4, it, 1, [id=2]
|
||||||
|
4, it, 2, [id=3]
|
||||||
|
4, it, 3, [id=4]
|
||||||
|
4, done
|
95
testing/btest/language/table-iterate-record-key-default.zeek
Normal file
95
testing/btest/language/table-iterate-record-key-default.zeek
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
# @TEST-DOC: Iterating over tables with record keys would previously evaluate &default during each iteration. Ensure this isn't happening. Regression test for #3267.
|
||||||
|
# @TEST-EXEC: zeek -b %INPUT >output
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
|
global seq = 0;
|
||||||
|
function my_seq(): count {
|
||||||
|
print seq, "my_seq() invoked";
|
||||||
|
return ++seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
type R: record {
|
||||||
|
id: count &default=my_seq();
|
||||||
|
};
|
||||||
|
|
||||||
|
global tbl: table[R] of count;
|
||||||
|
|
||||||
|
print seq, "populating table, expecting 4 my_seq() invocations";
|
||||||
|
|
||||||
|
tbl[R()] = 1;
|
||||||
|
tbl[R()] = 2;
|
||||||
|
tbl[R()] = 3;
|
||||||
|
tbl[R()] = 4;
|
||||||
|
|
||||||
|
print seq, "iterating table, expecting no my_seq() invocations";
|
||||||
|
for ( [r], c in tbl )
|
||||||
|
print seq, "it", r, c;
|
||||||
|
|
||||||
|
print seq, "done";
|
||||||
|
|
||||||
|
# @TEST-START-NEXT
|
||||||
|
#
|
||||||
|
# This acts subtly different - my_seq() is called maybe for the [r] local
|
||||||
|
# in the for loop?!
|
||||||
|
global seq = 0;
|
||||||
|
function my_seq(): count {
|
||||||
|
print seq, "my_seq() invoked";
|
||||||
|
return ++seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
type R: record {
|
||||||
|
id: count &default=my_seq();
|
||||||
|
};
|
||||||
|
|
||||||
|
global tbl: table[R] of count;
|
||||||
|
|
||||||
|
event zeek_init()
|
||||||
|
{
|
||||||
|
print seq, "populating table, expecting 4 my_seq() invocations";
|
||||||
|
|
||||||
|
tbl[R()] = 1;
|
||||||
|
tbl[R()] = 2;
|
||||||
|
tbl[R()] = 3;
|
||||||
|
tbl[R()] = 4;
|
||||||
|
|
||||||
|
print seq, "iterating table, expecting no my_seq() invocations";
|
||||||
|
for ( [r], c in tbl )
|
||||||
|
print seq, "it", r, c;
|
||||||
|
|
||||||
|
print seq, "done";
|
||||||
|
}
|
||||||
|
|
||||||
|
print seq, "done parsing";
|
||||||
|
|
||||||
|
# @TEST-START-NEXT
|
||||||
|
#
|
||||||
|
# table[R] of R
|
||||||
|
global seq = 0;
|
||||||
|
function my_seq(): count {
|
||||||
|
print seq, "my_seq() invoked";
|
||||||
|
return ++seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
type R: record {
|
||||||
|
id: count &default=my_seq();
|
||||||
|
};
|
||||||
|
|
||||||
|
global tbl: table[R] of R;
|
||||||
|
|
||||||
|
event zeek_init()
|
||||||
|
{
|
||||||
|
print seq, "populating table, expecting 8 my_seq() invocations";
|
||||||
|
|
||||||
|
tbl[R()] = R();
|
||||||
|
tbl[R()] = R();
|
||||||
|
tbl[R()] = R();
|
||||||
|
tbl[R()] = R();
|
||||||
|
|
||||||
|
print seq, "iterating table, expecting no my_seq() invocations";
|
||||||
|
for ( [r1], r2 in tbl )
|
||||||
|
print seq, "it", r1, r2;
|
||||||
|
|
||||||
|
print seq, "done";
|
||||||
|
}
|
||||||
|
|
||||||
|
print seq, "done parsing";
|
59
testing/btest/language/vector-iterate-record-default.zeek
Normal file
59
testing/btest/language/vector-iterate-record-default.zeek
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
# @TEST-DOC: Iterating over vectors holding record. This mirrors table-iterate-record-key-default, but for vectors. They didn't have the same issue. Regression test for #3267.
|
||||||
|
# @TEST-EXEC: zeek -b %INPUT >output
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
|
global seq = 0;
|
||||||
|
function my_seq(): count {
|
||||||
|
print seq, "my_seq() invoked";
|
||||||
|
return ++seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
type R: record {
|
||||||
|
id: count &default=my_seq();
|
||||||
|
};
|
||||||
|
|
||||||
|
global vec: vector of R;
|
||||||
|
|
||||||
|
print seq, "populating vector, expecting 4 my_seq() invocations";
|
||||||
|
vec += R();
|
||||||
|
vec += R();
|
||||||
|
vec += R();
|
||||||
|
vec += R();
|
||||||
|
|
||||||
|
print seq, "iterating vector, expecting no my_seq() invocations";
|
||||||
|
for ( i, r in vec )
|
||||||
|
print seq, "it", i, r;
|
||||||
|
|
||||||
|
print seq, "done";
|
||||||
|
|
||||||
|
# @TEST-START-NEXT
|
||||||
|
#
|
||||||
|
# Same as above, but populate / iterate record in zeek_init.
|
||||||
|
global seq = 0;
|
||||||
|
function my_seq(): count {
|
||||||
|
print seq, "my_seq() invoked";
|
||||||
|
return ++seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
type R: record {
|
||||||
|
id: count &default=my_seq();
|
||||||
|
};
|
||||||
|
|
||||||
|
global vec: vector of R;
|
||||||
|
|
||||||
|
event zeek_init()
|
||||||
|
{
|
||||||
|
print seq, "populating vector, expecting 4 my_seq() invocations";
|
||||||
|
vec += R();
|
||||||
|
vec += R();
|
||||||
|
vec += R();
|
||||||
|
vec += R();
|
||||||
|
|
||||||
|
print seq, "iterating vector, expecting no my_seq() invocations";
|
||||||
|
for ( i, r in vec )
|
||||||
|
print seq, "it", i, r;
|
||||||
|
|
||||||
|
print seq, "done";
|
||||||
|
}
|
||||||
|
|
||||||
|
print seq, "done parsing";
|
Loading…
Add table
Add a link
Reference in a new issue