From 754831d7b0378ce8fb4fbb63a14bce75c40124da Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 17 Feb 2023 12:54:39 +0100 Subject: [PATCH] TableVal: Propagate &ordered through copy() Copying an &ordered table or set would result in a copy that is not ordered. This seems rather surprising behavior, so propagate the &ordered attribute. Closes #2793 --- src/Val.cc | 14 +++++++- .../Baseline/language.set-iteration/.stderr | 1 + .../btest/Baseline/language.set-iteration/out | 25 +++++++++++++++ testing/btest/language/set-iteration.zeek | 32 +++++++++++++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/language.set-iteration/.stderr create mode 100644 testing/btest/Baseline/language.set-iteration/out create mode 100644 testing/btest/language/set-iteration.zeek diff --git a/src/Val.cc b/src/Val.cc index 3890e63361..97afd9c333 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -2619,7 +2619,19 @@ double TableVal::CallExpireFunc(ListValPtr idx) ValPtr TableVal::DoClone(CloneState* state) { - auto tv = make_intrusive(table_type); + // Propagate the &ordered attribute when cloning. + // + // Some of the attributes are dealt with later, but this one needs to be + // passed explicitly to the TableVal constructor so the underlying PDict + // is initialized ordered. + detail::AttributesPtr init_attrs = nullptr; + if ( auto ordered_attr = GetAttr(detail::ATTR_ORDERED) ) + { + init_attrs = zeek::make_intrusive(table_type, false, false); + init_attrs->AddAttr(ordered_attr); + } + + auto tv = make_intrusive(table_type, init_attrs); state->NewClone(this, tv); const PDict* tbl = AsTable(); diff --git a/testing/btest/Baseline/language.set-iteration/.stderr b/testing/btest/Baseline/language.set-iteration/.stderr new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/language.set-iteration/.stderr @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/language.set-iteration/out b/testing/btest/Baseline/language.set-iteration/out new file mode 100644 index 0000000000..e859e0d929 --- /dev/null +++ b/testing/btest/Baseline/language.set-iteration/out @@ -0,0 +1,25 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +sset +2 +3 +1 +4 +5 +copy(sset) +3 +2 +1 +4 +5 +ordered_sset +1 +2 +3 +4 +5 +copy(ordered_sset) +1 +2 +3 +4 +5 diff --git a/testing/btest/language/set-iteration.zeek b/testing/btest/language/set-iteration.zeek new file mode 100644 index 0000000000..274fb917a6 --- /dev/null +++ b/testing/btest/language/set-iteration.zeek @@ -0,0 +1,32 @@ +# @TEST-EXEC: zeek -b %INPUT >out +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff .stderr + +global sset: set[string]; +global ordered_sset: set[string] &ordered; + +event zeek_init() + { + local i = 0; + while ( ++i <= 5 ) + { + add sset[cat(i)]; + add ordered_sset[cat(i)]; + } + + print "sset"; + for ( s in sset ) + print s; + + print "copy(sset)"; + for ( s in copy(sset) ) + print s; + + print "ordered_sset"; + for ( s in ordered_sset ) + print s; + + print "copy(ordered_sset)"; + for ( s in copy(ordered_sset) ) + print s; + }