diff --git a/CHANGES b/CHANGES index f1da6b44d6..4e860d7eca 100644 --- a/CHANGES +++ b/CHANGES @@ -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) diff --git a/VERSION b/VERSION index 142d07f16f..1754da8f31 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2-477 +2.2-478 diff --git a/src/Expr.cc b/src/Expr.cc index b3a4b8b096..8d757fd2dd 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -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)); diff --git a/testing/btest/Baseline/language.record-bad-ctor2/out b/testing/btest/Baseline/language.record-bad-ctor2/out new file mode 100644 index 0000000000..d5ce540dd8 --- /dev/null +++ b/testing/btest/Baseline/language.record-bad-ctor2/out @@ -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]) diff --git a/testing/btest/language/record-bad-ctor2.bro b/testing/btest/language/record-bad-ctor2.bro new file mode 100644 index 0000000000..7941c38860 --- /dev/null +++ b/testing/btest/language/record-bad-ctor2.bro @@ -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;