mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 10:38:20 +00:00
Merge remote-tracking branch 'origin/topic/timw/3059-set-vector-conversion'
* origin/topic/timw/3059-set-vector-conversion: Fix conversion with record types Add conversion between set and vector using 'as' keyword Add std::move for a couple of variables passed by value
This commit is contained in:
commit
e8ef169b27
11 changed files with 206 additions and 3 deletions
8
CHANGES
8
CHANGES
|
@ -1,3 +1,11 @@
|
||||||
|
6.1.0-dev.293 | 2023-08-11 10:34:52 -0700
|
||||||
|
|
||||||
|
* Fix conversion with record types (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Add conversion between set and vector using 'as' keyword (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
|
* Add std::move for a couple of variables passed by value (Tim Wojtulewicz, Corelight)
|
||||||
|
|
||||||
6.1.0-dev.289 | 2023-08-11 09:52:24 -0700
|
6.1.0-dev.289 | 2023-08-11 09:52:24 -0700
|
||||||
|
|
||||||
* Modbus: Add early return in case of data being too short to parse (Tim Wojtulewicz, Corelight)
|
* Modbus: Add early return in case of data being too short to parse (Tim Wojtulewicz, Corelight)
|
||||||
|
|
5
NEWS
5
NEWS
|
@ -54,6 +54,11 @@ New Functionality
|
||||||
modules by prefixing their names with ``::``. Previously, these required an
|
modules by prefixing their names with ``::``. Previously, these required an
|
||||||
explicit ``GLOBAL::`` prefix to be used. Using ``GLOBAL::`` has been deprecated.
|
explicit ``GLOBAL::`` prefix to be used. Using ``GLOBAL::`` has been deprecated.
|
||||||
|
|
||||||
|
- The ``as`` keyword now supports casting between ``set`` and ``vector`` values
|
||||||
|
with the same element type. Converting ``set`` values with multiple index
|
||||||
|
values is not supported. We plan to extend the use of the ``as`` keyword to
|
||||||
|
support more type conversions in the future.
|
||||||
|
|
||||||
Changed Functionality
|
Changed Functionality
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
6.1.0-dev.289
|
6.1.0-dev.293
|
||||||
|
|
|
@ -3703,7 +3703,7 @@ void TableConstructorExpr::ExprDescribe(ODesc* d) const
|
||||||
SetConstructorExpr::SetConstructorExpr(ListExprPtr constructor_list,
|
SetConstructorExpr::SetConstructorExpr(ListExprPtr constructor_list,
|
||||||
std::unique_ptr<std::vector<AttrPtr>> arg_attrs,
|
std::unique_ptr<std::vector<AttrPtr>> arg_attrs,
|
||||||
TypePtr arg_type, AttributesPtr arg_attrs2)
|
TypePtr arg_type, AttributesPtr arg_attrs2)
|
||||||
: UnaryExpr(EXPR_SET_CONSTRUCTOR, expand_op(constructor_list, arg_type))
|
: UnaryExpr(EXPR_SET_CONSTRUCTOR, expand_op(std::move(constructor_list), arg_type))
|
||||||
{
|
{
|
||||||
if ( IsError() )
|
if ( IsError() )
|
||||||
return;
|
return;
|
||||||
|
@ -3737,7 +3737,7 @@ SetConstructorExpr::SetConstructorExpr(ListExprPtr constructor_list,
|
||||||
if ( arg_attrs )
|
if ( arg_attrs )
|
||||||
SetAttrs(make_intrusive<Attributes>(std::move(*arg_attrs), type, false, false));
|
SetAttrs(make_intrusive<Attributes>(std::move(*arg_attrs), type, false, false));
|
||||||
else
|
else
|
||||||
SetAttrs(arg_attrs2);
|
SetAttrs(std::move(arg_attrs2));
|
||||||
|
|
||||||
const auto& indices = type->AsTableType()->GetIndices()->GetTypes();
|
const auto& indices = type->AsTableType()->GetIndices()->GetTypes();
|
||||||
ExprPList& cle = op->AsListExpr()->Exprs();
|
ExprPList& cle = op->AsListExpr()->Exprs();
|
||||||
|
|
79
src/Val.cc
79
src/Val.cc
|
@ -4282,7 +4282,78 @@ ValPtr cast_value_to_type(Val* v, Type* t)
|
||||||
return static_cast<Broker::detail::DataVal*>(dv.get())->castTo(t);
|
return static_cast<Broker::detail::DataVal*>(dv.get())->castTo(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow casting between sets and vectors if the yield types are the same.
|
||||||
|
if ( v->GetType()->IsSet() && IsVector(t->Tag()) )
|
||||||
|
{
|
||||||
|
auto set_type = v->GetType<SetType>();
|
||||||
|
auto indices = set_type->GetIndices();
|
||||||
|
|
||||||
|
if ( indices->GetTypes().size() > 1 )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
auto ret_type = IntrusivePtr<VectorType>{NewRef{}, t->AsVectorType()};
|
||||||
|
auto ret = make_intrusive<VectorVal>(ret_type);
|
||||||
|
|
||||||
|
auto* table = v->AsTable();
|
||||||
|
auto* tval = v->AsTableVal();
|
||||||
|
int index = 0;
|
||||||
|
for ( const auto& te : *table )
|
||||||
|
{
|
||||||
|
auto k = te.GetHashKey();
|
||||||
|
auto lv = tval->RecreateIndex(*k);
|
||||||
|
ValPtr entry_key = lv->Length() == 1 ? lv->Idx(0) : lv;
|
||||||
|
ret->Assign(index, entry_key);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else if ( IsVector(v->GetType()->Tag()) && t->IsSet() )
|
||||||
|
{
|
||||||
|
auto ret_type = IntrusivePtr<TableType>{NewRef{}, t->AsSetType()};
|
||||||
|
auto ret = make_intrusive<TableVal>(ret_type);
|
||||||
|
|
||||||
|
auto vv = v->AsVectorVal();
|
||||||
|
size_t size = vv->Size();
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < size; i++ )
|
||||||
|
{
|
||||||
|
auto ve = vv->ValAt(i);
|
||||||
|
ret->Assign(std::move(ve), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool can_cast_set_and_vector(const Type* t1, const Type* t2)
|
||||||
|
{
|
||||||
|
const TableType* st = nullptr;
|
||||||
|
const VectorType* vt = nullptr;
|
||||||
|
|
||||||
|
if ( t1->IsSet() && IsVector(t2->Tag()) )
|
||||||
|
{
|
||||||
|
st = t1->AsSetType();
|
||||||
|
vt = t2->AsVectorType();
|
||||||
|
}
|
||||||
|
else if ( IsVector(t1->Tag()) && t2->IsSet() )
|
||||||
|
{
|
||||||
|
st = t2->AsSetType();
|
||||||
|
vt = t1->AsVectorType();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( st && vt )
|
||||||
|
{
|
||||||
|
auto set_indices = st->GetIndices()->GetTypes();
|
||||||
|
if ( set_indices.size() > 1 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return same_type(set_indices[0], vt->Yield());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool can_cast_value_to_type(const Val* v, Type* t)
|
bool can_cast_value_to_type(const Val* v, Type* t)
|
||||||
|
@ -4308,6 +4379,10 @@ bool can_cast_value_to_type(const Val* v, Type* t)
|
||||||
return static_cast<const Broker::detail::DataVal*>(dv.get())->canCastTo(t);
|
return static_cast<const Broker::detail::DataVal*>(dv.get())->canCastTo(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow casting between sets and vectors if the yield types are the same.
|
||||||
|
if ( can_cast_set_and_vector(v->GetType().get(), t) )
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4327,6 +4402,10 @@ bool can_cast_value_to_type(const Type* s, Type* t)
|
||||||
// will.
|
// will.
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// Allow casting between sets and vectors if the yield types are the same.
|
||||||
|
if ( can_cast_set_and_vector(s, t) )
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
error in <...>/vector-set-conversions-errors.zeek, line 8: cast not supported (v1 as set[addr])
|
||||||
|
error in <...>/vector-set-conversions-errors.zeek, line 15: cast not supported (s2 as vector of addr)
|
||||||
|
error in <...>/vector-set-conversions-errors.zeek, line 22: cast not supported (s3 as vector of port)
|
|
@ -0,0 +1 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
|
@ -0,0 +1 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
39
testing/btest/Baseline/language.vector-set-conversions/out
Normal file
39
testing/btest/Baseline/language.vector-set-conversions/out
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
vector to set
|
||||||
|
[1, 1, 1, 2, 2, 3, 3, 4]
|
||||||
|
{
|
||||||
|
4,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
set to vector (count)
|
||||||
|
{
|
||||||
|
4,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
1
|
||||||
|
}
|
||||||
|
[4, 2, 3, 1]
|
||||||
|
|
||||||
|
set to vector (port)
|
||||||
|
{
|
||||||
|
23/tcp,
|
||||||
|
21/tcp
|
||||||
|
}
|
||||||
|
[23/tcp, 21/tcp]
|
||||||
|
|
||||||
|
set to vector (record)
|
||||||
|
{
|
||||||
|
[a=a, b=b],
|
||||||
|
[a=a1, b=b1]
|
||||||
|
}
|
||||||
|
{
|
||||||
|
[a=a, b=b],
|
||||||
|
[a=a1, b=b1]
|
||||||
|
}
|
||||||
|
|
||||||
|
vector to set (record)
|
||||||
|
[[a=a, b=b], [a=a1, b=b1]]
|
||||||
|
[[a=a, b=b], [a=a1, b=b1]]
|
24
testing/btest/language/vector-set-conversions-errors.zeek
Normal file
24
testing/btest/language/vector-set-conversions-errors.zeek
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# @TEST-DOC: Test error cases while converting between sets and vectorswith the 'as' keyword
|
||||||
|
# @TEST-EXEC-FAIL: zeek -b %INPUT > out
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
# @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-abspath" btest-diff .stderr
|
||||||
|
|
||||||
|
print("vector to set: type mismatch");
|
||||||
|
local v1 = vector(1, 1, 1, 2, 2, 3, 3, 4);
|
||||||
|
local s1 = v1 as set[addr];
|
||||||
|
print(v1);
|
||||||
|
print(s1);
|
||||||
|
|
||||||
|
print("");
|
||||||
|
print("set to vector: type mismatch");
|
||||||
|
local s2 = set(1, 2, 3, 4);
|
||||||
|
local v2 = s2 as vector of addr;
|
||||||
|
print(s2);
|
||||||
|
print(v2);
|
||||||
|
|
||||||
|
print("");
|
||||||
|
print("set to vector: multiple indices");
|
||||||
|
local s3: set[port,string] = { [21/tcp, "ftp"], [23/tcp, "telnet"] };
|
||||||
|
local v3 = s3 as vector of port;
|
||||||
|
print(s3);
|
||||||
|
print(v3);
|
42
testing/btest/language/vector-set-conversions.zeek
Normal file
42
testing/btest/language/vector-set-conversions.zeek
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
# @TEST-DOC: Tests converting between sets and vectors with the 'as' keyword
|
||||||
|
# @TEST-EXEC: zeek -b %INPUT > out
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
# @TEST-EXEC: btest-diff .stderr
|
||||||
|
|
||||||
|
type r: record {
|
||||||
|
a: string;
|
||||||
|
b: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
print("vector to set");
|
||||||
|
local v1 = vector(1, 1, 1, 2, 2, 3, 3, 4);
|
||||||
|
local s1 = v1 as set[count];
|
||||||
|
print(v1);
|
||||||
|
print(s1);
|
||||||
|
|
||||||
|
print("");
|
||||||
|
print("set to vector (count)");
|
||||||
|
local s2 = set(1, 2, 3, 4);
|
||||||
|
local v2 = s2 as vector of count;
|
||||||
|
print(s2);
|
||||||
|
print(v2);
|
||||||
|
|
||||||
|
print("");
|
||||||
|
print("set to vector (port)");
|
||||||
|
local s3 = set(21/tcp, 23/tcp);
|
||||||
|
local v3 = s3 as vector of port;
|
||||||
|
print(s3);
|
||||||
|
print(v3);
|
||||||
|
|
||||||
|
local s: set[r] = set([$a="a", $b="b"], [$a="a1", $b="b1"]);
|
||||||
|
local v: vector of r = vector([$a="a", $b="b"], [$a="a1", $b="b1"]);
|
||||||
|
|
||||||
|
print("");
|
||||||
|
print("set to vector (record)");
|
||||||
|
print s;
|
||||||
|
print v as set[r];
|
||||||
|
|
||||||
|
print("");
|
||||||
|
print("vector to set (record)");
|
||||||
|
print v;
|
||||||
|
print s as vector of r;
|
Loading…
Add table
Add a link
Reference in a new issue