Change record ctors to only allow record-field-assignment expressions.

Previously, any expression that evaluates to a record may have been used
in a record ctor's expression list.  This didn't work in all cases,
doesn't provide any unique functionality that can't be done otherwise,
and is possibly a path to introducing subtle scripting errors.

BIT-1192 #closed
This commit is contained in:
Jon Siwek 2014-05-19 15:31:33 -05:00
parent aa81825104
commit aee708c703
5 changed files with 30 additions and 23 deletions

View file

@ -1,4 +1,9 @@
2.2-478 | 2014-05-19 15:31:33 -0500
* Change record ctors to only allow record-field-assignment
expressions. (Jon Siwek)
2.2-477 | 2014-05-19 14:13:00 -0500
* Fix X509::Result record's "result" field to be set internally as type int instead of type count. (Bernhard Amann)

View file

@ -1 +1 @@
2.2-477
2.2-478

View file

@ -3398,8 +3398,8 @@ RecordConstructorExpr::RecordConstructorExpr(ListExpr* constructor_list)
if ( IsError() )
return;
// Spin through the list, which should be comprised of
// either record's or record-field-assign, and build up a
// Spin through the list, which should be comprised only of
// record-field-assign expressions, and build up a
// record type to associate with this constructor.
type_decl_list* record_types = new type_decl_list;
@ -3409,32 +3409,17 @@ RecordConstructorExpr::RecordConstructorExpr(ListExpr* constructor_list)
Expr* e = exprs[i];
BroType* t = e->Type();
if ( e->Tag() == EXPR_FIELD_ASSIGN )
{
FieldAssignExpr* field = (FieldAssignExpr*) e;
BroType* field_type = field->Type()->Ref();
char* field_name = copy_string(field->FieldName());
record_types->append(new TypeDecl(field_type, field_name));
continue;
}
if ( t->Tag() != TYPE_RECORD )
if ( e->Tag() != EXPR_FIELD_ASSIGN )
{
Error("bad type in record constructor", e);
SetError();
continue;
}
// It's a record - add in its fields.
const RecordType* rt = t->AsRecordType();
int n = rt->NumFields();
for ( int j = 0; j < n; ++j )
{
const TypeDecl* td = rt->FieldDecl(j);
record_types->append(new TypeDecl(td->type->Ref(), td->id));
}
FieldAssignExpr* field = (FieldAssignExpr*) e;
BroType* field_type = field->Type()->Ref();
char* field_name = copy_string(field->FieldName());
record_types->append(new TypeDecl(field_type, field_name));
}
SetType(new RecordType(record_types));

View file

@ -0,0 +1 @@
error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.record-bad-ctor2/record-bad-ctor2.bro, line 14: bad type in record constructor ([[$cmd=echo hi]] and [$cmd=echo hi])

View file

@ -0,0 +1,16 @@
# @TEST-EXEC-FAIL: bro -b %INPUT >out 2>&1
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out
# Record ctor's expression list shouldn't accept "expressions that
# eval in to record". The expression list should only be comprised of
# record-field-assignment expressions.
type myrec: record {
cmd: string;
stdin: string &default="";
read_files: string &optional;
};
local bad = myrec([$cmd="echo hi"]);
print bad;