mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
GH-1328: Improve behavior of Dictionary iterator invalidation
Previously, an assertion was triggered in debug builds upon any attempt to insert or remove a Dictionary entry while any iteration of that Dictionary is underway and also even in cases where Dictionary membership was not actually modified (and thus invalidates a loop). Now, it emits run-time warnings regardless of build-type and only when insert/remove operations truly change the Dictionary membership. In the context of a Zeek script causing an invalidation, the warning message also now helps pinpoint the exact expression that causes it.
This commit is contained in:
parent
9d8bab692c
commit
8f98b068c8
7 changed files with 287 additions and 35 deletions
73
testing/btest/language/table-set-iterator-invalidation.zeek
Normal file
73
testing/btest/language/table-set-iterator-invalidation.zeek
Normal file
|
@ -0,0 +1,73 @@
|
|||
# @TEST-EXEC: zeek -b %INPUT >out 2>&1
|
||||
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out
|
||||
|
||||
# Note that while modifying container membership during for-loop iteration is
|
||||
# supposed to be undefined-behavior, it should be practically ok to have this
|
||||
# test perform such operations if they always `break` out of the loop
|
||||
# immediately afterward.
|
||||
|
||||
local t = table([1] = "one", [2] = "two", [3] = "three");
|
||||
|
||||
for ( i in t )
|
||||
# Modifying an existing element is not qualified an modifying membership,
|
||||
# so this doesn't trigger a warning.
|
||||
t[i] = cat(i);
|
||||
|
||||
print t;
|
||||
|
||||
for ( i in t )
|
||||
{
|
||||
# Adding an element in a loop should trigger a warning.
|
||||
t[4] = "four";
|
||||
break;
|
||||
}
|
||||
|
||||
print t;
|
||||
|
||||
for ( i in t )
|
||||
{
|
||||
# Deleting an element in a loop should trigger a warning.
|
||||
delete t[4];
|
||||
break;
|
||||
}
|
||||
|
||||
print t;
|
||||
|
||||
for ( i in t )
|
||||
# Trying to delete a non-existent element within in a loop does not
|
||||
# actually modify membership, so does not trigger a warning.
|
||||
delete t[0];
|
||||
|
||||
print t;
|
||||
|
||||
local s = set(1, 2, 3);
|
||||
|
||||
for ( n in s )
|
||||
# Trying to add an existing element within in a loop does not
|
||||
# actually modify membership, so does not trigger a warning.
|
||||
add s[1];
|
||||
|
||||
for ( n in s )
|
||||
{
|
||||
# Adding an element in a loop should trigger a warning.
|
||||
add s[4];
|
||||
break;
|
||||
}
|
||||
|
||||
print s;
|
||||
|
||||
for ( n in s )
|
||||
{
|
||||
# Deleting an element in a loop should trigger a warning.
|
||||
delete s[4];
|
||||
break;
|
||||
}
|
||||
|
||||
print s;
|
||||
|
||||
for ( n in s )
|
||||
# Trying to delete a non-existent element within in a loop does not
|
||||
# actually modify membership, so does not trigger a warning.
|
||||
delete s[0];
|
||||
|
||||
print s;
|
Loading…
Add table
Add a link
Reference in a new issue