mirror of
https://github.com/zeek/zeek.git
synced 2025-10-15 13:08:20 +00:00
Fix for a case where nested records weren't coerced even though possible.
This commit is contained in:
parent
005b1505b8
commit
f08ef8350a
3 changed files with 48 additions and 7 deletions
36
src/Expr.cc
36
src/Expr.cc
|
@ -3971,12 +3971,18 @@ RecordCoerceExpr::RecordCoerceExpr(Expr* op, RecordType* r)
|
||||||
|
|
||||||
if ( ! same_type(sup_t_i, sub_t_i) )
|
if ( ! same_type(sup_t_i, sub_t_i) )
|
||||||
{
|
{
|
||||||
char buf[512];
|
if ( sup_t_i->Tag() != TYPE_RECORD ||
|
||||||
safe_snprintf(buf, sizeof(buf),
|
sub_t_i->Tag() != TYPE_RECORD ||
|
||||||
"type clash for field \"%s\"", sub_r->FieldName(i));
|
! record_promotion_compatible(sup_t_i->AsRecordType(),
|
||||||
Error(buf, sub_t_i);
|
sub_t_i->AsRecordType()) )
|
||||||
SetError();
|
{
|
||||||
break;
|
char buf[512];
|
||||||
|
safe_snprintf(buf, sizeof(buf),
|
||||||
|
"type clash for field \"%s\"", sub_r->FieldName(i));
|
||||||
|
Error(buf, sub_t_i);
|
||||||
|
SetError();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
map[t_i] = i;
|
map[t_i] = i;
|
||||||
|
@ -4024,6 +4030,24 @@ Val* RecordCoerceExpr::Fold(Val* v) const
|
||||||
rhs = rhs->Ref();
|
rhs = rhs->Ref();
|
||||||
|
|
||||||
assert(rhs || Type()->AsRecordType()->FieldDecl(i)->FindAttr(ATTR_OPTIONAL));
|
assert(rhs || Type()->AsRecordType()->FieldDecl(i)->FindAttr(ATTR_OPTIONAL));
|
||||||
|
|
||||||
|
BroType* rhs_type = rhs->Type();
|
||||||
|
RecordType* val_type = val->Type()->AsRecordType();
|
||||||
|
BroType* field_type = val_type->FieldType(i);
|
||||||
|
|
||||||
|
if ( rhs_type->Tag() == TYPE_RECORD &&
|
||||||
|
field_type->Tag() == TYPE_RECORD &&
|
||||||
|
! same_type(rhs_type, field_type) )
|
||||||
|
{
|
||||||
|
Val* new_val = rhs->AsRecordVal()->CoerceTo(
|
||||||
|
field_type->AsRecordType());
|
||||||
|
if ( new_val )
|
||||||
|
{
|
||||||
|
Unref(rhs);
|
||||||
|
rhs = new_val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val->Assign(i, rhs);
|
val->Assign(i, rhs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
[major=4, minor=4, minor2=<uninitialized>, addl=<uninitialized>]
|
[major=4, minor=4, minor2=<uninitialized>, addl=<uninitialized>]
|
||||||
|
[c=1, f=[i=2.0 hrs, s=<uninitialized>]]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# @TEST-EXEC: bro %INPUT >output 2>&1
|
# @TEST-EXEC: bro %INPUT >output
|
||||||
# @TEST-EXEC: btest-diff output
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
type Version: record {
|
type Version: record {
|
||||||
|
@ -17,8 +17,24 @@ global matched_software: table[string] of Info = {
|
||||||
["OpenSSH_4.4"] = [$name="OpenSSH", $version=[$major=4,$minor=4]],
|
["OpenSSH_4.4"] = [$name="OpenSSH", $version=[$major=4,$minor=4]],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type Foo: record {
|
||||||
|
i: interval &default=1hr;
|
||||||
|
s: string &optional;
|
||||||
|
};
|
||||||
|
|
||||||
|
type FooContainer: record {
|
||||||
|
c: count;
|
||||||
|
f: Foo &optional;
|
||||||
|
};
|
||||||
|
|
||||||
|
function foo_func(fc: FooContainer)
|
||||||
|
{
|
||||||
|
print fc;
|
||||||
|
}
|
||||||
|
|
||||||
event bro_init()
|
event bro_init()
|
||||||
{
|
{
|
||||||
for ( sw in matched_software )
|
for ( sw in matched_software )
|
||||||
print matched_software[sw]$version;
|
print matched_software[sw]$version;
|
||||||
|
foo_func([$c=1, $f=[$i=2hrs]]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue