diff --git a/src/Dict.h b/src/Dict.h index c9ebb84a90..c3443a3ddf 100644 --- a/src/Dict.h +++ b/src/Dict.h @@ -382,7 +382,9 @@ public: pointer operator->() { return &curr; } RobustDictIterator& operator++() { - curr = dict->GetNextRobustIteration(this); + if ( dict ) + curr = dict->GetNextRobustIteration(this); + return *this; } @@ -475,6 +477,7 @@ private: inserted = nullptr; visited = nullptr; dict = nullptr; + curr = nullptr; // make this same as robust_end() } } @@ -765,6 +768,11 @@ public: order.reset(); if ( iterators ) { + // Complete() erases from this Dictionary's iterators member, use a copy. + auto copied_iterators = *iterators; + for ( auto* i : copied_iterators ) + i->Complete(); + delete iterators; iterators = nullptr; } diff --git a/testing/btest/Traces/smb/smb_many_open_files_500.pcap.gz b/testing/btest/Traces/smb/smb_many_open_files_500.pcap.gz new file mode 100644 index 0000000000..574deee82e Binary files /dev/null and b/testing/btest/Traces/smb/smb_many_open_files_500.pcap.gz differ diff --git a/testing/btest/core/dict-iteration-expire-3523.zeek b/testing/btest/core/dict-iteration-expire-3523.zeek new file mode 100644 index 0000000000..843c6b4406 --- /dev/null +++ b/testing/btest/core/dict-iteration-expire-3523.zeek @@ -0,0 +1,14 @@ +# @TEST-EXEC: zcat <$TRACES/smb/smb_many_open_files_500.pcap.gz | zeek -b -Cr - %INPUT +# @TEST-DOC: Regression test #3523; no output check, just shouldn't crash + +redef table_expire_delay = 0.1sec; +redef table_incremental_step = 1; +redef table_expire_interval = 0.1sec; + +redef record connection += { + recent_tcp: set[string] &default=set() &read_expire=3min; +}; + +event new_packet(c: connection, pkt: pkt_hdr) { + add c$recent_tcp[cat(pkt$tcp)]; +}