diff --git a/.clang-format b/.clang-format index 394707c91a..79910187b2 100644 --- a/.clang-format +++ b/.clang-format @@ -47,7 +47,7 @@ ColumnLimit: 100 ConstructorInitializerAllOnOneLineOrOnePerLine: false FixNamespaceComments: false IndentCaseLabels: true -IndentCaseBlocks: true +IndentCaseBlocks: false IndentExternBlock: NoIndent IndentPPDirectives: None IndentWidth: 4 diff --git a/src/Attr.cc b/src/Attr.cc index d5a25cfc1e..b0d2947a00 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -317,58 +317,96 @@ void Attributes::CheckAttr(Attr* a) case ATTR_ADD_FUNC: case ATTR_DEL_FUNC: + { + bool is_add = a->Tag() == ATTR_ADD_FUNC; + + const auto& at = a->GetExpr()->GetType(); + if ( at->Tag() != TYPE_FUNC ) { - bool is_add = a->Tag() == ATTR_ADD_FUNC; - - const auto& at = a->GetExpr()->GetType(); - if ( at->Tag() != TYPE_FUNC ) - { - a->GetExpr()->Error(is_add ? "&add_func must be a function" - : "&delete_func must be a function"); - break; - } - - FuncType* aft = at->AsFuncType(); - if ( ! same_type(aft->Yield(), type) ) - { - a->GetExpr()->Error( - is_add ? "&add_func function must yield same type as variable" - : "&delete_func function must yield same type as variable"); - break; - } + a->GetExpr()->Error(is_add ? "&add_func must be a function" + : "&delete_func must be a function"); + break; } + + FuncType* aft = at->AsFuncType(); + if ( ! same_type(aft->Yield(), type) ) + { + a->GetExpr()->Error(is_add + ? "&add_func function must yield same type as variable" + : "&delete_func function must yield same type as variable"); + break; + } + } break; case ATTR_DEFAULT: + { + // &default is allowed for global tables, since it's used in initialization + // of table fields. it's not allowed otherwise. + if ( global_var && ! type->IsTable() ) { - // &default is allowed for global tables, since it's used in initialization - // of table fields. it's not allowed otherwise. - if ( global_var && ! type->IsTable() ) + Error("&default is not valid for global variables except for tables"); + break; + } + + const auto& atype = a->GetExpr()->GetType(); + + if ( type->Tag() != TYPE_TABLE || (type->IsSet() && ! in_record) ) + { + if ( same_type(atype, type) ) + // Ok. + break; + + // Record defaults may be promotable. + if ( (type->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD && + record_promotion_compatible(atype->AsRecordType(), type->AsRecordType())) ) + // Ok. + break; + + if ( type->Tag() == TYPE_TABLE && type->AsTableType()->IsUnspecifiedTable() ) + // Ok. + break; + + auto e = check_and_promote_expr(a->GetExpr(), type); + + if ( e ) { - Error("&default is not valid for global variables except for tables"); + a->SetAttrExpr(std::move(e)); + // Ok. break; } - const auto& atype = a->GetExpr()->GetType(); + a->GetExpr()->Error("&default value has inconsistent type", type.get()); + return; + } - if ( type->Tag() != TYPE_TABLE || (type->IsSet() && ! in_record) ) + TableType* tt = type->AsTableType(); + const auto& ytype = tt->Yield(); + + if ( ! in_record ) + { + // &default applies to the type itself. + if ( ! same_type(atype, ytype) ) { - if ( same_type(atype, type) ) + // It can still be a default function. + if ( atype->Tag() == TYPE_FUNC ) + { + FuncType* f = atype->AsFuncType(); + if ( ! f->CheckArgs(tt->GetIndexTypes()) || ! same_type(f->Yield(), ytype) ) + Error("&default function type clash"); + // Ok. break; + } - // Record defaults may be promotable. - if ( (type->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD && + // Table defaults may be promotable. + if ( (ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD && record_promotion_compatible(atype->AsRecordType(), - type->AsRecordType())) ) + ytype->AsRecordType())) ) // Ok. break; - if ( type->Tag() == TYPE_TABLE && type->AsTableType()->IsUnspecifiedTable() ) - // Ok. - break; - - auto e = check_and_promote_expr(a->GetExpr(), type); + auto e = check_and_promote_expr(a->GetExpr(), ytype); if ( e ) { @@ -377,120 +415,79 @@ void Attributes::CheckAttr(Attr* a) break; } - a->GetExpr()->Error("&default value has inconsistent type", type.get()); - return; + Error("&default value has inconsistent type 2"); } - TableType* tt = type->AsTableType(); - const auto& ytype = tt->Yield(); + // Ok. + break; + } - if ( ! in_record ) - { - // &default applies to the type itself. - if ( ! same_type(atype, ytype) ) - { - // It can still be a default function. - if ( atype->Tag() == TYPE_FUNC ) - { - FuncType* f = atype->AsFuncType(); - if ( ! f->CheckArgs(tt->GetIndexTypes()) || - ! same_type(f->Yield(), ytype) ) - Error("&default function type clash"); - - // Ok. - break; - } - - // Table defaults may be promotable. - if ( (ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD && - record_promotion_compatible(atype->AsRecordType(), - ytype->AsRecordType())) ) - // Ok. - break; - - auto e = check_and_promote_expr(a->GetExpr(), ytype); - - if ( e ) - { - a->SetAttrExpr(std::move(e)); - // Ok. - break; - } - - Error("&default value has inconsistent type 2"); - } + else + { + // &default applies to record field. + if ( same_type(atype, type) ) // Ok. break; - } - else + if ( (atype->Tag() == TYPE_TABLE && atype->AsTableType()->IsUnspecifiedTable()) ) { - // &default applies to record field. + auto e = check_and_promote_expr(a->GetExpr(), type); - if ( same_type(atype, type) ) - // Ok. - break; - - if ( (atype->Tag() == TYPE_TABLE && - atype->AsTableType()->IsUnspecifiedTable()) ) + if ( e ) { - auto e = check_and_promote_expr(a->GetExpr(), type); - - if ( e ) - { - a->SetAttrExpr(std::move(e)); - break; - } - } - - // Table defaults may be promotable. - if ( ytype && ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD && - record_promotion_compatible(atype->AsRecordType(), ytype->AsRecordType()) ) - // Ok. + a->SetAttrExpr(std::move(e)); break; - - Error("&default value has inconsistent type"); + } } + + // Table defaults may be promotable. + if ( ytype && ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD && + record_promotion_compatible(atype->AsRecordType(), ytype->AsRecordType()) ) + // Ok. + break; + + Error("&default value has inconsistent type"); } + } break; case ATTR_EXPIRE_READ: - { - if ( Find(ATTR_BROKER_STORE) ) - Error("&broker_store and &read_expire cannot be used simultaneously"); + { + if ( Find(ATTR_BROKER_STORE) ) + Error("&broker_store and &read_expire cannot be used simultaneously"); - if ( Find(ATTR_BACKEND) ) - Error("&backend and &read_expire cannot be used simultaneously"); - } + if ( Find(ATTR_BACKEND) ) + Error("&backend and &read_expire cannot be used simultaneously"); + } // fallthrough case ATTR_EXPIRE_WRITE: case ATTR_EXPIRE_CREATE: + { + if ( type->Tag() != TYPE_TABLE ) { - if ( type->Tag() != TYPE_TABLE ) - { - Error("expiration only applicable to sets/tables"); - break; - } - - int num_expires = 0; - - for ( const auto& a : attrs ) - { - if ( a->Tag() == ATTR_EXPIRE_READ || a->Tag() == ATTR_EXPIRE_WRITE || - a->Tag() == ATTR_EXPIRE_CREATE ) - num_expires++; - } - - if ( num_expires > 1 ) - { - Error("set/table can only have one of &read_expire, &write_expire, " - "&create_expire"); - break; - } + Error("expiration only applicable to sets/tables"); + break; } + int num_expires = 0; + + for ( const auto& a : attrs ) + { + if ( a->Tag() == ATTR_EXPIRE_READ || a->Tag() == ATTR_EXPIRE_WRITE || + a->Tag() == ATTR_EXPIRE_CREATE ) + num_expires++; + } + + if ( num_expires > 1 ) + { + Error("set/table can only have one of &read_expire, &write_expire, " + "&create_expire"); + break; + } + } + #if 0 //### not easy to test this w/o knowing the ID. if ( ! global_var ) @@ -500,172 +497,172 @@ void Attributes::CheckAttr(Attr* a) break; case ATTR_EXPIRE_FUNC: + { + if ( type->Tag() != TYPE_TABLE ) { - if ( type->Tag() != TYPE_TABLE ) - { - Error("expiration only applicable to tables"); - break; - } - - type->AsTableType()->CheckExpireFuncCompatibility({NewRef{}, a}); - - if ( Find(ATTR_BROKER_STORE) ) - Error("&broker_store and &expire_func cannot be used simultaneously"); - - if ( Find(ATTR_BACKEND) ) - Error("&backend and &expire_func cannot be used simultaneously"); - + Error("expiration only applicable to tables"); break; } + type->AsTableType()->CheckExpireFuncCompatibility({NewRef{}, a}); + + if ( Find(ATTR_BROKER_STORE) ) + Error("&broker_store and &expire_func cannot be used simultaneously"); + + if ( Find(ATTR_BACKEND) ) + Error("&backend and &expire_func cannot be used simultaneously"); + + break; + } + case ATTR_ON_CHANGE: + { + if ( type->Tag() != TYPE_TABLE ) { - if ( type->Tag() != TYPE_TABLE ) - { - Error("&on_change only applicable to sets/tables"); - break; - } - - const auto& change_func = a->GetExpr(); - - if ( change_func->GetType()->Tag() != TYPE_FUNC || - change_func->GetType()->AsFuncType()->Flavor() != FUNC_FLAVOR_FUNCTION ) - Error("&on_change attribute is not a function"); - - const FuncType* c_ft = change_func->GetType()->AsFuncType(); - - if ( c_ft->Yield()->Tag() != TYPE_VOID ) - { - Error("&on_change must not return a value"); - break; - } - - const TableType* the_table = type->AsTableType(); - - if ( the_table->IsUnspecifiedTable() ) - break; - - const auto& args = c_ft->ParamList()->GetTypes(); - const auto& t_indexes = the_table->GetIndexTypes(); - if ( args.size() != (type->IsSet() ? 2 : 3) + t_indexes.size() ) - { - Error("&on_change function has incorrect number of arguments"); - break; - } - - if ( ! same_type(args[0], the_table->AsTableType()) ) - { - Error("&on_change: first argument must be of same type as table"); - break; - } - - // can't check exact type here yet - the data structures don't exist yet. - if ( args[1]->Tag() != TYPE_ENUM ) - { - Error("&on_change: second argument must be a TableChange enum"); - break; - } - - for ( size_t i = 0; i < t_indexes.size(); i++ ) - { - if ( ! same_type(args[2 + i], t_indexes[i]) ) - { - Error("&on_change: index types do not match table"); - break; - } - } - - if ( ! type->IsSet() ) - if ( ! same_type(args[2 + t_indexes.size()], the_table->Yield()) ) - { - Error("&on_change: value type does not match table"); - break; - } + Error("&on_change only applicable to sets/tables"); + break; } + + const auto& change_func = a->GetExpr(); + + if ( change_func->GetType()->Tag() != TYPE_FUNC || + change_func->GetType()->AsFuncType()->Flavor() != FUNC_FLAVOR_FUNCTION ) + Error("&on_change attribute is not a function"); + + const FuncType* c_ft = change_func->GetType()->AsFuncType(); + + if ( c_ft->Yield()->Tag() != TYPE_VOID ) + { + Error("&on_change must not return a value"); + break; + } + + const TableType* the_table = type->AsTableType(); + + if ( the_table->IsUnspecifiedTable() ) + break; + + const auto& args = c_ft->ParamList()->GetTypes(); + const auto& t_indexes = the_table->GetIndexTypes(); + if ( args.size() != (type->IsSet() ? 2 : 3) + t_indexes.size() ) + { + Error("&on_change function has incorrect number of arguments"); + break; + } + + if ( ! same_type(args[0], the_table->AsTableType()) ) + { + Error("&on_change: first argument must be of same type as table"); + break; + } + + // can't check exact type here yet - the data structures don't exist yet. + if ( args[1]->Tag() != TYPE_ENUM ) + { + Error("&on_change: second argument must be a TableChange enum"); + break; + } + + for ( size_t i = 0; i < t_indexes.size(); i++ ) + { + if ( ! same_type(args[2 + i], t_indexes[i]) ) + { + Error("&on_change: index types do not match table"); + break; + } + } + + if ( ! type->IsSet() ) + if ( ! same_type(args[2 + t_indexes.size()], the_table->Yield()) ) + { + Error("&on_change: value type does not match table"); + break; + } + } break; case ATTR_BACKEND: + { + if ( ! global_var || type->Tag() != TYPE_TABLE ) { - if ( ! global_var || type->Tag() != TYPE_TABLE ) - { - Error("&backend only applicable to global sets/tables"); - break; - } - - // cannot do better equality check - the Broker types are not - // actually existing yet when we are here. We will do that - // later - before actually attaching to a broker store - if ( a->GetExpr()->GetType()->Tag() != TYPE_ENUM ) - { - Error("&backend must take an enum argument"); - break; - } - - // Only support atomic types for the moment, unless - // explicitly overriden - if ( ! type->AsTableType()->IsSet() && - ! input::Manager::IsCompatibleType(type->AsTableType()->Yield().get(), true) && - ! Find(ATTR_BROKER_STORE_ALLOW_COMPLEX) ) - { - Error("&backend only supports atomic types as table value"); - } - - if ( Find(ATTR_EXPIRE_FUNC) ) - Error("&backend and &expire_func cannot be used simultaneously"); - - if ( Find(ATTR_EXPIRE_READ) ) - Error("&backend and &read_expire cannot be used simultaneously"); - - if ( Find(ATTR_BROKER_STORE) ) - Error("&backend and &broker_store cannot be used simultaneously"); - + Error("&backend only applicable to global sets/tables"); break; } + // cannot do better equality check - the Broker types are not + // actually existing yet when we are here. We will do that + // later - before actually attaching to a broker store + if ( a->GetExpr()->GetType()->Tag() != TYPE_ENUM ) + { + Error("&backend must take an enum argument"); + break; + } + + // Only support atomic types for the moment, unless + // explicitly overriden + if ( ! type->AsTableType()->IsSet() && + ! input::Manager::IsCompatibleType(type->AsTableType()->Yield().get(), true) && + ! Find(ATTR_BROKER_STORE_ALLOW_COMPLEX) ) + { + Error("&backend only supports atomic types as table value"); + } + + if ( Find(ATTR_EXPIRE_FUNC) ) + Error("&backend and &expire_func cannot be used simultaneously"); + + if ( Find(ATTR_EXPIRE_READ) ) + Error("&backend and &read_expire cannot be used simultaneously"); + + if ( Find(ATTR_BROKER_STORE) ) + Error("&backend and &broker_store cannot be used simultaneously"); + + break; + } + case ATTR_BROKER_STORE: + { + if ( type->Tag() != TYPE_TABLE ) { - if ( type->Tag() != TYPE_TABLE ) - { - Error("&broker_store only applicable to sets/tables"); - break; - } - - if ( a->GetExpr()->GetType()->Tag() != TYPE_STRING ) - { - Error("&broker_store must take a string argument"); - break; - } - - // Only support atomic types for the moment, unless - // explicitly overriden - if ( ! type->AsTableType()->IsSet() && - ! input::Manager::IsCompatibleType(type->AsTableType()->Yield().get(), true) && - ! Find(ATTR_BROKER_STORE_ALLOW_COMPLEX) ) - { - Error("&broker_store only supports atomic types as table value"); - } - - if ( Find(ATTR_EXPIRE_FUNC) ) - Error("&broker_store and &expire_func cannot be used simultaneously"); - - if ( Find(ATTR_EXPIRE_READ) ) - Error("&broker_store and &read_expire cannot be used simultaneously"); - - if ( Find(ATTR_BACKEND) ) - Error("&backend and &broker_store cannot be used simultaneously"); - + Error("&broker_store only applicable to sets/tables"); break; } - case ATTR_BROKER_STORE_ALLOW_COMPLEX: + if ( a->GetExpr()->GetType()->Tag() != TYPE_STRING ) { - if ( type->Tag() != TYPE_TABLE ) - { - Error("&broker_allow_complex_type only applicable to sets/tables"); - break; - } + Error("&broker_store must take a string argument"); + break; } + // Only support atomic types for the moment, unless + // explicitly overriden + if ( ! type->AsTableType()->IsSet() && + ! input::Manager::IsCompatibleType(type->AsTableType()->Yield().get(), true) && + ! Find(ATTR_BROKER_STORE_ALLOW_COMPLEX) ) + { + Error("&broker_store only supports atomic types as table value"); + } + + if ( Find(ATTR_EXPIRE_FUNC) ) + Error("&broker_store and &expire_func cannot be used simultaneously"); + + if ( Find(ATTR_EXPIRE_READ) ) + Error("&broker_store and &read_expire cannot be used simultaneously"); + + if ( Find(ATTR_BACKEND) ) + Error("&backend and &broker_store cannot be used simultaneously"); + + break; + } + + case ATTR_BROKER_STORE_ALLOW_COMPLEX: + { + if ( type->Tag() != TYPE_TABLE ) + { + Error("&broker_allow_complex_type only applicable to sets/tables"); + break; + } + } + case ATTR_TRACKED: // FIXME: Check here for global ID? break; @@ -695,24 +692,24 @@ void Attributes::CheckAttr(Attr* a) break; case ATTR_TYPE_COLUMN: + { + if ( type->Tag() != TYPE_PORT ) { - if ( type->Tag() != TYPE_PORT ) - { - Error("type_column tag only applicable to ports"); - break; - } - - const auto& atype = a->GetExpr()->GetType(); - - if ( atype->Tag() != TYPE_STRING ) - { - Error("type column needs to have a string argument"); - break; - } - + Error("type_column tag only applicable to ports"); break; } + const auto& atype = a->GetExpr()->GetType(); + + if ( atype->Tag() != TYPE_STRING ) + { + Error("type column needs to have a string argument"); + break; + } + + break; + } + default: BadTag("Attributes::CheckAttr", attr_name(a->Tag())); } diff --git a/src/CompHash.cc b/src/CompHash.cc index 72fe39364f..89b5201238 100644 --- a/src/CompHash.cc +++ b/src/CompHash.cc @@ -158,326 +158,319 @@ bool CompositeHash::RecoverOneVal(const HashKey& hk, Type* t, ValPtr* pval, bool switch ( it ) { case TYPE_INTERNAL_INT: - { - bro_int_t i; - hk.Read("int", i); + { + bro_int_t i; + hk.Read("int", i); - if ( tag == TYPE_ENUM ) - *pval = t->AsEnumType()->GetEnumVal(i); - else if ( tag == TYPE_BOOL ) - *pval = val_mgr->Bool(i); - else if ( tag == TYPE_INT ) - *pval = val_mgr->Int(i); - else - { + if ( tag == TYPE_ENUM ) + *pval = t->AsEnumType()->GetEnumVal(i); + else if ( tag == TYPE_BOOL ) + *pval = val_mgr->Bool(i); + else if ( tag == TYPE_INT ) + *pval = val_mgr->Int(i); + else + { + reporter->InternalError( + "bad internal unsigned int in CompositeHash::RecoverOneVal()"); + *pval = nullptr; + return false; + } + } + break; + + case TYPE_INTERNAL_UNSIGNED: + { + bro_uint_t u; + hk.Read("unsigned", u); + + switch ( tag ) + { + case TYPE_COUNT: + *pval = val_mgr->Count(u); + break; + + case TYPE_PORT: + *pval = val_mgr->Port(u); + break; + + default: reporter->InternalError( "bad internal unsigned int in CompositeHash::RecoverOneVal()"); *pval = nullptr; return false; - } - } - break; - - case TYPE_INTERNAL_UNSIGNED: - { - bro_uint_t u; - hk.Read("unsigned", u); - - switch ( tag ) - { - case TYPE_COUNT: - *pval = val_mgr->Count(u); - break; - - case TYPE_PORT: - *pval = val_mgr->Port(u); - break; - - default: - reporter->InternalError( - "bad internal unsigned int in CompositeHash::RecoverOneVal()"); - *pval = nullptr; - return false; - } } + } break; case TYPE_INTERNAL_DOUBLE: - { - double d; - hk.Read("double", d); + { + double d; + hk.Read("double", d); - if ( tag == TYPE_INTERVAL ) - *pval = make_intrusive(d, 1.0); - else if ( tag == TYPE_TIME ) - *pval = make_intrusive(d); - else - *pval = make_intrusive(d); - } + if ( tag == TYPE_INTERVAL ) + *pval = make_intrusive(d, 1.0); + else if ( tag == TYPE_TIME ) + *pval = make_intrusive(d); + else + *pval = make_intrusive(d); + } break; case TYPE_INTERNAL_ADDR: + { + hk.AlignRead(sizeof(uint32_t)); + hk.EnsureReadSpace(sizeof(uint32_t) * 4); + IPAddr addr(IPv6, static_cast(hk.KeyAtRead()), IPAddr::Network); + hk.SkipRead("addr", sizeof(uint32_t) * 4); + + switch ( tag ) { - hk.AlignRead(sizeof(uint32_t)); - hk.EnsureReadSpace(sizeof(uint32_t) * 4); - IPAddr addr(IPv6, static_cast(hk.KeyAtRead()), IPAddr::Network); - hk.SkipRead("addr", sizeof(uint32_t) * 4); + case TYPE_ADDR: + *pval = make_intrusive(addr); + break; - switch ( tag ) - { - case TYPE_ADDR: - *pval = make_intrusive(addr); - break; - - default: - reporter->InternalError( - "bad internal address in CompositeHash::RecoverOneVal()"); - *pval = nullptr; - return false; - } + default: + reporter->InternalError( + "bad internal address in CompositeHash::RecoverOneVal()"); + *pval = nullptr; + return false; } + } break; case TYPE_INTERNAL_SUBNET: - { - hk.AlignRead(sizeof(uint32_t)); - hk.EnsureReadSpace(sizeof(uint32_t) * 4); - IPAddr addr(IPv6, static_cast(hk.KeyAtRead()), IPAddr::Network); - hk.SkipRead("subnet", sizeof(uint32_t) * 4); + { + hk.AlignRead(sizeof(uint32_t)); + hk.EnsureReadSpace(sizeof(uint32_t) * 4); + IPAddr addr(IPv6, static_cast(hk.KeyAtRead()), IPAddr::Network); + hk.SkipRead("subnet", sizeof(uint32_t) * 4); - uint32_t width; - hk.Read("subnet-width", width); - *pval = make_intrusive(addr, width); - } + uint32_t width; + hk.Read("subnet-width", width); + *pval = make_intrusive(addr, width); + } break; case TYPE_INTERNAL_VOID: case TYPE_INTERNAL_OTHER: + { + switch ( t->Tag() ) { - switch ( t->Tag() ) + case TYPE_FUNC: { - case TYPE_FUNC: + uint32_t id; + hk.Read("func", id); + const auto& f = Func::GetFuncPtrByID(id); + + if ( ! f ) + reporter->InternalError("failed to look up unique function id %" PRIu32 + " in CompositeHash::RecoverOneVal()", + id); + + *pval = make_intrusive(f); + const auto& pvt = (*pval)->GetType(); + + if ( ! pvt ) + reporter->InternalError( + "bad aggregate Val in CompositeHash::RecoverOneVal()"); + + else if ( t->Tag() != TYPE_FUNC && ! same_type(pvt, t) ) + // ### Maybe fix later, but may be fundamentally un-checkable --US + { + reporter->InternalError( + "inconsistent aggregate Val in CompositeHash::RecoverOneVal()"); + *pval = nullptr; + return false; + } + + // ### A crude approximation for now. + else if ( t->Tag() == TYPE_FUNC && pvt->Tag() != TYPE_FUNC ) + { + reporter->InternalError( + "inconsistent aggregate Val in CompositeHash::RecoverOneVal()"); + *pval = nullptr; + return false; + } + } + break; + + case TYPE_PATTERN: + { + const char* texts[2] = {nullptr, nullptr}; + uint64_t lens[2] = {0, 0}; + + if ( ! singleton ) + { + hk.Read("pattern-len1", lens[0]); + hk.Read("pattern-len2", lens[1]); + } + + texts[0] = static_cast(hk.KeyAtRead()); + hk.SkipRead("pattern-string1", strlen(texts[0]) + 1); + texts[1] = static_cast(hk.KeyAtRead()); + hk.SkipRead("pattern-string2", strlen(texts[1]) + 1); + + RE_Matcher* re = new RE_Matcher(texts[0], texts[1]); + + if ( ! re->Compile() ) + reporter->InternalError("failed compiling table/set key pattern: %s", + re->PatternText()); + + *pval = make_intrusive(re); + } + break; + + case TYPE_RECORD: + { + auto rt = t->AsRecordType(); + int num_fields = rt->NumFields(); + + std::vector values; + int i; + for ( i = 0; i < num_fields; ++i ) + { + ValPtr v; + Attributes* a = rt->FieldDecl(i)->attrs.get(); + bool optional = (a && a->Find(ATTR_OPTIONAL)); + + if ( ! RecoverOneVal(hk, rt->GetFieldType(i).get(), &v, optional, false) ) { - uint32_t id; - hk.Read("func", id); - const auto& f = Func::GetFuncPtrByID(id); - - if ( ! f ) - reporter->InternalError( - "failed to look up unique function id %" PRIu32 - " in CompositeHash::RecoverOneVal()", - id); - - *pval = make_intrusive(f); - const auto& pvt = (*pval)->GetType(); - - if ( ! pvt ) - reporter->InternalError( - "bad aggregate Val in CompositeHash::RecoverOneVal()"); - - else if ( t->Tag() != TYPE_FUNC && ! same_type(pvt, t) ) - // ### Maybe fix later, but may be fundamentally un-checkable --US - { - reporter->InternalError( - "inconsistent aggregate Val in CompositeHash::RecoverOneVal()"); - *pval = nullptr; - return false; - } - - // ### A crude approximation for now. - else if ( t->Tag() == TYPE_FUNC && pvt->Tag() != TYPE_FUNC ) - { - reporter->InternalError( - "inconsistent aggregate Val in CompositeHash::RecoverOneVal()"); - *pval = nullptr; - return false; - } - } - break; - - case TYPE_PATTERN: - { - const char* texts[2] = {nullptr, nullptr}; - uint64_t lens[2] = {0, 0}; - - if ( ! singleton ) - { - hk.Read("pattern-len1", lens[0]); - hk.Read("pattern-len2", lens[1]); - } - - texts[0] = static_cast(hk.KeyAtRead()); - hk.SkipRead("pattern-string1", strlen(texts[0]) + 1); - texts[1] = static_cast(hk.KeyAtRead()); - hk.SkipRead("pattern-string2", strlen(texts[1]) + 1); - - RE_Matcher* re = new RE_Matcher(texts[0], texts[1]); - - if ( ! re->Compile() ) - reporter->InternalError( - "failed compiling table/set key pattern: %s", - re->PatternText()); - - *pval = make_intrusive(re); - } - break; - - case TYPE_RECORD: - { - auto rt = t->AsRecordType(); - int num_fields = rt->NumFields(); - - std::vector values; - int i; - for ( i = 0; i < num_fields; ++i ) - { - ValPtr v; - Attributes* a = rt->FieldDecl(i)->attrs.get(); - bool optional = (a && a->Find(ATTR_OPTIONAL)); - - if ( ! RecoverOneVal(hk, rt->GetFieldType(i).get(), &v, optional, - false) ) - { - *pval = nullptr; - return false; - } - - // An earlier call to reporter->InternalError would have called - // abort() and broken the call tree that clang-tidy is relying on to - // get the error described. - // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Branch) - if ( ! (v || optional) ) - { - reporter->InternalError( - "didn't recover expected number of fields from HashKey"); - *pval = nullptr; - return false; - } - - values.emplace_back(std::move(v)); - } - - ASSERT(int(values.size()) == num_fields); - - auto rv = make_intrusive(IntrusivePtr{NewRef{}, rt}); - - for ( int i = 0; i < num_fields; ++i ) - rv->Assign(i, std::move(values[i])); - - *pval = std::move(rv); - } - break; - - case TYPE_TABLE: - { - int n; - hk.Read("table-size", n); - auto tt = t->AsTableType(); - auto tv = make_intrusive(IntrusivePtr{NewRef{}, tt}); - - for ( int i = 0; i < n; ++i ) - { - ValPtr key; - if ( ! RecoverOneVal(hk, tt->GetIndices().get(), &key, false, - false) ) - { - *pval = nullptr; - return false; - } - - if ( t->IsSet() ) - tv->Assign(std::move(key), nullptr); - else - { - ValPtr value; - if ( ! RecoverOneVal(hk, tt->Yield().get(), &value, false, - false) ) - { - *pval = nullptr; - return false; - } - tv->Assign(std::move(key), std::move(value)); - } - } - - *pval = std::move(tv); - } - break; - - case TYPE_VECTOR: - { - unsigned int n; - hk.Read("vector-size", n); - auto vt = t->AsVectorType(); - auto vv = make_intrusive(IntrusivePtr{NewRef{}, vt}); - - for ( unsigned int i = 0; i < n; ++i ) - { - unsigned int index; - hk.Read("vector-idx", index); - bool have_val; - hk.Read("vector-idx-present", have_val); - ValPtr value; - - if ( have_val && - ! RecoverOneVal(hk, vt->Yield().get(), &value, false, false) ) - { - *pval = nullptr; - return false; - } - - vv->Assign(index, std::move(value)); - } - - *pval = std::move(vv); - } - break; - - case TYPE_LIST: - { - int n; - hk.Read("list-size", n); - auto tl = t->AsTypeList(); - auto lv = make_intrusive(TYPE_ANY); - - for ( int i = 0; i < n; ++i ) - { - ValPtr v; - Type* it = tl->GetTypes()[i].get(); - if ( ! RecoverOneVal(hk, it, &v, false, false) ) - return false; - lv->Append(std::move(v)); - } - - *pval = std::move(lv); - } - break; - - default: - { - reporter->InternalError( - "bad index type in CompositeHash::RecoverOneVal"); *pval = nullptr; return false; } + + // An earlier call to reporter->InternalError would have called + // abort() and broken the call tree that clang-tidy is relying on to + // get the error described. + // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Branch) + if ( ! (v || optional) ) + { + reporter->InternalError( + "didn't recover expected number of fields from HashKey"); + *pval = nullptr; + return false; + } + + values.emplace_back(std::move(v)); + } + + ASSERT(int(values.size()) == num_fields); + + auto rv = make_intrusive(IntrusivePtr{NewRef{}, rt}); + + for ( int i = 0; i < num_fields; ++i ) + rv->Assign(i, std::move(values[i])); + + *pval = std::move(rv); + } + break; + + case TYPE_TABLE: + { + int n; + hk.Read("table-size", n); + auto tt = t->AsTableType(); + auto tv = make_intrusive(IntrusivePtr{NewRef{}, tt}); + + for ( int i = 0; i < n; ++i ) + { + ValPtr key; + if ( ! RecoverOneVal(hk, tt->GetIndices().get(), &key, false, false) ) + { + *pval = nullptr; + return false; + } + + if ( t->IsSet() ) + tv->Assign(std::move(key), nullptr); + else + { + ValPtr value; + if ( ! RecoverOneVal(hk, tt->Yield().get(), &value, false, false) ) + { + *pval = nullptr; + return false; + } + tv->Assign(std::move(key), std::move(value)); + } + } + + *pval = std::move(tv); + } + break; + + case TYPE_VECTOR: + { + unsigned int n; + hk.Read("vector-size", n); + auto vt = t->AsVectorType(); + auto vv = make_intrusive(IntrusivePtr{NewRef{}, vt}); + + for ( unsigned int i = 0; i < n; ++i ) + { + unsigned int index; + hk.Read("vector-idx", index); + bool have_val; + hk.Read("vector-idx-present", have_val); + ValPtr value; + + if ( have_val && + ! RecoverOneVal(hk, vt->Yield().get(), &value, false, false) ) + { + *pval = nullptr; + return false; + } + + vv->Assign(index, std::move(value)); + } + + *pval = std::move(vv); + } + break; + + case TYPE_LIST: + { + int n; + hk.Read("list-size", n); + auto tl = t->AsTypeList(); + auto lv = make_intrusive(TYPE_ANY); + + for ( int i = 0; i < n; ++i ) + { + ValPtr v; + Type* it = tl->GetTypes()[i].get(); + if ( ! RecoverOneVal(hk, it, &v, false, false) ) + return false; + lv->Append(std::move(v)); + } + + *pval = std::move(lv); + } + break; + + default: + { + reporter->InternalError("bad index type in CompositeHash::RecoverOneVal"); + *pval = nullptr; + return false; } } + } break; case TYPE_INTERNAL_STRING: + { + int n = hk.Size(); + + if ( ! singleton ) { - int n = hk.Size(); - - if ( ! singleton ) - { - hk.Read("string-len", n); - hk.EnsureReadSpace(n); - } - - *pval = - make_intrusive(new String((const byte_vec)hk.KeyAtRead(), n, true)); - hk.SkipRead("string", n); + hk.Read("string-len", n); + hk.EnsureReadSpace(n); } + + *pval = make_intrusive(new String((const byte_vec)hk.KeyAtRead(), n, true)); + hk.SkipRead("string", n); + } break; case TYPE_INTERNAL_ERROR: @@ -545,164 +538,161 @@ bool CompositeHash::SingleValHash(HashKey& hk, const Val* v, Type* bt, bool type case TYPE_INTERNAL_VOID: case TYPE_INTERNAL_OTHER: + { + switch ( v->GetType()->Tag() ) { - switch ( v->GetType()->Tag() ) + case TYPE_FUNC: + hk.Write("func", v->AsFunc()->GetUniqueFuncID()); + break; + + case TYPE_PATTERN: { - case TYPE_FUNC: - hk.Write("func", v->AsFunc()->GetUniqueFuncID()); - break; + const char* texts[2] = {v->AsPattern()->PatternText(), + v->AsPattern()->AnywherePatternText()}; + uint64_t lens[2] = {strlen(texts[0]) + 1, strlen(texts[1]) + 1}; - case TYPE_PATTERN: - { - const char* texts[2] = {v->AsPattern()->PatternText(), - v->AsPattern()->AnywherePatternText()}; - uint64_t lens[2] = {strlen(texts[0]) + 1, strlen(texts[1]) + 1}; + if ( ! singleton ) + { + hk.Write("pattern-len1", lens[0]); + hk.Write("pattern-len2", lens[1]); + } + else + { + hk.Reserve("pattern", lens[0] + lens[1]); + hk.Allocate(); + } - if ( ! singleton ) - { - hk.Write("pattern-len1", lens[0]); - hk.Write("pattern-len2", lens[1]); - } - else - { - hk.Reserve("pattern", lens[0] + lens[1]); - hk.Allocate(); - } - - hk.Write("pattern-string1", static_cast(texts[0]), - lens[0]); - hk.Write("pattern-string2", static_cast(texts[1]), - lens[1]); - break; - } - - case TYPE_RECORD: - { - auto rv = v->AsRecordVal(); - auto rt = bt->AsRecordType(); - int num_fields = rt->NumFields(); - - if ( ! EnsureTypeReserve(hk, v, bt, type_check) ) - return false; - - for ( int i = 0; i < num_fields; ++i ) - { - auto rv_i = rv->GetField(i); - - Attributes* a = rt->FieldDecl(i)->attrs.get(); - bool optional_attr = (a && a->Find(ATTR_OPTIONAL)); - - if ( ! (rv_i || optional_attr) ) - return false; - - if ( ! SingleValHash(hk, rv_i.get(), rt->GetFieldType(i).get(), - type_check, optional_attr, false) ) - return false; - } - break; - } - - case TYPE_TABLE: - { - if ( ! EnsureTypeReserve(hk, v, bt, type_check) ) - return false; - - auto tv = v->AsTableVal(); - auto hashkeys = ordered_hashkeys(tv); - - hk.Write("table-size", tv->Size()); - - for ( auto& kv : *hashkeys ) - { - auto key = kv.second; - - if ( ! SingleValHash(hk, key.get(), key->GetType().get(), - type_check, false, false) ) - return false; - - if ( ! v->GetType()->IsSet() ) - { - auto val = const_cast(tv)->FindOrDefault(key); - - if ( ! SingleValHash(hk, val.get(), val->GetType().get(), - type_check, false, false) ) - return false; - } - } - } - break; - - case TYPE_VECTOR: - { - if ( ! EnsureTypeReserve(hk, v, bt, type_check) ) - return false; - - auto vv = v->AsVectorVal(); - auto vt = v->GetType()->AsVectorType(); - - hk.Write("vector-size", vv->Size()); - - for ( unsigned int i = 0; i < vv->Size(); ++i ) - { - auto val = vv->ValAt(i); - hk.Write("vector-idx", i); - hk.Write("vector-idx-present", val != nullptr); - - if ( val && ! SingleValHash(hk, val.get(), vt->Yield().get(), - type_check, false, false) ) - return false; - } - } - break; - - case TYPE_LIST: - { - if ( ! hk.IsAllocated() ) - { - if ( ! ReserveSingleTypeKeySize(hk, bt, v, type_check, false, false, - false) ) - return false; - - hk.Allocate(); - } - - auto lv = v->AsListVal(); - - hk.Write("list-size", lv->Length()); - - for ( int i = 0; i < lv->Length(); ++i ) - { - Val* entry_val = lv->Idx(i).get(); - if ( ! SingleValHash(hk, entry_val, entry_val->GetType().get(), - type_check, false, false) ) - return false; - } - } - break; - - default: - { - reporter->InternalError( - "bad index type in CompositeHash::SingleValHash"); - return false; - } + hk.Write("pattern-string1", static_cast(texts[0]), lens[0]); + hk.Write("pattern-string2", static_cast(texts[1]), lens[1]); + break; } - break; // case TYPE_INTERNAL_VOID/OTHER + case TYPE_RECORD: + { + auto rv = v->AsRecordVal(); + auto rt = bt->AsRecordType(); + int num_fields = rt->NumFields(); + + if ( ! EnsureTypeReserve(hk, v, bt, type_check) ) + return false; + + for ( int i = 0; i < num_fields; ++i ) + { + auto rv_i = rv->GetField(i); + + Attributes* a = rt->FieldDecl(i)->attrs.get(); + bool optional_attr = (a && a->Find(ATTR_OPTIONAL)); + + if ( ! (rv_i || optional_attr) ) + return false; + + if ( ! SingleValHash(hk, rv_i.get(), rt->GetFieldType(i).get(), type_check, + optional_attr, false) ) + return false; + } + break; + } + + case TYPE_TABLE: + { + if ( ! EnsureTypeReserve(hk, v, bt, type_check) ) + return false; + + auto tv = v->AsTableVal(); + auto hashkeys = ordered_hashkeys(tv); + + hk.Write("table-size", tv->Size()); + + for ( auto& kv : *hashkeys ) + { + auto key = kv.second; + + if ( ! SingleValHash(hk, key.get(), key->GetType().get(), type_check, false, + false) ) + return false; + + if ( ! v->GetType()->IsSet() ) + { + auto val = const_cast(tv)->FindOrDefault(key); + + if ( ! SingleValHash(hk, val.get(), val->GetType().get(), type_check, + false, false) ) + return false; + } + } + } + break; + + case TYPE_VECTOR: + { + if ( ! EnsureTypeReserve(hk, v, bt, type_check) ) + return false; + + auto vv = v->AsVectorVal(); + auto vt = v->GetType()->AsVectorType(); + + hk.Write("vector-size", vv->Size()); + + for ( unsigned int i = 0; i < vv->Size(); ++i ) + { + auto val = vv->ValAt(i); + hk.Write("vector-idx", i); + hk.Write("vector-idx-present", val != nullptr); + + if ( val && ! SingleValHash(hk, val.get(), vt->Yield().get(), type_check, + false, false) ) + return false; + } + } + break; + + case TYPE_LIST: + { + if ( ! hk.IsAllocated() ) + { + if ( ! ReserveSingleTypeKeySize(hk, bt, v, type_check, false, false, + false) ) + return false; + + hk.Allocate(); + } + + auto lv = v->AsListVal(); + + hk.Write("list-size", lv->Length()); + + for ( int i = 0; i < lv->Length(); ++i ) + { + Val* entry_val = lv->Idx(i).get(); + if ( ! SingleValHash(hk, entry_val, entry_val->GetType().get(), type_check, + false, false) ) + return false; + } + } + break; + + default: + { + reporter->InternalError("bad index type in CompositeHash::SingleValHash"); + return false; + } } + break; // case TYPE_INTERNAL_VOID/OTHER + } + case TYPE_INTERNAL_STRING: - { - if ( ! EnsureTypeReserve(hk, v, bt, type_check) ) - return false; + { + if ( ! EnsureTypeReserve(hk, v, bt, type_check) ) + return false; - const auto sval = v->AsString(); + const auto sval = v->AsString(); - if ( ! singleton ) - hk.Write("string-len", sval->Len()); + if ( ! singleton ) + hk.Write("string-len", sval->Len()); - hk.Write("string", sval->Bytes(), sval->Len()); - } + hk.Write("string", sval->Bytes(), sval->Len()); + } break; case TYPE_INTERNAL_ERROR: @@ -783,138 +773,137 @@ bool CompositeHash::ReserveSingleTypeKeySize(HashKey& hk, Type* bt, const Val* v case TYPE_INTERNAL_VOID: case TYPE_INTERNAL_OTHER: + { + switch ( bt->Tag() ) { - switch ( bt->Tag() ) + case TYPE_FUNC: { - case TYPE_FUNC: - { - hk.ReserveType("func"); - break; - } - - case TYPE_PATTERN: - { - if ( ! v ) - return (optional && ! calc_static_size); - - if ( ! singleton ) - { - hk.ReserveType("pattern-len1"); - hk.ReserveType("pattern-len2"); - } - - // +1 in the following to include null terminators - hk.Reserve("pattern-string1", strlen(v->AsPattern()->PatternText()) + 1, - 0); - hk.Reserve("pattern-string1", - strlen(v->AsPattern()->AnywherePatternText()) + 1, 0); - break; - } - - case TYPE_RECORD: - { - if ( ! v ) - return (optional && ! calc_static_size); - - const RecordVal* rv = v->AsRecordVal(); - RecordType* rt = bt->AsRecordType(); - int num_fields = rt->NumFields(); - - for ( int i = 0; i < num_fields; ++i ) - { - Attributes* a = rt->FieldDecl(i)->attrs.get(); - bool optional_attr = (a && a->Find(ATTR_OPTIONAL)); - - auto rv_v = rv ? rv->GetField(i) : nullptr; - if ( ! ReserveSingleTypeKeySize( - hk, rt->GetFieldType(i).get(), rv_v.get(), type_check, - optional_attr, calc_static_size, false) ) - return false; - } - break; - } - - case TYPE_TABLE: - { - if ( ! v ) - return (optional && ! calc_static_size); - - auto tv = v->AsTableVal(); - auto hashkeys = ordered_hashkeys(tv); - - hk.ReserveType("table-size"); - - for ( auto& kv : *hashkeys ) - { - auto key = kv.second; - - if ( ! ReserveSingleTypeKeySize(hk, key->GetType().get(), key.get(), - type_check, false, calc_static_size, - false) ) - return false; - - if ( ! bt->IsSet() ) - { - auto val = const_cast(tv)->FindOrDefault(key); - if ( ! ReserveSingleTypeKeySize(hk, val->GetType().get(), - val.get(), type_check, false, - calc_static_size, false) ) - return false; - } - } - - break; - } - - case TYPE_VECTOR: - { - if ( ! v ) - return (optional && ! calc_static_size); - - hk.ReserveType("vector-size"); - VectorVal* vv = const_cast(v->AsVectorVal()); - for ( unsigned int i = 0; i < vv->Size(); ++i ) - { - auto val = vv->ValAt(i); - hk.ReserveType("vector-idx"); - hk.ReserveType("vector-idx-present"); - if ( val && ! ReserveSingleTypeKeySize( - hk, bt->AsVectorType()->Yield().get(), val.get(), - type_check, false, calc_static_size, false) ) - return false; - } - break; - } - - case TYPE_LIST: - { - if ( ! v ) - return (optional && ! calc_static_size); - - hk.ReserveType("list-size"); - ListVal* lv = const_cast(v->AsListVal()); - for ( int i = 0; i < lv->Length(); ++i ) - { - if ( ! ReserveSingleTypeKeySize(hk, lv->Idx(i)->GetType().get(), - lv->Idx(i).get(), type_check, false, - calc_static_size, false) ) - return false; - } - - break; - } - - default: - { - reporter->InternalError( - "bad index type in CompositeHash::ReserveSingleTypeKeySize"); - return 0; - } + hk.ReserveType("func"); + break; } - break; // case TYPE_INTERNAL_VOID/OTHER + case TYPE_PATTERN: + { + if ( ! v ) + return (optional && ! calc_static_size); + + if ( ! singleton ) + { + hk.ReserveType("pattern-len1"); + hk.ReserveType("pattern-len2"); + } + + // +1 in the following to include null terminators + hk.Reserve("pattern-string1", strlen(v->AsPattern()->PatternText()) + 1, 0); + hk.Reserve("pattern-string1", strlen(v->AsPattern()->AnywherePatternText()) + 1, + 0); + break; + } + + case TYPE_RECORD: + { + if ( ! v ) + return (optional && ! calc_static_size); + + const RecordVal* rv = v->AsRecordVal(); + RecordType* rt = bt->AsRecordType(); + int num_fields = rt->NumFields(); + + for ( int i = 0; i < num_fields; ++i ) + { + Attributes* a = rt->FieldDecl(i)->attrs.get(); + bool optional_attr = (a && a->Find(ATTR_OPTIONAL)); + + auto rv_v = rv ? rv->GetField(i) : nullptr; + if ( ! ReserveSingleTypeKeySize(hk, rt->GetFieldType(i).get(), rv_v.get(), + type_check, optional_attr, calc_static_size, + false) ) + return false; + } + break; + } + + case TYPE_TABLE: + { + if ( ! v ) + return (optional && ! calc_static_size); + + auto tv = v->AsTableVal(); + auto hashkeys = ordered_hashkeys(tv); + + hk.ReserveType("table-size"); + + for ( auto& kv : *hashkeys ) + { + auto key = kv.second; + + if ( ! ReserveSingleTypeKeySize(hk, key->GetType().get(), key.get(), + type_check, false, calc_static_size, + false) ) + return false; + + if ( ! bt->IsSet() ) + { + auto val = const_cast(tv)->FindOrDefault(key); + if ( ! ReserveSingleTypeKeySize(hk, val->GetType().get(), val.get(), + type_check, false, calc_static_size, + false) ) + return false; + } + } + + break; + } + + case TYPE_VECTOR: + { + if ( ! v ) + return (optional && ! calc_static_size); + + hk.ReserveType("vector-size"); + VectorVal* vv = const_cast(v->AsVectorVal()); + for ( unsigned int i = 0; i < vv->Size(); ++i ) + { + auto val = vv->ValAt(i); + hk.ReserveType("vector-idx"); + hk.ReserveType("vector-idx-present"); + if ( val && ! ReserveSingleTypeKeySize( + hk, bt->AsVectorType()->Yield().get(), val.get(), + type_check, false, calc_static_size, false) ) + return false; + } + break; + } + + case TYPE_LIST: + { + if ( ! v ) + return (optional && ! calc_static_size); + + hk.ReserveType("list-size"); + ListVal* lv = const_cast(v->AsListVal()); + for ( int i = 0; i < lv->Length(); ++i ) + { + if ( ! ReserveSingleTypeKeySize(hk, lv->Idx(i)->GetType().get(), + lv->Idx(i).get(), type_check, false, + calc_static_size, false) ) + return false; + } + + break; + } + + default: + { + reporter->InternalError( + "bad index type in CompositeHash::ReserveSingleTypeKeySize"); + return 0; + } } + break; // case TYPE_INTERNAL_VOID/OTHER + } + case TYPE_INTERNAL_STRING: if ( ! v ) return (optional && ! calc_static_size); diff --git a/src/DbgBreakpoint.cc b/src/DbgBreakpoint.cc index b309326b23..01dcbb059a 100644 --- a/src/DbgBreakpoint.cc +++ b/src/DbgBreakpoint.cc @@ -348,19 +348,19 @@ void DbgBreakpoint::PrintHitMsg() case BP_STMT: case BP_FUNC: case BP_LINE: - { - ODesc d; - Frame* f = g_frame_stack.back(); - const ScriptFunc* func = f->GetFunction(); + { + ODesc d; + Frame* f = g_frame_stack.back(); + const ScriptFunc* func = f->GetFunction(); - if ( func ) - func->DescribeDebug(&d, f->GetFuncArgs()); + if ( func ) + func->DescribeDebug(&d, f->GetFuncArgs()); - const Location* loc = at_stmt->GetLocationInfo(); + const Location* loc = at_stmt->GetLocationInfo(); - debug_msg("Breakpoint %d, %s at %s:%d\n", GetID(), d.Description(), loc->filename, - loc->first_line); - } + debug_msg("Breakpoint %d, %s at %s:%d\n", GetID(), d.Description(), loc->filename, + loc->first_line); + } return; case BP_TIME: diff --git a/src/Expr.cc b/src/Expr.cc index 42b6350613..d12c023828 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -320,75 +320,75 @@ const char* assign_to_index(ValPtr v1, ValPtr v2, ValPtr v3, bool& iterators_inv switch ( v1->GetType()->Tag() ) { case TYPE_VECTOR: + { + const ListVal* lv = v2->AsListVal(); + VectorVal* v1_vect = v1->AsVectorVal(); + + if ( lv->Length() > 1 ) { - const ListVal* lv = v2->AsListVal(); - VectorVal* v1_vect = v1->AsVectorVal(); + auto len = v1_vect->Size(); + bro_int_t first = get_slice_index(lv->Idx(0)->CoerceToInt(), len); + bro_int_t last = get_slice_index(lv->Idx(1)->CoerceToInt(), len); - if ( lv->Length() > 1 ) - { - auto len = v1_vect->Size(); - bro_int_t first = get_slice_index(lv->Idx(0)->CoerceToInt(), len); - bro_int_t last = get_slice_index(lv->Idx(1)->CoerceToInt(), len); + // Remove the elements from the vector within the slice. + for ( auto idx = first; idx < last; idx++ ) + v1_vect->Remove(first); - // Remove the elements from the vector within the slice. - for ( auto idx = first; idx < last; idx++ ) - v1_vect->Remove(first); + // Insert the new elements starting at the first + // position. - // Insert the new elements starting at the first - // position. + VectorVal* v_vect = v3->AsVectorVal(); - VectorVal* v_vect = v3->AsVectorVal(); - - for ( auto idx = 0u; idx < v_vect->Size(); idx++, first++ ) - v1_vect->Insert(first, v_vect->ValAt(idx)); - } - - else if ( ! v1_vect->Assign(lv->Idx(0)->CoerceToUnsigned(), std::move(v3)) ) - { - v3 = std::move(v_extra); - - if ( v3 ) - { - ODesc d; - v3->Describe(&d); - const auto& vt = v3->GetType(); - auto vtt = vt->Tag(); - std::string tn = vtt == TYPE_RECORD ? vt->GetName() : type_name(vtt); - return util::fmt( - "vector index assignment failed for invalid type '%s', value: %s", - tn.data(), d.Description()); - } - else - return "assignment failed with null value"; - } - break; + for ( auto idx = 0u; idx < v_vect->Size(); idx++, first++ ) + v1_vect->Insert(first, v_vect->ValAt(idx)); } + else if ( ! v1_vect->Assign(lv->Idx(0)->CoerceToUnsigned(), std::move(v3)) ) + { + v3 = std::move(v_extra); + + if ( v3 ) + { + ODesc d; + v3->Describe(&d); + const auto& vt = v3->GetType(); + auto vtt = vt->Tag(); + std::string tn = vtt == TYPE_RECORD ? vt->GetName() : type_name(vtt); + return util::fmt( + "vector index assignment failed for invalid type '%s', value: %s", + tn.data(), d.Description()); + } + else + return "assignment failed with null value"; + } + break; + } + case TYPE_TABLE: + { + if ( ! v1->AsTableVal()->Assign(std::move(v2), std::move(v3), true, + &iterators_invalidated) ) { - if ( ! v1->AsTableVal()->Assign(std::move(v2), std::move(v3), true, - &iterators_invalidated) ) + v3 = std::move(v_extra); + + if ( v3 ) { - v3 = std::move(v_extra); - - if ( v3 ) - { - ODesc d; - v3->Describe(&d); - const auto& vt = v3->GetType(); - auto vtt = vt->Tag(); - std::string tn = vtt == TYPE_RECORD ? vt->GetName() : type_name(vtt); - return util::fmt( - "table index assignment failed for invalid type '%s', value: %s", - tn.data(), d.Description()); - } - else - return "assignment failed with null value"; + ODesc d; + v3->Describe(&d); + const auto& vt = v3->GetType(); + auto vtt = vt->Tag(); + std::string tn = vtt == TYPE_RECORD ? vt->GetName() : type_name(vtt); + return util::fmt( + "table index assignment failed for invalid type '%s', value: %s", tn.data(), + d.Description()); } - - break; + else + return "assignment failed with null value"; } + break; + } + case TYPE_STRING: return "assignment via string index accessor not allowed"; break; @@ -925,54 +925,54 @@ ValPtr BinaryExpr::Fold(Val* v1, Val* v2) const DO_FOLD(*); break; case EXPR_DIVIDE: + { + if ( is_integral ) { - if ( is_integral ) - { - if ( i2 == 0 ) - RuntimeError("division by zero"); + if ( i2 == 0 ) + RuntimeError("division by zero"); - i3 = i1 / i2; - } - - else if ( is_unsigned ) - { - if ( u2 == 0 ) - RuntimeError("division by zero"); - - u3 = u1 / u2; - } - else - { - if ( d2 == 0 ) - RuntimeError("division by zero"); - - d3 = d1 / d2; - } + i3 = i1 / i2; } + + else if ( is_unsigned ) + { + if ( u2 == 0 ) + RuntimeError("division by zero"); + + u3 = u1 / u2; + } + else + { + if ( d2 == 0 ) + RuntimeError("division by zero"); + + d3 = d1 / d2; + } + } break; case EXPR_MOD: + { + if ( is_integral ) { - if ( is_integral ) - { - if ( i2 == 0 ) - RuntimeError("modulo by zero"); + if ( i2 == 0 ) + RuntimeError("modulo by zero"); - i3 = i1 % i2; - } - - else if ( is_unsigned ) - { - if ( u2 == 0 ) - RuntimeError("modulo by zero"); - - u3 = u1 % u2; - } - - else - RuntimeErrorWithCallStack("bad type in BinaryExpr::Fold"); + i3 = i1 % i2; } + else if ( is_unsigned ) + { + if ( u2 == 0 ) + RuntimeError("modulo by zero"); + + u3 = u1 % u2; + } + + else + RuntimeErrorWithCallStack("bad type in BinaryExpr::Fold"); + } + break; case EXPR_AND: @@ -1061,13 +1061,13 @@ ValPtr BinaryExpr::StringFold(Val* v1, Val* v2) const case EXPR_ADD: case EXPR_ADD_TO: - { - std::vector strings; - strings.push_back(s1); - strings.push_back(s2); + { + std::vector strings; + strings.push_back(s1); + strings.push_back(s2); - return make_intrusive(concatenate(strings)); - } + return make_intrusive(concatenate(strings)); + } default: BadTag("BinaryExpr::StringFold", expr_name(tag)); @@ -1102,24 +1102,24 @@ ValPtr BinaryExpr::SetFold(Val* v1, Val* v2) const return tv1->Intersection(*tv2); case EXPR_OR: - { - auto rval = v1->Clone(); + { + auto rval = v1->Clone(); - if ( ! tv2->AddTo(rval.get(), false, false) ) - reporter->InternalError("set union failed to type check"); + if ( ! tv2->AddTo(rval.get(), false, false) ) + reporter->InternalError("set union failed to type check"); - return rval; - } + return rval; + } case EXPR_SUB: - { - auto rval = v1->Clone(); + { + auto rval = v1->Clone(); - if ( ! tv2->RemoveFrom(rval.get()) ) - reporter->InternalError("set difference failed to type check"); + if ( ! tv2->RemoveFrom(rval.get()) ) + reporter->InternalError("set difference failed to type check"); - return rval; - } + return rval; + } case EXPR_EQ: res = tv1->EqualTo(*tv2); @@ -3020,15 +3020,15 @@ ValPtr IndexExpr::Fold(Val* v1, Val* v2) const switch ( v1->GetType()->Tag() ) { case TYPE_VECTOR: - { - VectorVal* vect = v1->AsVectorVal(); - const ListVal* lv = v2->AsListVal(); + { + VectorVal* vect = v1->AsVectorVal(); + const ListVal* lv = v2->AsListVal(); - if ( lv->Length() == 1 ) - v = vect->ValAt(lv->Idx(0)->CoerceToUnsigned()); - else - return index_slice(vect, lv); - } + if ( lv->Length() == 1 ) + v = vect->ValAt(lv->Idx(0)->CoerceToUnsigned()); + else + return index_slice(vect, lv); + } break; case TYPE_TABLE: diff --git a/src/Func.cc b/src/Func.cc index 355544362e..d50221132c 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -272,26 +272,25 @@ void Func::CheckPluginResult(bool handled, const ValPtr& hook_result, FunctionFl break; case FUNC_FLAVOR_FUNCTION: + { + const auto& yt = GetType()->Yield(); + + if ( (! yt) || yt->Tag() == TYPE_VOID ) { - const auto& yt = GetType()->Yield(); - - if ( (! yt) || yt->Tag() == TYPE_VOID ) - { - if ( hook_result ) - reporter->InternalError( - "plugin returned non-void result for void method %s", this->Name()); - } - - else if ( hook_result && hook_result->GetType()->Tag() != yt->Tag() && - yt->Tag() != TYPE_ANY ) - { - reporter->InternalError( - "plugin returned wrong type (got %d, expecting %d) for %s", - hook_result->GetType()->Tag(), yt->Tag(), this->Name()); - } - - break; + if ( hook_result ) + reporter->InternalError("plugin returned non-void result for void method %s", + this->Name()); } + + else if ( hook_result && hook_result->GetType()->Tag() != yt->Tag() && + yt->Tag() != TYPE_ANY ) + { + reporter->InternalError("plugin returned wrong type (got %d, expecting %d) for %s", + hook_result->GetType()->Tag(), yt->Tag(), this->Name()); + } + + break; + } } } diff --git a/src/IP.cc b/src/IP.cc index 497d3260d8..ba104277c4 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -58,249 +58,244 @@ RecordValPtr IPv6_Hdr::ToVal(VectorValPtr chain) const switch ( type ) { case IPPROTO_IPV6: - { - static auto ip6_hdr_type = id::find_type("ip6_hdr"); - rv = make_intrusive(ip6_hdr_type); - const struct ip6_hdr* ip6 = (const struct ip6_hdr*)data; - rv->Assign(0, (ntohl(ip6->ip6_flow) & 0x0ff00000) >> 20); - rv->Assign(1, ntohl(ip6->ip6_flow) & 0x000fffff); - rv->Assign(2, ntohs(ip6->ip6_plen)); - rv->Assign(3, ip6->ip6_nxt); - rv->Assign(4, ip6->ip6_hlim); - rv->Assign(5, make_intrusive(IPAddr(ip6->ip6_src))); - rv->Assign(6, make_intrusive(IPAddr(ip6->ip6_dst))); - if ( ! chain ) - chain = - make_intrusive(id::find_type("ip6_ext_hdr_chain")); - rv->Assign(7, std::move(chain)); - } + { + static auto ip6_hdr_type = id::find_type("ip6_hdr"); + rv = make_intrusive(ip6_hdr_type); + const struct ip6_hdr* ip6 = (const struct ip6_hdr*)data; + rv->Assign(0, (ntohl(ip6->ip6_flow) & 0x0ff00000) >> 20); + rv->Assign(1, ntohl(ip6->ip6_flow) & 0x000fffff); + rv->Assign(2, ntohs(ip6->ip6_plen)); + rv->Assign(3, ip6->ip6_nxt); + rv->Assign(4, ip6->ip6_hlim); + rv->Assign(5, make_intrusive(IPAddr(ip6->ip6_src))); + rv->Assign(6, make_intrusive(IPAddr(ip6->ip6_dst))); + if ( ! chain ) + chain = make_intrusive(id::find_type("ip6_ext_hdr_chain")); + rv->Assign(7, std::move(chain)); + } break; case IPPROTO_HOPOPTS: - { - static auto ip6_hopopts_type = id::find_type("ip6_hopopts"); - rv = make_intrusive(ip6_hopopts_type); - const struct ip6_hbh* hbh = (const struct ip6_hbh*)data; - rv->Assign(0, hbh->ip6h_nxt); - rv->Assign(1, hbh->ip6h_len); - uint16_t off = 2 * sizeof(uint8_t); - rv->Assign(2, BuildOptionsVal(data + off, Length() - off)); - } + { + static auto ip6_hopopts_type = id::find_type("ip6_hopopts"); + rv = make_intrusive(ip6_hopopts_type); + const struct ip6_hbh* hbh = (const struct ip6_hbh*)data; + rv->Assign(0, hbh->ip6h_nxt); + rv->Assign(1, hbh->ip6h_len); + uint16_t off = 2 * sizeof(uint8_t); + rv->Assign(2, BuildOptionsVal(data + off, Length() - off)); + } break; case IPPROTO_DSTOPTS: - { - static auto ip6_dstopts_type = id::find_type("ip6_dstopts"); - rv = make_intrusive(ip6_dstopts_type); - const struct ip6_dest* dst = (const struct ip6_dest*)data; - rv->Assign(0, dst->ip6d_nxt); - rv->Assign(1, dst->ip6d_len); - uint16_t off = 2 * sizeof(uint8_t); - rv->Assign(2, BuildOptionsVal(data + off, Length() - off)); - } + { + static auto ip6_dstopts_type = id::find_type("ip6_dstopts"); + rv = make_intrusive(ip6_dstopts_type); + const struct ip6_dest* dst = (const struct ip6_dest*)data; + rv->Assign(0, dst->ip6d_nxt); + rv->Assign(1, dst->ip6d_len); + uint16_t off = 2 * sizeof(uint8_t); + rv->Assign(2, BuildOptionsVal(data + off, Length() - off)); + } break; case IPPROTO_ROUTING: - { - static auto ip6_routing_type = id::find_type("ip6_routing"); - rv = make_intrusive(ip6_routing_type); - const struct ip6_rthdr* rt = (const struct ip6_rthdr*)data; - rv->Assign(0, rt->ip6r_nxt); - rv->Assign(1, rt->ip6r_len); - rv->Assign(2, rt->ip6r_type); - rv->Assign(3, rt->ip6r_segleft); - uint16_t off = 4 * sizeof(uint8_t); - rv->Assign(4, new String(data + off, Length() - off, true)); - } + { + static auto ip6_routing_type = id::find_type("ip6_routing"); + rv = make_intrusive(ip6_routing_type); + const struct ip6_rthdr* rt = (const struct ip6_rthdr*)data; + rv->Assign(0, rt->ip6r_nxt); + rv->Assign(1, rt->ip6r_len); + rv->Assign(2, rt->ip6r_type); + rv->Assign(3, rt->ip6r_segleft); + uint16_t off = 4 * sizeof(uint8_t); + rv->Assign(4, new String(data + off, Length() - off, true)); + } break; case IPPROTO_FRAGMENT: - { - static auto ip6_fragment_type = id::find_type("ip6_fragment"); - rv = make_intrusive(ip6_fragment_type); - const struct ip6_frag* frag = (const struct ip6_frag*)data; - rv->Assign(0, frag->ip6f_nxt); - rv->Assign(1, frag->ip6f_reserved); - rv->Assign(2, (ntohs(frag->ip6f_offlg) & 0xfff8) >> 3); - rv->Assign(3, (ntohs(frag->ip6f_offlg) & 0x0006) >> 1); - rv->Assign(4, static_cast(ntohs(frag->ip6f_offlg) & 0x0001)); - rv->Assign(5, ntohl(frag->ip6f_ident)); - } + { + static auto ip6_fragment_type = id::find_type("ip6_fragment"); + rv = make_intrusive(ip6_fragment_type); + const struct ip6_frag* frag = (const struct ip6_frag*)data; + rv->Assign(0, frag->ip6f_nxt); + rv->Assign(1, frag->ip6f_reserved); + rv->Assign(2, (ntohs(frag->ip6f_offlg) & 0xfff8) >> 3); + rv->Assign(3, (ntohs(frag->ip6f_offlg) & 0x0006) >> 1); + rv->Assign(4, static_cast(ntohs(frag->ip6f_offlg) & 0x0001)); + rv->Assign(5, ntohl(frag->ip6f_ident)); + } break; case IPPROTO_AH: - { - static auto ip6_ah_type = id::find_type("ip6_ah"); - rv = make_intrusive(ip6_ah_type); - rv->Assign(0, ((ip6_ext*)data)->ip6e_nxt); - rv->Assign(1, ((ip6_ext*)data)->ip6e_len); - rv->Assign(2, ntohs(((uint16_t*)data)[1])); - rv->Assign(3, ntohl(((uint32_t*)data)[1])); + { + static auto ip6_ah_type = id::find_type("ip6_ah"); + rv = make_intrusive(ip6_ah_type); + rv->Assign(0, ((ip6_ext*)data)->ip6e_nxt); + rv->Assign(1, ((ip6_ext*)data)->ip6e_len); + rv->Assign(2, ntohs(((uint16_t*)data)[1])); + rv->Assign(3, ntohl(((uint32_t*)data)[1])); - if ( Length() >= 12 ) - { - // Sequence Number and ICV fields can only be extracted if - // Payload Len was non-zero for this header. - rv->Assign(4, ntohl(((uint32_t*)data)[2])); - uint16_t off = 3 * sizeof(uint32_t); - rv->Assign(5, new String(data + off, Length() - off, true)); - } + if ( Length() >= 12 ) + { + // Sequence Number and ICV fields can only be extracted if + // Payload Len was non-zero for this header. + rv->Assign(4, ntohl(((uint32_t*)data)[2])); + uint16_t off = 3 * sizeof(uint32_t); + rv->Assign(5, new String(data + off, Length() - off, true)); } + } break; case IPPROTO_ESP: - { - static auto ip6_esp_type = id::find_type("ip6_esp"); - rv = make_intrusive(ip6_esp_type); - const uint32_t* esp = (const uint32_t*)data; - rv->Assign(0, ntohl(esp[0])); - rv->Assign(1, ntohl(esp[1])); - } + { + static auto ip6_esp_type = id::find_type("ip6_esp"); + rv = make_intrusive(ip6_esp_type); + const uint32_t* esp = (const uint32_t*)data; + rv->Assign(0, ntohl(esp[0])); + rv->Assign(1, ntohl(esp[1])); + } break; case IPPROTO_MOBILITY: + { + static auto ip6_mob_type = id::find_type("ip6_mobility_hdr"); + rv = make_intrusive(ip6_mob_type); + const struct ip6_mobility* mob = (const struct ip6_mobility*)data; + rv->Assign(0, mob->ip6mob_payload); + rv->Assign(1, mob->ip6mob_len); + rv->Assign(2, mob->ip6mob_type); + rv->Assign(3, mob->ip6mob_rsv); + rv->Assign(4, ntohs(mob->ip6mob_chksum)); + + static auto ip6_mob_msg_type = id::find_type("ip6_mobility_msg"); + auto msg = make_intrusive(ip6_mob_msg_type); + msg->Assign(0, mob->ip6mob_type); + + uint16_t off = sizeof(ip6_mobility); + const u_char* msg_data = data + off; + + static auto ip6_mob_brr_type = id::find_type("ip6_mobility_brr"); + static auto ip6_mob_hoti_type = id::find_type("ip6_mobility_hoti"); + static auto ip6_mob_coti_type = id::find_type("ip6_mobility_coti"); + static auto ip6_mob_hot_type = id::find_type("ip6_mobility_hot"); + static auto ip6_mob_cot_type = id::find_type("ip6_mobility_cot"); + static auto ip6_mob_bu_type = id::find_type("ip6_mobility_bu"); + static auto ip6_mob_back_type = id::find_type("ip6_mobility_back"); + static auto ip6_mob_be_type = id::find_type("ip6_mobility_be"); + + switch ( mob->ip6mob_type ) { - static auto ip6_mob_type = id::find_type("ip6_mobility_hdr"); - rv = make_intrusive(ip6_mob_type); - const struct ip6_mobility* mob = (const struct ip6_mobility*)data; - rv->Assign(0, mob->ip6mob_payload); - rv->Assign(1, mob->ip6mob_len); - rv->Assign(2, mob->ip6mob_type); - rv->Assign(3, mob->ip6mob_rsv); - rv->Assign(4, ntohs(mob->ip6mob_chksum)); - - static auto ip6_mob_msg_type = id::find_type("ip6_mobility_msg"); - auto msg = make_intrusive(ip6_mob_msg_type); - msg->Assign(0, mob->ip6mob_type); - - uint16_t off = sizeof(ip6_mobility); - const u_char* msg_data = data + off; - - static auto ip6_mob_brr_type = id::find_type("ip6_mobility_brr"); - static auto ip6_mob_hoti_type = id::find_type("ip6_mobility_hoti"); - static auto ip6_mob_coti_type = id::find_type("ip6_mobility_coti"); - static auto ip6_mob_hot_type = id::find_type("ip6_mobility_hot"); - static auto ip6_mob_cot_type = id::find_type("ip6_mobility_cot"); - static auto ip6_mob_bu_type = id::find_type("ip6_mobility_bu"); - static auto ip6_mob_back_type = id::find_type("ip6_mobility_back"); - static auto ip6_mob_be_type = id::find_type("ip6_mobility_be"); - - switch ( mob->ip6mob_type ) + case 0: { - case 0: - { - auto m = make_intrusive(ip6_mob_brr_type); - m->Assign(0, ntohs(*((uint16_t*)msg_data))); - off += sizeof(uint16_t); - m->Assign(1, BuildOptionsVal(data + off, Length() - off)); - msg->Assign(1, std::move(m)); - } - break; + auto m = make_intrusive(ip6_mob_brr_type); + m->Assign(0, ntohs(*((uint16_t*)msg_data))); + off += sizeof(uint16_t); + m->Assign(1, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(1, std::move(m)); + } + break; - case 1: - { - auto m = make_intrusive(ip6_mob_hoti_type); - m->Assign(0, ntohs(*((uint16_t*)msg_data))); - m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t))))); - off += sizeof(uint16_t) + sizeof(uint64_t); - m->Assign(2, BuildOptionsVal(data + off, Length() - off)); - msg->Assign(2, std::move(m)); - break; - } - - case 2: - { - auto m = make_intrusive(ip6_mob_coti_type); - m->Assign(0, ntohs(*((uint16_t*)msg_data))); - m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t))))); - off += sizeof(uint16_t) + sizeof(uint64_t); - m->Assign(2, BuildOptionsVal(data + off, Length() - off)); - msg->Assign(3, std::move(m)); - break; - } - - case 3: - { - auto m = make_intrusive(ip6_mob_hot_type); - m->Assign(0, ntohs(*((uint16_t*)msg_data))); - m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t))))); - m->Assign(2, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t) + - sizeof(uint64_t))))); - off += sizeof(uint16_t) + 2 * sizeof(uint64_t); - m->Assign(3, BuildOptionsVal(data + off, Length() - off)); - msg->Assign(4, std::move(m)); - break; - } - - case 4: - { - auto m = make_intrusive(ip6_mob_cot_type); - m->Assign(0, ntohs(*((uint16_t*)msg_data))); - m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t))))); - m->Assign(2, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t) + - sizeof(uint64_t))))); - off += sizeof(uint16_t) + 2 * sizeof(uint64_t); - m->Assign(3, BuildOptionsVal(data + off, Length() - off)); - msg->Assign(5, std::move(m)); - break; - } - - case 5: - { - auto m = make_intrusive(ip6_mob_bu_type); - m->Assign(0, ntohs(*((uint16_t*)msg_data))); - m->Assign(1, static_cast( - ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) & - 0x8000)); - m->Assign(2, static_cast( - ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) & - 0x4000)); - m->Assign(3, static_cast( - ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) & - 0x2000)); - m->Assign(4, static_cast( - ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) & - 0x1000)); - m->Assign(5, ntohs(*((uint16_t*)(msg_data + 2 * sizeof(uint16_t))))); - off += 3 * sizeof(uint16_t); - m->Assign(6, BuildOptionsVal(data + off, Length() - off)); - msg->Assign(6, std::move(m)); - break; - } - - case 6: - { - auto m = make_intrusive(ip6_mob_back_type); - m->Assign(0, *((uint8_t*)msg_data)); - m->Assign(1, static_cast( - *((uint8_t*)(msg_data + sizeof(uint8_t))) & 0x80)); - m->Assign(2, ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t))))); - m->Assign(3, ntohs(*((uint16_t*)(msg_data + 2 * sizeof(uint16_t))))); - off += 3 * sizeof(uint16_t); - m->Assign(4, BuildOptionsVal(data + off, Length() - off)); - msg->Assign(7, std::move(m)); - break; - } - - case 7: - { - auto m = make_intrusive(ip6_mob_be_type); - m->Assign(0, *((uint8_t*)msg_data)); - const in6_addr* hoa = (const in6_addr*)(msg_data + sizeof(uint16_t)); - m->Assign(1, make_intrusive(IPAddr(*hoa))); - off += sizeof(uint16_t) + sizeof(in6_addr); - m->Assign(2, BuildOptionsVal(data + off, Length() - off)); - msg->Assign(8, std::move(m)); - break; - } - - default: - reporter->Weird("unknown_mobility_type", util::fmt("%d", mob->ip6mob_type)); - break; + case 1: + { + auto m = make_intrusive(ip6_mob_hoti_type); + m->Assign(0, ntohs(*((uint16_t*)msg_data))); + m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t))))); + off += sizeof(uint16_t) + sizeof(uint64_t); + m->Assign(2, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(2, std::move(m)); + break; } - rv->Assign(5, std::move(msg)); + case 2: + { + auto m = make_intrusive(ip6_mob_coti_type); + m->Assign(0, ntohs(*((uint16_t*)msg_data))); + m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t))))); + off += sizeof(uint16_t) + sizeof(uint64_t); + m->Assign(2, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(3, std::move(m)); + break; + } + + case 3: + { + auto m = make_intrusive(ip6_mob_hot_type); + m->Assign(0, ntohs(*((uint16_t*)msg_data))); + m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t))))); + m->Assign( + 2, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t) + sizeof(uint64_t))))); + off += sizeof(uint16_t) + 2 * sizeof(uint64_t); + m->Assign(3, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(4, std::move(m)); + break; + } + + case 4: + { + auto m = make_intrusive(ip6_mob_cot_type); + m->Assign(0, ntohs(*((uint16_t*)msg_data))); + m->Assign(1, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t))))); + m->Assign( + 2, ntohll(*((uint64_t*)(msg_data + sizeof(uint16_t) + sizeof(uint64_t))))); + off += sizeof(uint16_t) + 2 * sizeof(uint64_t); + m->Assign(3, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(5, std::move(m)); + break; + } + + case 5: + { + auto m = make_intrusive(ip6_mob_bu_type); + m->Assign(0, ntohs(*((uint16_t*)msg_data))); + m->Assign(1, static_cast( + ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) & 0x8000)); + m->Assign(2, static_cast( + ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) & 0x4000)); + m->Assign(3, static_cast( + ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) & 0x2000)); + m->Assign(4, static_cast( + ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t)))) & 0x1000)); + m->Assign(5, ntohs(*((uint16_t*)(msg_data + 2 * sizeof(uint16_t))))); + off += 3 * sizeof(uint16_t); + m->Assign(6, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(6, std::move(m)); + break; + } + + case 6: + { + auto m = make_intrusive(ip6_mob_back_type); + m->Assign(0, *((uint8_t*)msg_data)); + m->Assign(1, + static_cast(*((uint8_t*)(msg_data + sizeof(uint8_t))) & 0x80)); + m->Assign(2, ntohs(*((uint16_t*)(msg_data + sizeof(uint16_t))))); + m->Assign(3, ntohs(*((uint16_t*)(msg_data + 2 * sizeof(uint16_t))))); + off += 3 * sizeof(uint16_t); + m->Assign(4, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(7, std::move(m)); + break; + } + + case 7: + { + auto m = make_intrusive(ip6_mob_be_type); + m->Assign(0, *((uint8_t*)msg_data)); + const in6_addr* hoa = (const in6_addr*)(msg_data + sizeof(uint16_t)); + m->Assign(1, make_intrusive(IPAddr(*hoa))); + off += sizeof(uint16_t) + sizeof(in6_addr); + m->Assign(2, BuildOptionsVal(data + off, Length() - off)); + msg->Assign(8, std::move(m)); + break; + } + + default: + reporter->Weird("unknown_mobility_type", util::fmt("%d", mob->ip6mob_type)); + break; } + + rv->Assign(5, std::move(msg)); + } break; default: @@ -384,67 +379,67 @@ RecordValPtr IP_Hdr::ToPktHdrVal(RecordValPtr pkt_hdr, int sindex) const switch ( proto ) { case IPPROTO_TCP: - { - const struct tcphdr* tp = (const struct tcphdr*)data; - auto tcp_hdr = make_intrusive(tcp_hdr_type); + { + const struct tcphdr* tp = (const struct tcphdr*)data; + auto tcp_hdr = make_intrusive(tcp_hdr_type); - int tcp_hdr_len = tp->th_off * 4; - int data_len = PayloadLen() - tcp_hdr_len; + int tcp_hdr_len = tp->th_off * 4; + int data_len = PayloadLen() - tcp_hdr_len; - tcp_hdr->Assign(0, val_mgr->Port(ntohs(tp->th_sport), TRANSPORT_TCP)); - tcp_hdr->Assign(1, val_mgr->Port(ntohs(tp->th_dport), TRANSPORT_TCP)); - tcp_hdr->Assign(2, ntohl(tp->th_seq)); - tcp_hdr->Assign(3, ntohl(tp->th_ack)); - tcp_hdr->Assign(4, tcp_hdr_len); - tcp_hdr->Assign(5, data_len); - tcp_hdr->Assign(6, tp->th_x2); - tcp_hdr->Assign(7, tp->th_flags); - tcp_hdr->Assign(8, ntohs(tp->th_win)); + tcp_hdr->Assign(0, val_mgr->Port(ntohs(tp->th_sport), TRANSPORT_TCP)); + tcp_hdr->Assign(1, val_mgr->Port(ntohs(tp->th_dport), TRANSPORT_TCP)); + tcp_hdr->Assign(2, ntohl(tp->th_seq)); + tcp_hdr->Assign(3, ntohl(tp->th_ack)); + tcp_hdr->Assign(4, tcp_hdr_len); + tcp_hdr->Assign(5, data_len); + tcp_hdr->Assign(6, tp->th_x2); + tcp_hdr->Assign(7, tp->th_flags); + tcp_hdr->Assign(8, ntohs(tp->th_win)); - pkt_hdr->Assign(sindex + 2, std::move(tcp_hdr)); - break; - } + pkt_hdr->Assign(sindex + 2, std::move(tcp_hdr)); + break; + } case IPPROTO_UDP: - { - const struct udphdr* up = (const struct udphdr*)data; - auto udp_hdr = make_intrusive(udp_hdr_type); + { + const struct udphdr* up = (const struct udphdr*)data; + auto udp_hdr = make_intrusive(udp_hdr_type); - udp_hdr->Assign(0, val_mgr->Port(ntohs(up->uh_sport), TRANSPORT_UDP)); - udp_hdr->Assign(1, val_mgr->Port(ntohs(up->uh_dport), TRANSPORT_UDP)); - udp_hdr->Assign(2, ntohs(up->uh_ulen)); + udp_hdr->Assign(0, val_mgr->Port(ntohs(up->uh_sport), TRANSPORT_UDP)); + udp_hdr->Assign(1, val_mgr->Port(ntohs(up->uh_dport), TRANSPORT_UDP)); + udp_hdr->Assign(2, ntohs(up->uh_ulen)); - pkt_hdr->Assign(sindex + 3, std::move(udp_hdr)); - break; - } + pkt_hdr->Assign(sindex + 3, std::move(udp_hdr)); + break; + } case IPPROTO_ICMP: - { - const struct icmp* icmpp = (const struct icmp*)data; - auto icmp_hdr = make_intrusive(icmp_hdr_type); + { + const struct icmp* icmpp = (const struct icmp*)data; + auto icmp_hdr = make_intrusive(icmp_hdr_type); - icmp_hdr->Assign(0, icmpp->icmp_type); + icmp_hdr->Assign(0, icmpp->icmp_type); - pkt_hdr->Assign(sindex + 4, std::move(icmp_hdr)); - break; - } + pkt_hdr->Assign(sindex + 4, std::move(icmp_hdr)); + break; + } case IPPROTO_ICMPV6: - { - const struct icmp6_hdr* icmpp = (const struct icmp6_hdr*)data; - auto icmp_hdr = make_intrusive(icmp_hdr_type); + { + const struct icmp6_hdr* icmpp = (const struct icmp6_hdr*)data; + auto icmp_hdr = make_intrusive(icmp_hdr_type); - icmp_hdr->Assign(0, icmpp->icmp6_type); + icmp_hdr->Assign(0, icmpp->icmp6_type); - pkt_hdr->Assign(sindex + 4, std::move(icmp_hdr)); - break; - } + pkt_hdr->Assign(sindex + 4, std::move(icmp_hdr)); + break; + } default: - { - // This is not a protocol we understand. - break; - } + { + // This is not a protocol we understand. + break; + } } return pkt_hdr; @@ -585,30 +580,30 @@ void IPv6_Hdr_Chain::ProcessRoutingHeader(const struct ip6_rthdr* r, uint16_t le switch ( r->ip6r_type ) { case 0: // Defined by RFC 2460, deprecated by RFC 5095 + { + if ( r->ip6r_segleft > 0 && r->ip6r_len >= 2 ) { - if ( r->ip6r_segleft > 0 && r->ip6r_len >= 2 ) - { - if ( r->ip6r_len % 2 == 0 ) - finalDst = new IPAddr(*addr); - else - reporter->Weird(SrcAddr(), DstAddr(), "odd_routing0_len"); - } - - // Always raise a weird since this type is deprecated. - reporter->Weird(SrcAddr(), DstAddr(), "routing0_hdr"); + if ( r->ip6r_len % 2 == 0 ) + finalDst = new IPAddr(*addr); + else + reporter->Weird(SrcAddr(), DstAddr(), "odd_routing0_len"); } + + // Always raise a weird since this type is deprecated. + reporter->Weird(SrcAddr(), DstAddr(), "routing0_hdr"); + } break; case 2: // Defined by Mobile IPv6 RFC 6275. + { + if ( r->ip6r_segleft > 0 ) { - if ( r->ip6r_segleft > 0 ) - { - if ( r->ip6r_len == 2 ) - finalDst = new IPAddr(*addr); - else - reporter->Weird(SrcAddr(), DstAddr(), "bad_routing2_len"); - } + if ( r->ip6r_len == 2 ) + finalDst = new IPAddr(*addr); + else + reporter->Weird(SrcAddr(), DstAddr(), "bad_routing2_len"); } + } break; default: @@ -642,36 +637,35 @@ void IPv6_Hdr_Chain::ProcessDstOpts(const struct ip6_dest* d, uint16_t len) len -= sizeof(uint8_t); break; default: + { + // Double-check that the len can hold the whole option structure. + // Otherwise we get a buffer-overflow when we check the option_len. + // Also check that it holds everything for the option itself. + if ( len < sizeof(struct ip6_opt) || len < sizeof(struct ip6_opt) + opt->ip6o_len ) { - // Double-check that the len can hold the whole option structure. - // Otherwise we get a buffer-overflow when we check the option_len. - // Also check that it holds everything for the option itself. - if ( len < sizeof(struct ip6_opt) || - len < sizeof(struct ip6_opt) + opt->ip6o_len ) - { - reporter->Weird(SrcAddr(), DstAddr(), "bad_ipv6_dest_opt_len"); - len = 0; - break; - } - - if ( opt->ip6o_type == - 201 ) // Home Address Option, Mobile IPv6 RFC 6275 section 6.3 - { - if ( opt->ip6o_len == sizeof(struct in6_addr) ) - { - if ( homeAddr ) - reporter->Weird(SrcAddr(), DstAddr(), "multiple_home_addr_opts"); - else - homeAddr = - new IPAddr(*((const in6_addr*)(data + sizeof(struct ip6_opt)))); - } - else - reporter->Weird(SrcAddr(), DstAddr(), "bad_home_addr_len"); - } - - data += sizeof(struct ip6_opt) + opt->ip6o_len; - len -= sizeof(struct ip6_opt) + opt->ip6o_len; + reporter->Weird(SrcAddr(), DstAddr(), "bad_ipv6_dest_opt_len"); + len = 0; + break; } + + if ( opt->ip6o_type == + 201 ) // Home Address Option, Mobile IPv6 RFC 6275 section 6.3 + { + if ( opt->ip6o_len == sizeof(struct in6_addr) ) + { + if ( homeAddr ) + reporter->Weird(SrcAddr(), DstAddr(), "multiple_home_addr_opts"); + else + homeAddr = + new IPAddr(*((const in6_addr*)(data + sizeof(struct ip6_opt)))); + } + else + reporter->Weird(SrcAddr(), DstAddr(), "bad_home_addr_len"); + } + + data += sizeof(struct ip6_opt) + opt->ip6o_len; + len -= sizeof(struct ip6_opt) + opt->ip6o_len; + } break; } } diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index d8d709cdf0..9e00e3aa70 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -1285,38 +1285,38 @@ static bool val_to_maskedval(Val* v, maskedvalue_list* append_to, vectorpush_back(v->AsSubNet()); + delete mval; + return true; + } + else + { + const uint32_t* n; + uint32_t m[4]; + v->AsSubNet().Prefix().GetBytes(&n); + v->AsSubNetVal()->Mask().CopyIPv6(m); + + for ( unsigned int i = 0; i < 4; ++i ) + m[i] = ntohl(m[i]); + + bool is_v4_mask = m[0] == 0xffffffff && m[1] == m[0] && m[2] == m[0]; + + if ( v->AsSubNet().Prefix().GetFamily() == IPv4 && is_v4_mask ) { - prefix_vector->push_back(v->AsSubNet()); - delete mval; - return true; + mval->val = ntohl(*n); + mval->mask = m[3]; } else { - const uint32_t* n; - uint32_t m[4]; - v->AsSubNet().Prefix().GetBytes(&n); - v->AsSubNetVal()->Mask().CopyIPv6(m); - - for ( unsigned int i = 0; i < 4; ++i ) - m[i] = ntohl(m[i]); - - bool is_v4_mask = m[0] == 0xffffffff && m[1] == m[0] && m[2] == m[0]; - - if ( v->AsSubNet().Prefix().GetFamily() == IPv4 && is_v4_mask ) - { - mval->val = ntohl(*n); - mval->mask = m[3]; - } - else - { - rules_error("IPv6 subnets not supported"); - mval->val = 0; - mval->mask = 0; - } + rules_error("IPv6 subnets not supported"); + mval->val = 0; + mval->mask = 0; } } + } break; default: diff --git a/src/Stmt.cc b/src/Stmt.cc index e2a01395b8..257b2fd7a1 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -353,10 +353,10 @@ void do_print_stmt(const std::vector& vals) case BifEnum::Log::REDIRECT_NONE: break; case BifEnum::Log::REDIRECT_ALL: - { - print_log(vals); - return; - } + { + print_log(vals); + return; + } case BifEnum::Log::REDIRECT_STDOUT: if ( f->FileHandle() == stdout ) { @@ -765,35 +765,35 @@ SwitchStmt::SwitchStmt(ExprPtr index, case_list* arg_cases) { // Simplify trivial unary plus/minus expressions on consts. case EXPR_NEGATE: - { - NegExpr* ne = (NegExpr*)(expr); + { + NegExpr* ne = (NegExpr*)(expr); - if ( ne->Op()->IsConst() ) - Unref(exprs.replace(j, new ConstExpr(ne->Eval(nullptr)))); - } + if ( ne->Op()->IsConst() ) + Unref(exprs.replace(j, new ConstExpr(ne->Eval(nullptr)))); + } break; case EXPR_POSITIVE: - { - PosExpr* pe = (PosExpr*)(expr); + { + PosExpr* pe = (PosExpr*)(expr); - if ( pe->Op()->IsConst() ) - Unref(exprs.replace(j, new ConstExpr(pe->Eval(nullptr)))); - } + if ( pe->Op()->IsConst() ) + Unref(exprs.replace(j, new ConstExpr(pe->Eval(nullptr)))); + } break; case EXPR_NAME: + { + NameExpr* ne = (NameExpr*)(expr); + + if ( ne->Id()->IsConst() ) { - NameExpr* ne = (NameExpr*)(expr); + auto v = ne->Eval(nullptr); - if ( ne->Id()->IsConst() ) - { - auto v = ne->Eval(nullptr); - - if ( v ) - Unref(exprs.replace(j, new ConstExpr(std::move(v)))); - } + if ( v ) + Unref(exprs.replace(j, new ConstExpr(std::move(v)))); } + } break; default: diff --git a/src/Trigger.cc b/src/Trigger.cc index ba1aa31d23..ba9825071f 100644 --- a/src/Trigger.cc +++ b/src/Trigger.cc @@ -48,17 +48,17 @@ TraversalCode trigger::TriggerTraversalCallback::PreExpr(const Expr* expr) switch ( expr->Tag() ) { case EXPR_NAME: - { - const auto* e = static_cast(expr); - if ( e->Id()->IsGlobal() ) - trigger->Register(e->Id()); + { + const auto* e = static_cast(expr); + if ( e->Id()->IsGlobal() ) + trigger->Register(e->Id()); - Val* v = e->Id()->GetVal().get(); + Val* v = e->Id()->GetVal().get(); - if ( v && v->Modifiable() ) - trigger->Register(v); - break; - }; + if ( v && v->Modifiable() ) + trigger->Register(v); + break; + }; default: // All others are uninteresting. diff --git a/src/Type.cc b/src/Type.cc index 0d3a6e10cc..7e04f80f74 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -459,39 +459,39 @@ static bool is_supported_index_type(const TypePtr& t, const char** tname) return true; case TYPE_RECORD: - { - auto rt = t->AsRecordType(); + { + auto rt = t->AsRecordType(); - for ( auto i = 0; i < rt->NumFields(); ++i ) - if ( ! is_supported_index_type(rt->GetFieldType(i), tname) ) - return false; - - return true; - } - - case TYPE_LIST: - { - for ( const auto& type : t->AsTypeList()->GetTypes() ) - if ( ! is_supported_index_type(type, tname) ) - return false; - - return true; - } - - case TYPE_TABLE: - { - auto tt = t->AsTableType(); - - if ( ! is_supported_index_type(tt->GetIndices(), tname) ) + for ( auto i = 0; i < rt->NumFields(); ++i ) + if ( ! is_supported_index_type(rt->GetFieldType(i), tname) ) return false; - const auto& yt = tt->Yield(); + return true; + } - if ( ! yt ) - return true; + case TYPE_LIST: + { + for ( const auto& type : t->AsTypeList()->GetTypes() ) + if ( ! is_supported_index_type(type, tname) ) + return false; - return is_supported_index_type(yt, tname); - } + return true; + } + + case TYPE_TABLE: + { + auto tt = t->AsTableType(); + + if ( ! is_supported_index_type(tt->GetIndices(), tname) ) + return false; + + const auto& yt = tt->Yield(); + + if ( ! yt ) + return true; + + return is_supported_index_type(yt, tname); + } case TYPE_VECTOR: return is_supported_index_type(t->AsVectorType()->Yield(), tname); @@ -1254,23 +1254,23 @@ void RecordType::Create(std::vector>& r) const break; case FieldInit::R_INIT_DEF: + { + auto v = init->def_expr->Eval(nullptr); + if ( v ) { - auto v = init->def_expr->Eval(nullptr); - if ( v ) + const auto& t = init->def_type; + + if ( init->def_coerce ) { - const auto& t = init->def_type; - - if ( init->def_coerce ) - { - auto rt = cast_intrusive(t); - v = v->AsRecordVal()->CoerceTo(rt); - } - - r_i = ZVal(v, t); + auto rt = cast_intrusive(t); + v = v->AsRecordVal()->CoerceTo(rt); } - else - reporter->Error("failed &default in record creation"); + + r_i = ZVal(v, t); } + else + reporter->Error("failed &default in record creation"); + } break; case FieldInit::R_INIT_RECORD: @@ -1904,81 +1904,81 @@ bool same_type(const Type& arg_t1, const Type& arg_t2, bool is_init, bool match_ return true; case TYPE_OPAQUE: - { - const OpaqueType* ot1 = (const OpaqueType*)t1; - const OpaqueType* ot2 = (const OpaqueType*)t2; - return ot1->Name() == ot2->Name(); - } + { + const OpaqueType* ot1 = (const OpaqueType*)t1; + const OpaqueType* ot2 = (const OpaqueType*)t2; + return ot1->Name() == ot2->Name(); + } case TYPE_TABLE: - { - const IndexType* it1 = (const IndexType*)t1; - const IndexType* it2 = (const IndexType*)t2; + { + const IndexType* it1 = (const IndexType*)t1; + const IndexType* it2 = (const IndexType*)t2; - const auto& tl1 = it1->GetIndices(); - const auto& tl2 = it2->GetIndices(); + const auto& tl1 = it1->GetIndices(); + const auto& tl2 = it2->GetIndices(); - if ( (tl1 || tl2) && ! (tl1 && tl2) ) - return false; + if ( (tl1 || tl2) && ! (tl1 && tl2) ) + return false; - const auto& y1 = t1->Yield(); - const auto& y2 = t2->Yield(); + const auto& y1 = t1->Yield(); + const auto& y2 = t2->Yield(); - if ( (y1 || y2) && ! (y1 && y2) ) - return false; + if ( (y1 || y2) && ! (y1 && y2) ) + return false; - break; - } + break; + } case TYPE_FUNC: - { - const FuncType* ft1 = (const FuncType*)t1; - const FuncType* ft2 = (const FuncType*)t2; + { + const FuncType* ft1 = (const FuncType*)t1; + const FuncType* ft2 = (const FuncType*)t2; - if ( ft1->Flavor() != ft2->Flavor() ) - return false; + if ( ft1->Flavor() != ft2->Flavor() ) + return false; - const auto& y1 = t1->Yield(); - const auto& y2 = t2->Yield(); - if ( (y1 || y2) && ! (y1 && y2) ) - return false; + const auto& y1 = t1->Yield(); + const auto& y2 = t2->Yield(); + if ( (y1 || y2) && ! (y1 && y2) ) + return false; - break; - } + break; + } case TYPE_RECORD: - { - const RecordType* rt1 = (const RecordType*)t1; - const RecordType* rt2 = (const RecordType*)t2; + { + const RecordType* rt1 = (const RecordType*)t1; + const RecordType* rt2 = (const RecordType*)t2; - if ( rt1->NumFields() != rt2->NumFields() ) + if ( rt1->NumFields() != rt2->NumFields() ) + return false; + + for ( int i = 0; i < rt1->NumFields(); ++i ) + { + const TypeDecl* td1 = rt1->FieldDecl(i); + const TypeDecl* td2 = rt2->FieldDecl(i); + + if ( match_record_field_names && ! util::streq(td1->id, td2->id) ) return false; - for ( int i = 0; i < rt1->NumFields(); ++i ) - { - const TypeDecl* td1 = rt1->FieldDecl(i); - const TypeDecl* td2 = rt2->FieldDecl(i); - - if ( match_record_field_names && ! util::streq(td1->id, td2->id) ) - return false; - - if ( ! same_attrs(td1->attrs.get(), td2->attrs.get()) ) - return false; - } - - break; + if ( ! same_attrs(td1->attrs.get(), td2->attrs.get()) ) + return false; } + break; + } + case TYPE_LIST: - { - const auto& tl1 = t1->AsTypeList()->GetTypes(); - const auto& tl2 = t2->AsTypeList()->GetTypes(); + { + const auto& tl1 = t1->AsTypeList()->GetTypes(); + const auto& tl2 = t2->AsTypeList()->GetTypes(); - if ( tl1.size() != tl2.size() ) - return false; + if ( tl1.size() != tl2.size() ) + return false; - break; - } + break; + } case TYPE_VECTOR: case TYPE_FILE: @@ -2024,73 +2024,73 @@ bool same_type(const Type& arg_t1, const Type& arg_t2, bool is_init, bool match_ switch ( t1->Tag() ) { case TYPE_TABLE: + { + const IndexType* it1 = (const IndexType*)t1; + const IndexType* it2 = (const IndexType*)t2; + + const auto& tl1 = it1->GetIndices(); + const auto& tl2 = it2->GetIndices(); + + if ( ! same_type(tl1, tl2, is_init, match_record_field_names) ) + result = false; + else { - const IndexType* it1 = (const IndexType*)t1; - const IndexType* it2 = (const IndexType*)t2; + const auto& y1 = t1->Yield(); + const auto& y2 = t2->Yield(); - const auto& tl1 = it1->GetIndices(); - const auto& tl2 = it2->GetIndices(); - - if ( ! same_type(tl1, tl2, is_init, match_record_field_names) ) - result = false; - else - { - const auto& y1 = t1->Yield(); - const auto& y2 = t2->Yield(); - - result = same_type(y1, y2, is_init, match_record_field_names); - } - break; + result = same_type(y1, y2, is_init, match_record_field_names); } + break; + } case TYPE_FUNC: - { - const FuncType* ft1 = (const FuncType*)t1; - const FuncType* ft2 = (const FuncType*)t2; + { + const FuncType* ft1 = (const FuncType*)t1; + const FuncType* ft2 = (const FuncType*)t2; - if ( ! same_type(t1->Yield(), t2->Yield(), is_init, match_record_field_names) ) - result = false; - else - result = ft1->CheckArgs(ft2->ParamList()->GetTypes(), is_init, false); - break; - } + if ( ! same_type(t1->Yield(), t2->Yield(), is_init, match_record_field_names) ) + result = false; + else + result = ft1->CheckArgs(ft2->ParamList()->GetTypes(), is_init, false); + break; + } case TYPE_RECORD: + { + const RecordType* rt1 = (const RecordType*)t1; + const RecordType* rt2 = (const RecordType*)t2; + + result = true; + + for ( int i = 0; i < rt1->NumFields(); ++i ) { - const RecordType* rt1 = (const RecordType*)t1; - const RecordType* rt2 = (const RecordType*)t2; + const TypeDecl* td1 = rt1->FieldDecl(i); + const TypeDecl* td2 = rt2->FieldDecl(i); - result = true; - - for ( int i = 0; i < rt1->NumFields(); ++i ) + if ( ! same_type(td1->type, td2->type, is_init, match_record_field_names) ) { - const TypeDecl* td1 = rt1->FieldDecl(i); - const TypeDecl* td2 = rt2->FieldDecl(i); - - if ( ! same_type(td1->type, td2->type, is_init, match_record_field_names) ) - { - result = false; - break; - } + result = false; + break; } - break; } + break; + } case TYPE_LIST: - { - const auto& tl1 = t1->AsTypeList()->GetTypes(); - const auto& tl2 = t2->AsTypeList()->GetTypes(); + { + const auto& tl1 = t1->AsTypeList()->GetTypes(); + const auto& tl2 = t2->AsTypeList()->GetTypes(); - result = true; + result = true; - for ( auto i = 0u; i < tl1.size(); ++i ) - if ( ! same_type(tl1[i], tl2[i], is_init, match_record_field_names) ) - { - result = false; - break; - } - break; - } + for ( auto i = 0u; i < tl1.size(); ++i ) + if ( ! same_type(tl1[i], tl2[i], is_init, match_record_field_names) ) + { + result = false; + break; + } + break; + } case TYPE_VECTOR: case TYPE_FILE: @@ -2098,13 +2098,12 @@ bool same_type(const Type& arg_t1, const Type& arg_t2, bool is_init, bool match_ break; case TYPE_TYPE: - { - auto tt1 = t1->AsTypeType(); - auto tt2 = t2->AsTypeType(); - result = - same_type(tt1->GetType(), tt1->GetType(), is_init, match_record_field_names); - break; - } + { + auto tt1 = t1->AsTypeType(); + auto tt2 = t2->AsTypeType(); + result = same_type(tt1->GetType(), tt1->GetType(), is_init, match_record_field_names); + break; + } default: result = false; @@ -2287,180 +2286,180 @@ TypePtr merge_types(const TypePtr& arg_t1, const TypePtr& arg_t2) return base_type(tg1); case TYPE_ENUM: + { + // Could compare pointers t1 == t2, but maybe there's someone out + // there creating clones of the type, so safer to compare name. + if ( t1->GetName() != t2->GetName() ) { - // Could compare pointers t1 == t2, but maybe there's someone out - // there creating clones of the type, so safer to compare name. - if ( t1->GetName() != t2->GetName() ) - { - std::string msg = util::fmt("incompatible enum types: '%s' and '%s'", - t1->GetName().data(), t2->GetName().data()); + std::string msg = util::fmt("incompatible enum types: '%s' and '%s'", + t1->GetName().data(), t2->GetName().data()); - t1->Error(msg.data(), t2); - return nullptr; - } - - // Doing a lookup here as a roundabout way of ref-ing t1, without - // changing the function params which has t1 as const and also - // (potentially) avoiding a pitfall mentioned earlier about clones. - const auto& id = detail::global_scope()->Find(t1->GetName()); - - if ( id && id->IsType() && id->GetType()->Tag() == TYPE_ENUM ) - // It should make most sense to return the real type here rather - // than a copy since it may be redef'd later in parsing. If we - // return a copy, then whoever is using this return value won't - // actually see those changes from the redef. - return id->GetType(); - - std::string msg = - util::fmt("incompatible enum types: '%s' and '%s'" - " ('%s' enum type ID is invalid)", - t1->GetName().data(), t2->GetName().data(), t1->GetName().data()); t1->Error(msg.data(), t2); return nullptr; } + // Doing a lookup here as a roundabout way of ref-ing t1, without + // changing the function params which has t1 as const and also + // (potentially) avoiding a pitfall mentioned earlier about clones. + const auto& id = detail::global_scope()->Find(t1->GetName()); + + if ( id && id->IsType() && id->GetType()->Tag() == TYPE_ENUM ) + // It should make most sense to return the real type here rather + // than a copy since it may be redef'd later in parsing. If we + // return a copy, then whoever is using this return value won't + // actually see those changes from the redef. + return id->GetType(); + + std::string msg = + util::fmt("incompatible enum types: '%s' and '%s'" + " ('%s' enum type ID is invalid)", + t1->GetName().data(), t2->GetName().data(), t1->GetName().data()); + t1->Error(msg.data(), t2); + return nullptr; + } + case TYPE_TABLE: + { + const IndexType* it1 = (const IndexType*)t1; + const IndexType* it2 = (const IndexType*)t2; + + const auto& tl1 = it1->GetIndexTypes(); + const auto& tl2 = it2->GetIndexTypes(); + TypeListPtr tl3; + + if ( tl1.size() != tl2.size() ) { - const IndexType* it1 = (const IndexType*)t1; - const IndexType* it2 = (const IndexType*)t2; + t1->Error("incompatible types", t2); + return nullptr; + } - const auto& tl1 = it1->GetIndexTypes(); - const auto& tl2 = it2->GetIndexTypes(); - TypeListPtr tl3; + tl3 = make_intrusive(); - if ( tl1.size() != tl2.size() ) + for ( auto i = 0u; i < tl1.size(); ++i ) + { + auto tl3_i = merge_types(tl1[i], tl2[i]); + if ( ! tl3_i ) + return nullptr; + + tl3->Append(std::move(tl3_i)); + } + + const auto& y1 = t1->Yield(); + const auto& y2 = t2->Yield(); + TypePtr y3; + + if ( y1 || y2 ) + { + if ( ! y1 || ! y2 ) { t1->Error("incompatible types", t2); return nullptr; } - tl3 = make_intrusive(); - - for ( auto i = 0u; i < tl1.size(); ++i ) - { - auto tl3_i = merge_types(tl1[i], tl2[i]); - if ( ! tl3_i ) - return nullptr; - - tl3->Append(std::move(tl3_i)); - } - - const auto& y1 = t1->Yield(); - const auto& y2 = t2->Yield(); - TypePtr y3; - - if ( y1 || y2 ) - { - if ( ! y1 || ! y2 ) - { - t1->Error("incompatible types", t2); - return nullptr; - } - - y3 = merge_types(y1, y2); - if ( ! y3 ) - return nullptr; - } - - if ( t1->IsSet() ) - return make_intrusive(std::move(tl3), nullptr); - else - return make_intrusive(std::move(tl3), std::move(y3)); + y3 = merge_types(y1, y2); + if ( ! y3 ) + return nullptr; } + if ( t1->IsSet() ) + return make_intrusive(std::move(tl3), nullptr); + else + return make_intrusive(std::move(tl3), std::move(y3)); + } + case TYPE_FUNC: + { + if ( ! same_type(t1, t2) ) { - if ( ! same_type(t1, t2) ) - { - t1->Error("incompatible types", t2); - return nullptr; - } - - const FuncType* ft1 = (const FuncType*)t1; - const FuncType* ft2 = (const FuncType*)t1; - auto args = cast_intrusive(merge_types(ft1->Params(), ft2->Params())); - auto yield = t1->Yield() ? merge_types(t1->Yield(), t2->Yield()) : nullptr; - - return make_intrusive(std::move(args), std::move(yield), ft1->Flavor()); + t1->Error("incompatible types", t2); + return nullptr; } + const FuncType* ft1 = (const FuncType*)t1; + const FuncType* ft2 = (const FuncType*)t1; + auto args = cast_intrusive(merge_types(ft1->Params(), ft2->Params())); + auto yield = t1->Yield() ? merge_types(t1->Yield(), t2->Yield()) : nullptr; + + return make_intrusive(std::move(args), std::move(yield), ft1->Flavor()); + } + case TYPE_RECORD: + { + const RecordType* rt1 = (const RecordType*)t1; + const RecordType* rt2 = (const RecordType*)t2; + + if ( rt1->NumFields() != rt2->NumFields() ) + return nullptr; + + type_decl_list* tdl3 = new type_decl_list(rt1->NumFields()); + + for ( int i = 0; i < rt1->NumFields(); ++i ) { - const RecordType* rt1 = (const RecordType*)t1; - const RecordType* rt2 = (const RecordType*)t2; + const TypeDecl* td1 = rt1->FieldDecl(i); + const TypeDecl* td2 = rt2->FieldDecl(i); + auto tdl3_i = merge_types(td1->type, td2->type); - if ( rt1->NumFields() != rt2->NumFields() ) - return nullptr; - - type_decl_list* tdl3 = new type_decl_list(rt1->NumFields()); - - for ( int i = 0; i < rt1->NumFields(); ++i ) + if ( ! util::streq(td1->id, td2->id) || ! tdl3_i ) { - const TypeDecl* td1 = rt1->FieldDecl(i); - const TypeDecl* td2 = rt2->FieldDecl(i); - auto tdl3_i = merge_types(td1->type, td2->type); - - if ( ! util::streq(td1->id, td2->id) || ! tdl3_i ) - { - t1->Error("incompatible record fields", t2); - delete tdl3; - return nullptr; - } - - tdl3->push_back(new TypeDecl(util::copy_string(td1->id), std::move(tdl3_i))); + t1->Error("incompatible record fields", t2); + delete tdl3; + return nullptr; } - return make_intrusive(tdl3); + tdl3->push_back(new TypeDecl(util::copy_string(td1->id), std::move(tdl3_i))); } + return make_intrusive(tdl3); + } + case TYPE_LIST: + { + const TypeList* tl1 = t1->AsTypeList(); + const TypeList* tl2 = t2->AsTypeList(); + + if ( tl1->IsPure() != tl2->IsPure() ) { - const TypeList* tl1 = t1->AsTypeList(); - const TypeList* tl2 = t2->AsTypeList(); - - if ( tl1->IsPure() != tl2->IsPure() ) - { - tl1->Error("incompatible lists", tl2); - return nullptr; - } - - const auto& l1 = tl1->GetTypes(); - const auto& l2 = tl2->GetTypes(); - - if ( l1.size() == 0 || l2.size() == 0 ) - { - if ( l1.size() == 0 ) - tl1->Error("empty list"); - else - tl2->Error("empty list"); - return nullptr; - } - - if ( tl1->IsPure() ) - { - // We will be expanding the pure list when converting - // the initialization expression into a set of values. - // So the merge type of the list is the type of one - // of the elements, providing they're consistent. - return merge_types(l1[0], l2[0]); - } - - // Impure lists - must have the same size and match element - // by element. - if ( l1.size() != l2.size() ) - { - tl1->Error("different number of indices", tl2); - return nullptr; - } - - auto tl3 = make_intrusive(); - - for ( auto i = 0u; i < l1.size(); ++i ) - tl3->Append(merge_types(l1[i], l2[i])); - - return tl3; + tl1->Error("incompatible lists", tl2); + return nullptr; } + const auto& l1 = tl1->GetTypes(); + const auto& l2 = tl2->GetTypes(); + + if ( l1.size() == 0 || l2.size() == 0 ) + { + if ( l1.size() == 0 ) + tl1->Error("empty list"); + else + tl2->Error("empty list"); + return nullptr; + } + + if ( tl1->IsPure() ) + { + // We will be expanding the pure list when converting + // the initialization expression into a set of values. + // So the merge type of the list is the type of one + // of the elements, providing they're consistent. + return merge_types(l1[0], l2[0]); + } + + // Impure lists - must have the same size and match element + // by element. + if ( l1.size() != l2.size() ) + { + tl1->Error("different number of indices", tl2); + return nullptr; + } + + auto tl3 = make_intrusive(); + + for ( auto i = 0u; i < l1.size(); ++i ) + tl3->Append(merge_types(l1[i], l2[i])); + + return tl3; + } + case TYPE_VECTOR: if ( ! same_type(t1->Yield(), t2->Yield()) ) { diff --git a/src/Val.cc b/src/Val.cc index 294ffebd5a..3fa01f64c1 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -444,161 +444,161 @@ static void BuildJSON(threading::formatter::JSON::NullDoubleWriter& writer, Val* break; case TYPE_PORT: - { - auto* pval = val->AsPortVal(); - writer.StartObject(); - writer.Key("port"); - writer.Int64(pval->Port()); - writer.Key("proto"); - writer.String(pval->Protocol()); - writer.EndObject(); - break; - } + { + auto* pval = val->AsPortVal(); + writer.StartObject(); + writer.Key("port"); + writer.Int64(pval->Port()); + writer.Key("proto"); + writer.String(pval->Protocol()); + writer.EndObject(); + break; + } case TYPE_PATTERN: case TYPE_INTERVAL: case TYPE_ADDR: case TYPE_SUBNET: - { - ODesc d; - d.SetStyle(RAW_STYLE); - val->Describe(&d); - writer.String(reinterpret_cast(d.Bytes()), d.Len()); - break; - } + { + ODesc d; + d.SetStyle(RAW_STYLE); + val->Describe(&d); + writer.String(reinterpret_cast(d.Bytes()), d.Len()); + break; + } case TYPE_FILE: case TYPE_FUNC: case TYPE_ENUM: case TYPE_STRING: - { - ODesc d; - d.SetStyle(RAW_STYLE); - val->Describe(&d); - writer.String(util::json_escape_utf8( - std::string(reinterpret_cast(d.Bytes()), d.Len()))); - break; - } + { + ODesc d; + d.SetStyle(RAW_STYLE); + val->Describe(&d); + writer.String(util::json_escape_utf8( + std::string(reinterpret_cast(d.Bytes()), d.Len()))); + break; + } case TYPE_TABLE: + { + auto* table = val->AsTable(); + auto* tval = val->AsTableVal(); + + if ( tval->GetType()->IsSet() ) + writer.StartArray(); + else + writer.StartObject(); + + std::unique_ptr k; + TableEntryVal* entry; + + for ( const auto& te : *table ) { - auto* table = val->AsTable(); - auto* tval = val->AsTableVal(); + entry = te.GetValue(); + k = te.GetHashKey(); + + auto lv = tval->RecreateIndex(*k); + Val* entry_key = lv->Length() == 1 ? lv->Idx(0).get() : lv.get(); if ( tval->GetType()->IsSet() ) - writer.StartArray(); + BuildJSON(writer, entry_key, only_loggable, re); else - writer.StartObject(); - - std::unique_ptr k; - TableEntryVal* entry; - - for ( const auto& te : *table ) { - entry = te.GetValue(); - k = te.GetHashKey(); + rapidjson::StringBuffer buffer; + threading::formatter::JSON::NullDoubleWriter key_writer(buffer); + BuildJSON(key_writer, entry_key, only_loggable, re); + string key_str = buffer.GetString(); - auto lv = tval->RecreateIndex(*k); - Val* entry_key = lv->Length() == 1 ? lv->Idx(0).get() : lv.get(); + if ( key_str.length() >= 2 && key_str[0] == '"' && + key_str[key_str.length() - 1] == '"' ) + // Strip quotes. + key_str = key_str.substr(1, key_str.length() - 2); - if ( tval->GetType()->IsSet() ) - BuildJSON(writer, entry_key, only_loggable, re); - else - { - rapidjson::StringBuffer buffer; - threading::formatter::JSON::NullDoubleWriter key_writer(buffer); - BuildJSON(key_writer, entry_key, only_loggable, re); - string key_str = buffer.GetString(); - - if ( key_str.length() >= 2 && key_str[0] == '"' && - key_str[key_str.length() - 1] == '"' ) - // Strip quotes. - key_str = key_str.substr(1, key_str.length() - 2); - - BuildJSON(writer, entry->GetVal().get(), only_loggable, re, key_str); - } + BuildJSON(writer, entry->GetVal().get(), only_loggable, re, key_str); } - - if ( tval->GetType()->IsSet() ) - writer.EndArray(); - else - writer.EndObject(); - - break; } + if ( tval->GetType()->IsSet() ) + writer.EndArray(); + else + writer.EndObject(); + + break; + } + case TYPE_RECORD: + { + writer.StartObject(); + + auto* rval = val->AsRecordVal(); + auto rt = rval->GetType()->AsRecordType(); + + for ( auto i = 0; i < rt->NumFields(); ++i ) { - writer.StartObject(); + auto value = rval->GetFieldOrDefault(i); - auto* rval = val->AsRecordVal(); - auto rt = rval->GetType()->AsRecordType(); - - for ( auto i = 0; i < rt->NumFields(); ++i ) + if ( value && (! only_loggable || rt->FieldHasAttr(i, detail::ATTR_LOG)) ) { - auto value = rval->GetFieldOrDefault(i); + string key_str; + auto field_name = rt->FieldName(i); - if ( value && (! only_loggable || rt->FieldHasAttr(i, detail::ATTR_LOG)) ) + if ( re && re->MatchAnywhere(field_name) != 0 ) { - string key_str; - auto field_name = rt->FieldName(i); - - if ( re && re->MatchAnywhere(field_name) != 0 ) - { - auto blank = make_intrusive(""); - auto fn_val = make_intrusive(field_name); - const auto& bs = *blank->AsString(); - auto key_val = fn_val->Replace(re, bs, false); - key_str = key_val->ToStdString(); - } - else - key_str = field_name; - - BuildJSON(writer, value.get(), only_loggable, re, key_str); + auto blank = make_intrusive(""); + auto fn_val = make_intrusive(field_name); + const auto& bs = *blank->AsString(); + auto key_val = fn_val->Replace(re, bs, false); + key_str = key_val->ToStdString(); } - } + else + key_str = field_name; - writer.EndObject(); - break; + BuildJSON(writer, value.get(), only_loggable, re, key_str); + } } + writer.EndObject(); + break; + } + case TYPE_LIST: - { - writer.StartArray(); + { + writer.StartArray(); - auto* lval = val->AsListVal(); - size_t size = lval->Length(); - for ( size_t i = 0; i < size; i++ ) - BuildJSON(writer, lval->Idx(i).get(), only_loggable, re); + auto* lval = val->AsListVal(); + size_t size = lval->Length(); + for ( size_t i = 0; i < size; i++ ) + BuildJSON(writer, lval->Idx(i).get(), only_loggable, re); - writer.EndArray(); - break; - } + writer.EndArray(); + break; + } case TYPE_VECTOR: - { - writer.StartArray(); + { + writer.StartArray(); - auto* vval = val->AsVectorVal(); - size_t size = vval->SizeVal()->AsCount(); - for ( size_t i = 0; i < size; i++ ) - BuildJSON(writer, vval->ValAt(i).get(), only_loggable, re); + auto* vval = val->AsVectorVal(); + size_t size = vval->SizeVal()->AsCount(); + for ( size_t i = 0; i < size; i++ ) + BuildJSON(writer, vval->ValAt(i).get(), only_loggable, re); - writer.EndArray(); - break; - } + writer.EndArray(); + break; + } case TYPE_OPAQUE: - { - writer.StartObject(); + { + writer.StartObject(); - writer.Key("opaque_type"); - auto* oval = val->AsOpaqueVal(); - writer.String(OpaqueMgr::mgr()->TypeID(oval)); + writer.Key("opaque_type"); + auto* oval = val->AsOpaqueVal(); + writer.String(OpaqueMgr::mgr()->TypeID(oval)); - writer.EndObject(); - break; - } + writer.EndObject(); + break; + } default: writer.Null(); @@ -1369,23 +1369,23 @@ static void find_nested_record_types(const TypePtr& t, std::set* fo switch ( t->Tag() ) { case TYPE_RECORD: - { - auto rt = t->AsRecordType(); - found->emplace(rt); + { + auto rt = t->AsRecordType(); + found->emplace(rt); - for ( auto i = 0; i < rt->NumFields(); ++i ) - find_nested_record_types(rt->FieldDecl(i)->type, found); - } + for ( auto i = 0; i < rt->NumFields(); ++i ) + find_nested_record_types(rt->FieldDecl(i)->type, found); + } return; case TYPE_TABLE: find_nested_record_types(t->AsTableType()->GetIndices(), found); find_nested_record_types(t->AsTableType()->Yield(), found); return; case TYPE_LIST: - { - for ( const auto& type : t->AsTypeList()->GetTypes() ) - find_nested_record_types(type, found); - } + { + for ( const auto& type : t->AsTypeList()->GetTypes() ) + find_nested_record_types(type, found); + } return; case TYPE_FUNC: find_nested_record_types(t->AsFuncType()->Params(), found); @@ -2145,63 +2145,63 @@ void TableVal::SendToStore(const Val* index, const TableEntryVal* new_entry_val, { case ELEMENT_NEW: case ELEMENT_CHANGED: - { + { #ifndef __clang__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif - broker::optional expiry; + broker::optional expiry; #ifndef __clang__ #pragma GCC diagnostic pop #endif - auto expire_time = GetExpireTime(); - if ( expire_time == 0 ) - // Entry is set to immediately expire. Let's not forward it. - break; - - if ( expire_time > 0 ) - { - if ( attrs->Find(detail::ATTR_EXPIRE_CREATE) ) - { - // for create expiry, we have to substract the already elapsed time from - // the expiry. - auto e = expire_time - - (run_state::network_time - new_entry_val->ExpireAccessTime()); - if ( e <= 0 ) - // element already expired? Let's not insert it. - break; - - expiry = Broker::detail::convert_expiry(e); - } - else - expiry = Broker::detail::convert_expiry(expire_time); - } - - if ( table_type->IsSet() ) - handle->store.put(std::move(*broker_index), broker::data(), expiry); - else - { - if ( ! new_entry_val ) - { - emit_builtin_error( - "did not receive new value for Broker datastore send operation"); - return; - } - - auto new_value = new_entry_val->GetVal().get(); - auto broker_val = Broker::detail::val_to_data(new_value); - if ( ! broker_val ) - { - emit_builtin_error("invalid Broker data conversation for table value"); - return; - } - - handle->store.put(std::move(*broker_index), std::move(*broker_val), expiry); - } + auto expire_time = GetExpireTime(); + if ( expire_time == 0 ) + // Entry is set to immediately expire. Let's not forward it. break; + + if ( expire_time > 0 ) + { + if ( attrs->Find(detail::ATTR_EXPIRE_CREATE) ) + { + // for create expiry, we have to substract the already elapsed time from + // the expiry. + auto e = expire_time - + (run_state::network_time - new_entry_val->ExpireAccessTime()); + if ( e <= 0 ) + // element already expired? Let's not insert it. + break; + + expiry = Broker::detail::convert_expiry(e); + } + else + expiry = Broker::detail::convert_expiry(expire_time); } + if ( table_type->IsSet() ) + handle->store.put(std::move(*broker_index), broker::data(), expiry); + else + { + if ( ! new_entry_val ) + { + emit_builtin_error( + "did not receive new value for Broker datastore send operation"); + return; + } + + auto new_value = new_entry_val->GetVal().get(); + auto broker_val = Broker::detail::val_to_data(new_value); + if ( ! broker_val ) + { + emit_builtin_error("invalid Broker data conversation for table value"); + return; + } + + handle->store.put(std::move(*broker_index), std::move(*broker_val), expiry); + } + break; + } + case ELEMENT_REMOVED: handle->store.erase(std::move(*broker_index)); break; diff --git a/src/Var.cc b/src/Var.cc index e0d7f7c4c5..4067f17e4c 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -223,19 +223,19 @@ static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init, switch ( init->Tag() ) { case EXPR_TABLE_CONSTRUCTOR: - { - auto* ctor = static_cast(init.get()); - if ( ctor->GetAttrs() ) - id->AddAttrs(ctor->GetAttrs()); - } + { + auto* ctor = static_cast(init.get()); + if ( ctor->GetAttrs() ) + id->AddAttrs(ctor->GetAttrs()); + } break; case EXPR_SET_CONSTRUCTOR: - { - auto* ctor = static_cast(init.get()); - if ( ctor->GetAttrs() ) - id->AddAttrs(ctor->GetAttrs()); - } + { + auto* ctor = static_cast(init.get()); + if ( ctor->GetAttrs() ) + id->AddAttrs(ctor->GetAttrs()); + } break; default: diff --git a/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc b/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc index 34f3d0a77d..1e4d6d9278 100644 --- a/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc +++ b/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc @@ -256,55 +256,55 @@ bool BitTorrentTracker_Analyzer::ParseRequest(char* line) switch ( req_state ) { case detail::BTT_REQ_GET: + { + regmatch_t match[1]; + if ( regexec(&r_get, line, 1, match, 0) ) { - regmatch_t match[1]; - if ( regexec(&r_get, line, 1, match, 0) ) + ProtocolViolation("BitTorrentTracker: invalid HTTP GET"); + stop_orig = true; + return false; + } + + regmatch_t match_end[1]; + if ( ! regexec(&r_get_end, line, 1, match_end, 0) ) + { + if ( match_end[0].rm_so <= match[0].rm_eo ) { ProtocolViolation("BitTorrentTracker: invalid HTTP GET"); stop_orig = true; return false; } - regmatch_t match_end[1]; - if ( ! regexec(&r_get_end, line, 1, match_end, 0) ) - { - if ( match_end[0].rm_so <= match[0].rm_eo ) - { - ProtocolViolation("BitTorrentTracker: invalid HTTP GET"); - stop_orig = true; - return false; - } - - keep_alive = (line[match_end[0].rm_eo - 1] == '1'); - line[match_end[0].rm_so] = 0; - } - - RequestGet(&line[match[0].rm_eo]); - - req_state = detail::BTT_REQ_HEADER; + keep_alive = (line[match_end[0].rm_eo - 1] == '1'); + line[match_end[0].rm_so] = 0; } + + RequestGet(&line[match[0].rm_eo]); + + req_state = detail::BTT_REQ_HEADER; + } break; case detail::BTT_REQ_HEADER: + { + if ( ! *line ) { - if ( ! *line ) - { - EmitRequest(); - req_state = detail::BTT_REQ_DONE; - break; - } - - regmatch_t match[1]; - if ( regexec(&r_hdr, line, 1, match, 0) ) - { - ProtocolViolation("BitTorrentTracker: invalid HTTP request header"); - stop_orig = true; - return false; - } - - *strchr(line, ':') = 0; // this cannot fail - see regex_hdr - RequestHeader(line, &line[match[0].rm_eo]); + EmitRequest(); + req_state = detail::BTT_REQ_DONE; + break; } + + regmatch_t match[1]; + if ( regexec(&r_hdr, line, 1, match, 0) ) + { + ProtocolViolation("BitTorrentTracker: invalid HTTP request header"); + stop_orig = true; + return false; + } + + *strchr(line, ':') = 0; // this cannot fail - see regex_hdr + RequestHeader(line, &line[match[0].rm_eo]); + } break; case detail::BTT_REQ_DONE: @@ -356,27 +356,27 @@ bool BitTorrentTracker_Analyzer::ParseResponse(char* line) switch ( res_state ) { case detail::BTT_RES_STATUS: + { + if ( res_allow_blank_line && ! *line ) { - if ( res_allow_blank_line && ! *line ) - { - // There may be an empty line after the bencoded - // directory, if this is a keep-alive connection. - // Ignore it. - res_allow_blank_line = false; - break; - } - - regmatch_t match[1]; - if ( regexec(&r_stat, line, 1, match, 0) ) - { - ProtocolViolation("BitTorrentTracker: invalid HTTP status"); - stop_resp = true; - return false; - } - - ResponseStatus(&line[match[0].rm_eo]); - res_state = detail::BTT_RES_HEADER; + // There may be an empty line after the bencoded + // directory, if this is a keep-alive connection. + // Ignore it. + res_allow_blank_line = false; + break; } + + regmatch_t match[1]; + if ( regexec(&r_stat, line, 1, match, 0) ) + { + ProtocolViolation("BitTorrentTracker: invalid HTTP status"); + stop_resp = true; + return false; + } + + ResponseStatus(&line[match[0].rm_eo]); + res_state = detail::BTT_RES_HEADER; + } break; case detail::BTT_RES_HEADER: @@ -523,127 +523,122 @@ int BitTorrentTracker_Analyzer::ResponseParseBenc(void) switch ( benc_state ) { case detail::BENC_STATE_EMPTY: + { + switch ( res_buf_pos[0] ) { - switch ( res_buf_pos[0] ) - { - case 'd': - switch ( benc_stack.size() ) - { - case 0: - break; - case 1: - benc_raw = res_buf_pos; - benc_raw_type = detail::BENC_TYPE_DIR; - /* fall through */ - default: - VIOLATION_IF(benc_stack.back() == 'd' && - ! (benc_count.back() % 2), - "BitTorrentTracker: directory key is not a string " - "but a directory") - ++benc_raw_len; - } - - benc_stack.push_back('d'); - benc_count.push_back(0); - break; - - case 'l': - switch ( benc_stack.size() ) - { - case 0: - VIOLATION_IF(1, "BitTorrentTracker: not a bencoded directory " - "(first char: l)") - /* fall through */ - - case 1: - benc_raw = res_buf_pos; - benc_raw_type = detail::BENC_TYPE_LIST; - /* fall through */ - - default: - VIOLATION_IF(benc_stack.back() == 'd' && - ! (benc_count.back() % 2), - "BitTorrentTracker: directory key is not a string " - "but a list") - ++benc_raw_len; - } - - benc_stack.push_back('l'); - benc_count.push_back(0); - break; - - case 'i': - VIOLATION_IF( - ! benc_stack.size(), - "BitTorrentTracker: not a bencoded directory (first char: i)") - VIOLATION_IF( - benc_stack.back() == 'd' && ! (benc_count.back() % 2), - "BitTorrentTracker: directory key is not a string but an int") - - if ( benc_raw_type != detail::BENC_TYPE_NONE ) + case 'd': + switch ( benc_stack.size() ) + { + case 0: + break; + case 1: + benc_raw = res_buf_pos; + benc_raw_type = detail::BENC_TYPE_DIR; + /* fall through */ + default: + VIOLATION_IF(benc_stack.back() == 'd' && ! (benc_count.back() % 2), + "BitTorrentTracker: directory key is not a string " + "but a directory") ++benc_raw_len; + } - benc_state = detail::BENC_STATE_INT1; - break; + benc_stack.push_back('d'); + benc_count.push_back(0); + break; - case 'e': - VIOLATION_IF( - ! benc_stack.size(), - "BitTorrentTracker: not a bencoded directory (first char: e)") - VIOLATION_IF(benc_stack.back() == 'd' && benc_count.back() % 2, - "BitTorrentTracker: directory has an odd count of members") + case 'l': + switch ( benc_stack.size() ) + { + case 0: + VIOLATION_IF(1, "BitTorrentTracker: not a bencoded directory " + "(first char: l)") + /* fall through */ - if ( benc_raw_type != detail::BENC_TYPE_NONE ) + case 1: + benc_raw = res_buf_pos; + benc_raw_type = detail::BENC_TYPE_LIST; + /* fall through */ + + default: + VIOLATION_IF(benc_stack.back() == 'd' && ! (benc_count.back() % 2), + "BitTorrentTracker: directory key is not a string " + "but a list") ++benc_raw_len; + } - if ( benc_stack.size() == 2 ) - { // coming back to level 1 - ResponseBenc(benc_key_len, benc_key, benc_raw_type, benc_raw_len, - benc_raw); - benc_key = nullptr; - benc_key_len = 0; - benc_raw = nullptr; - benc_raw_len = 0; - benc_raw_type = detail::BENC_TYPE_NONE; - } + benc_stack.push_back('l'); + benc_count.push_back(0); + break; - benc_stack.pop_back(); - benc_count.pop_back(); + case 'i': + VIOLATION_IF(! benc_stack.size(), + "BitTorrentTracker: not a bencoded directory (first char: i)") + VIOLATION_IF(benc_stack.back() == 'd' && ! (benc_count.back() % 2), + "BitTorrentTracker: directory key is not a string but an int") - if ( benc_stack.size() ) - INC_COUNT - else - { // benc parsing successful - ++res_buf_pos; - return 0; - } - break; + if ( benc_raw_type != detail::BENC_TYPE_NONE ) + ++benc_raw_len; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - VIOLATION_IF( - ! benc_stack.size(), - "BitTorrentTracker: not a bencoded directory (first char: [0-9])") + benc_state = detail::BENC_STATE_INT1; + break; - if ( benc_raw_type != detail::BENC_TYPE_NONE ) - ++benc_raw_len; + case 'e': + VIOLATION_IF(! benc_stack.size(), + "BitTorrentTracker: not a bencoded directory (first char: e)") + VIOLATION_IF(benc_stack.back() == 'd' && benc_count.back() % 2, + "BitTorrentTracker: directory has an odd count of members") - benc_strlen = res_buf_pos; - benc_state = detail::BENC_STATE_STR1; - break; + if ( benc_raw_type != detail::BENC_TYPE_NONE ) + ++benc_raw_len; - default: - VIOLATION_IF(1, "BitTorrentTracker: no valid bencoding") - } + if ( benc_stack.size() == 2 ) + { // coming back to level 1 + ResponseBenc(benc_key_len, benc_key, benc_raw_type, benc_raw_len, + benc_raw); + benc_key = nullptr; + benc_key_len = 0; + benc_raw = nullptr; + benc_raw_len = 0; + benc_raw_type = detail::BENC_TYPE_NONE; + } + + benc_stack.pop_back(); + benc_count.pop_back(); + + if ( benc_stack.size() ) + INC_COUNT + else + { // benc parsing successful + ++res_buf_pos; + return 0; + } + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + VIOLATION_IF( + ! benc_stack.size(), + "BitTorrentTracker: not a bencoded directory (first char: [0-9])") + + if ( benc_raw_type != detail::BENC_TYPE_NONE ) + ++benc_raw_len; + + benc_strlen = res_buf_pos; + benc_state = detail::BENC_STATE_STR1; + break; + + default: + VIOLATION_IF(1, "BitTorrentTracker: no valid bencoding") } + } break; case detail::BENC_STATE_INT1: diff --git a/src/analyzer/protocol/dns/DNS.cc b/src/analyzer/protocol/dns/DNS.cc index 952e470b07..e34d0aa495 100644 --- a/src/analyzer/protocol/dns/DNS.cc +++ b/src/analyzer/protocol/dns/DNS.cc @@ -698,190 +698,188 @@ bool DNS_Interpreter::ParseRR_EDNS(detail::DNS_MsgInfo* msg, const u_char*& data switch ( option_code ) { case detail::TYPE_ECS: + { + // must be 4 bytes + variable number of octets for address + if ( option_len <= 4 ) { - // must be 4 bytes + variable number of octets for address - if ( option_len <= 4 ) - { - analyzer->Weird("EDNS_ECS_invalid_option_len"); - data += option_len; - break; - } - - detail::EDNS_ECS opt{}; - uint16_t ecs_family = ExtractShort(data, option_len); - uint16_t source_scope = ExtractShort(data, option_len); - opt.ecs_src_pfx_len = (source_scope >> 8) & 0xff; - opt.ecs_scp_pfx_len = source_scope & 0xff; - - // ADDRESS, variable number of octets, contains either an IPv4 or - // IPv6 address, depending on FAMILY, which MUST be truncated to the - // number of bits indicated by the SOURCE PREFIX-LENGTH field, - // padding with 0 bits to pad to the end of the last octet needed. - if ( ecs_family == L3_IPV4 ) - { - if ( opt.ecs_src_pfx_len > 32 ) - { - analyzer->Weird("EDNS_ECS_invalid_addr_v4_prefix", - util::fmt("%" PRIu16 " bits", opt.ecs_src_pfx_len)); - data += option_len; - break; - } - - if ( opt.ecs_src_pfx_len > option_len * 8 ) - { - analyzer->Weird("EDNS_ECS_invalid_addr_v4", - util::fmt("need %" PRIu16 " bits, have %d bits", - opt.ecs_src_pfx_len, option_len * 8)); - data += option_len; - break; - } - - opt.ecs_family = make_intrusive("v4"); - uint32_t addr = 0; - uint16_t shift_factor = 3; - int bits_left = opt.ecs_src_pfx_len; - - while ( bits_left > 0 ) - { - addr |= data[0] << (shift_factor * 8); - data++; - shift_factor--; - option_len--; - bits_left -= 8; - } - - addr = htonl(addr); - opt.ecs_addr = make_intrusive(addr); - } - else if ( ecs_family == L3_IPV6 ) - { - if ( opt.ecs_src_pfx_len > 128 ) - { - analyzer->Weird("EDNS_ECS_invalid_addr_v6_prefix", - util::fmt("%" PRIu16 " bits", opt.ecs_src_pfx_len)); - data += option_len; - break; - } - - if ( opt.ecs_src_pfx_len > option_len * 8 ) - { - analyzer->Weird("EDNS_ECS_invalid_addr_v6", - util::fmt("need %" PRIu16 " bits, have %d bits", - opt.ecs_src_pfx_len, option_len * 8)); - data += option_len; - break; - } - - opt.ecs_family = make_intrusive("v6"); - uint32_t addr[4] = {0}; - uint16_t shift_factor = 15; - int bits_left = opt.ecs_src_pfx_len; - int i = 0; - - while ( bits_left > 0 ) - { - addr[i / 4] |= data[0] << ((shift_factor % 4) * 8); - data++; - i++; - shift_factor--; - option_len--; - bits_left -= 8; - } - - for ( uint8_t i = 0; i < 4; i++ ) - { - addr[i] = htonl(addr[i]); - } - opt.ecs_addr = make_intrusive(addr); - } - else - { - // non ipv4/ipv6 family address - data += option_len; - break; - } - - analyzer->EnqueueConnEvent(dns_EDNS_ecs, analyzer->ConnVal(), - msg->BuildHdrVal(), msg->BuildEDNS_ECS_Val(&opt)); - data += option_len; - break; - } // END EDNS ECS - - case TYPE_TCP_KA: - { - EDNS_TCP_KEEPALIVE edns_tcp_keepalive{.keepalive_timeout_omitted = true, - .keepalive_timeout = 0}; - if ( option_len == 0 || option_len == 2 ) - { - // 0 bytes is permitted by RFC 7828, showing that the timeout value is - // omitted. - if ( option_len == 2 ) - { - edns_tcp_keepalive.keepalive_timeout = ExtractShort(data, option_len); - edns_tcp_keepalive.keepalive_timeout_omitted = false; - } - - if ( analyzer->Conn()->ConnTransport() == TRANSPORT_UDP ) - { - /* - * Based on RFC 7828 (3.2.1/3.2.2), clients and servers MUST NOT - * negotiate TCP Keepalive timeout in DNS-over-UDP. - */ - analyzer->Weird("EDNS_TCP_Keepalive_In_UDP"); - } - - analyzer->EnqueueConnEvent(dns_EDNS_tcp_keepalive, analyzer->ConnVal(), - msg->BuildHdrVal(), - msg->BuildEDNS_TCP_KA_Val(&edns_tcp_keepalive)); - } - else - { - // error. MUST BE 0 or 2 bytes. skip - data += option_len; - } - break; - } // END EDNS TCP KEEPALIVE - - case TYPE_COOKIE: - { - EDNS_COOKIE cookie{}; - if ( option_len != 8 && ! (option_len >= 16 && option_len <= 40) ) - { - /* - * option length for DNS Cookie must be 8 bytes (with client cookie only) - * OR - * between 16 bytes to 40 bytes (with an 8 bytes client and an 8 to 32 bytes - * server cookie) - */ - data += option_len; - break; - } - - int client_cookie_len = 8; - int server_cookie_len = option_len - client_cookie_len; - - cookie.client_cookie = - ExtractStream(data, client_cookie_len, client_cookie_len); - cookie.server_cookie = nullptr; - - if ( server_cookie_len >= 8 ) - { - cookie.server_cookie = - ExtractStream(data, server_cookie_len, server_cookie_len); - } - - analyzer->EnqueueConnEvent(dns_EDNS_cookie, analyzer->ConnVal(), - msg->BuildHdrVal(), - msg->BuildEDNS_COOKIE_Val(&cookie)); - - break; - } // END EDNS COOKIE - - default: - { + analyzer->Weird("EDNS_ECS_invalid_option_len"); data += option_len; break; } + + detail::EDNS_ECS opt{}; + uint16_t ecs_family = ExtractShort(data, option_len); + uint16_t source_scope = ExtractShort(data, option_len); + opt.ecs_src_pfx_len = (source_scope >> 8) & 0xff; + opt.ecs_scp_pfx_len = source_scope & 0xff; + + // ADDRESS, variable number of octets, contains either an IPv4 or + // IPv6 address, depending on FAMILY, which MUST be truncated to the + // number of bits indicated by the SOURCE PREFIX-LENGTH field, + // padding with 0 bits to pad to the end of the last octet needed. + if ( ecs_family == L3_IPV4 ) + { + if ( opt.ecs_src_pfx_len > 32 ) + { + analyzer->Weird("EDNS_ECS_invalid_addr_v4_prefix", + util::fmt("%" PRIu16 " bits", opt.ecs_src_pfx_len)); + data += option_len; + break; + } + + if ( opt.ecs_src_pfx_len > option_len * 8 ) + { + analyzer->Weird("EDNS_ECS_invalid_addr_v4", + util::fmt("need %" PRIu16 " bits, have %d bits", + opt.ecs_src_pfx_len, option_len * 8)); + data += option_len; + break; + } + + opt.ecs_family = make_intrusive("v4"); + uint32_t addr = 0; + uint16_t shift_factor = 3; + int bits_left = opt.ecs_src_pfx_len; + + while ( bits_left > 0 ) + { + addr |= data[0] << (shift_factor * 8); + data++; + shift_factor--; + option_len--; + bits_left -= 8; + } + + addr = htonl(addr); + opt.ecs_addr = make_intrusive(addr); + } + else if ( ecs_family == L3_IPV6 ) + { + if ( opt.ecs_src_pfx_len > 128 ) + { + analyzer->Weird("EDNS_ECS_invalid_addr_v6_prefix", + util::fmt("%" PRIu16 " bits", opt.ecs_src_pfx_len)); + data += option_len; + break; + } + + if ( opt.ecs_src_pfx_len > option_len * 8 ) + { + analyzer->Weird("EDNS_ECS_invalid_addr_v6", + util::fmt("need %" PRIu16 " bits, have %d bits", + opt.ecs_src_pfx_len, option_len * 8)); + data += option_len; + break; + } + + opt.ecs_family = make_intrusive("v6"); + uint32_t addr[4] = {0}; + uint16_t shift_factor = 15; + int bits_left = opt.ecs_src_pfx_len; + int i = 0; + + while ( bits_left > 0 ) + { + addr[i / 4] |= data[0] << ((shift_factor % 4) * 8); + data++; + i++; + shift_factor--; + option_len--; + bits_left -= 8; + } + + for ( uint8_t i = 0; i < 4; i++ ) + { + addr[i] = htonl(addr[i]); + } + opt.ecs_addr = make_intrusive(addr); + } + else + { + // non ipv4/ipv6 family address + data += option_len; + break; + } + + analyzer->EnqueueConnEvent(dns_EDNS_ecs, analyzer->ConnVal(), msg->BuildHdrVal(), + msg->BuildEDNS_ECS_Val(&opt)); + data += option_len; + break; + } // END EDNS ECS + + case TYPE_TCP_KA: + { + EDNS_TCP_KEEPALIVE edns_tcp_keepalive{.keepalive_timeout_omitted = true, + .keepalive_timeout = 0}; + if ( option_len == 0 || option_len == 2 ) + { + // 0 bytes is permitted by RFC 7828, showing that the timeout value is + // omitted. + if ( option_len == 2 ) + { + edns_tcp_keepalive.keepalive_timeout = ExtractShort(data, option_len); + edns_tcp_keepalive.keepalive_timeout_omitted = false; + } + + if ( analyzer->Conn()->ConnTransport() == TRANSPORT_UDP ) + { + /* + * Based on RFC 7828 (3.2.1/3.2.2), clients and servers MUST NOT + * negotiate TCP Keepalive timeout in DNS-over-UDP. + */ + analyzer->Weird("EDNS_TCP_Keepalive_In_UDP"); + } + + analyzer->EnqueueConnEvent(dns_EDNS_tcp_keepalive, analyzer->ConnVal(), + msg->BuildHdrVal(), + msg->BuildEDNS_TCP_KA_Val(&edns_tcp_keepalive)); + } + else + { + // error. MUST BE 0 or 2 bytes. skip + data += option_len; + } + break; + } // END EDNS TCP KEEPALIVE + + case TYPE_COOKIE: + { + EDNS_COOKIE cookie{}; + if ( option_len != 8 && ! (option_len >= 16 && option_len <= 40) ) + { + /* + * option length for DNS Cookie must be 8 bytes (with client cookie only) + * OR + * between 16 bytes to 40 bytes (with an 8 bytes client and an 8 to 32 bytes + * server cookie) + */ + data += option_len; + break; + } + + int client_cookie_len = 8; + int server_cookie_len = option_len - client_cookie_len; + + cookie.client_cookie = ExtractStream(data, client_cookie_len, client_cookie_len); + cookie.server_cookie = nullptr; + + if ( server_cookie_len >= 8 ) + { + cookie.server_cookie = + ExtractStream(data, server_cookie_len, server_cookie_len); + } + + analyzer->EnqueueConnEvent(dns_EDNS_cookie, analyzer->ConnVal(), msg->BuildHdrVal(), + msg->BuildEDNS_COOKIE_Val(&cookie)); + + break; + } // END EDNS COOKIE + + default: + { + data += option_len; + break; + } } } diff --git a/src/analyzer/protocol/http/HTTP.cc b/src/analyzer/protocol/http/HTTP.cc index 02ab9b05c6..ff52cb5dab 100644 --- a/src/analyzer/protocol/http/HTTP.cc +++ b/src/analyzer/protocol/http/HTTP.cc @@ -925,52 +925,51 @@ void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) switch ( request_state ) { case EXPECT_REQUEST_LINE: + { + int res = HTTP_RequestLine(line, end_of_line); + + if ( res < 0 ) + return; + + else if ( res > 0 ) { - int res = HTTP_RequestLine(line, end_of_line); + ++num_requests; - if ( res < 0 ) - return; + if ( ! keep_alive && num_requests > 1 ) + Weird("unexpected_multiple_HTTP_requests"); - else if ( res > 0 ) - { - ++num_requests; - - if ( ! keep_alive && num_requests > 1 ) - Weird("unexpected_multiple_HTTP_requests"); - - request_state = EXPECT_REQUEST_MESSAGE; - request_ongoing = 1; - unanswered_requests.push(request_method); - HTTP_Request(); - InitHTTPMessage(content_line, request_message, is_orig, HTTP_BODY_MAYBE, - len); - } + request_state = EXPECT_REQUEST_MESSAGE; + request_ongoing = 1; + unanswered_requests.push(request_method); + HTTP_Request(); + InitHTTPMessage(content_line, request_message, is_orig, HTTP_BODY_MAYBE, len); + } + else + { + if ( ! RequestExpected() ) + HTTP_Event("crud_trailing_HTTP_request", + analyzer::mime::to_string_val(line, end_of_line)); else { - if ( ! RequestExpected() ) - HTTP_Event("crud_trailing_HTTP_request", - analyzer::mime::to_string_val(line, end_of_line)); + // We do see HTTP requests with a + // trailing EOL that's not accounted + // for by the content-length. This + // will lead to a call to this method + // with len==0 while we are expecting + // a new request. Since HTTP servers + // handle such requests gracefully, + // we should do so as well. + if ( len == 0 ) + Weird("empty_http_request"); else { - // We do see HTTP requests with a - // trailing EOL that's not accounted - // for by the content-length. This - // will lead to a call to this method - // with len==0 while we are expecting - // a new request. Since HTTP servers - // handle such requests gracefully, - // we should do so as well. - if ( len == 0 ) - Weird("empty_http_request"); - else - { - ProtocolViolation("not a http request line"); - request_state = EXPECT_REQUEST_NOTHING; - } + ProtocolViolation("not a http request line"); + request_state = EXPECT_REQUEST_NOTHING; } } } + } break; case EXPECT_REQUEST_MESSAGE: diff --git a/src/analyzer/protocol/irc/IRC.cc b/src/analyzer/protocol/irc/IRC.cc index 1d3f0db1ee..fbade0eaf0 100644 --- a/src/analyzer/protocol/irc/IRC.cc +++ b/src/analyzer/protocol/irc/IRC.cc @@ -279,7 +279,7 @@ void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) make_intrusive(type.c_str()), make_intrusive(channel.c_str()), std::move(set)); } - break; + break; // Count of users and services on this server. case 255: @@ -456,38 +456,38 @@ void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig) // RPL_TOPIC reply. case 332: - { - if ( ! irc_channel_topic ) - break; - - vector parts = SplitWords(params, ' '); - if ( parts.size() < 4 ) - { - Weird("irc_invalid_topic_reply"); - return; - } - - unsigned int pos = params.find(':'); - if ( pos < params.size() ) - { - string topic = params.substr(pos + 1); - const char* t = topic.c_str(); - - if ( *t == ':' ) - ++t; - - EnqueueConnEvent(irc_channel_topic, ConnVal(), val_mgr->Bool(orig), - make_intrusive(parts[1].c_str()), - make_intrusive(t)); - } - else - { - Weird("irc_invalid_topic_reply"); - return; - } - } + { + if ( ! irc_channel_topic ) break; + vector parts = SplitWords(params, ' '); + if ( parts.size() < 4 ) + { + Weird("irc_invalid_topic_reply"); + return; + } + + unsigned int pos = params.find(':'); + if ( pos < params.size() ) + { + string topic = params.substr(pos + 1); + const char* t = topic.c_str(); + + if ( *t == ':' ) + ++t; + + EnqueueConnEvent(irc_channel_topic, ConnVal(), val_mgr->Bool(orig), + make_intrusive(parts[1].c_str()), + make_intrusive(t)); + } + else + { + Weird("irc_invalid_topic_reply"); + return; + } + } + break; + // WHO reply line. case 352: { diff --git a/src/analyzer/protocol/login/NVT.cc b/src/analyzer/protocol/login/NVT.cc index fc675e2b40..894aced4da 100644 --- a/src/analyzer/protocol/login/NVT.cc +++ b/src/analyzer/protocol/login/NVT.cc @@ -208,20 +208,19 @@ void TelnetAuthenticateOption::RecvSubOption(u_char* data, int len) switch ( data[0] ) { case HERE_IS_AUTHENTICATION: + { + TelnetAuthenticateOption* peer = (TelnetAuthenticateOption*)endp->FindPeerOption(code); + + if ( ! peer ) { - TelnetAuthenticateOption* peer = - (TelnetAuthenticateOption*)endp->FindPeerOption(code); - - if ( ! peer ) - { - reporter->AnalyzerError( - endp, "option peer missing in TelnetAuthenticateOption::RecvSubOption"); - return; - } - - if ( ! peer->DidRequestAuthentication() ) - InconsistentOption(0); + reporter->AnalyzerError( + endp, "option peer missing in TelnetAuthenticateOption::RecvSubOption"); + return; } + + if ( ! peer->DidRequestAuthentication() ) + InconsistentOption(0); + } break; case SEND_ME_AUTHENTICATION: @@ -247,11 +246,11 @@ void TelnetAuthenticateOption::RecvSubOption(u_char* data, int len) break; case AUTHENTICATION_NAME: - { - char* auth_name = new char[len]; - util::safe_strncpy(auth_name, (char*)data + 1, len); - endp->SetAuthName(auth_name); - } + { + char* auth_name = new char[len]; + util::safe_strncpy(auth_name, (char*)data + 1, len); + endp->SetAuthName(auth_name); + } break; default: diff --git a/src/analyzer/protocol/pop3/POP3.cc b/src/analyzer/protocol/pop3/POP3.cc index 9cffe3b2e1..4054c3ffb2 100644 --- a/src/analyzer/protocol/pop3/POP3.cc +++ b/src/analyzer/protocol/pop3/POP3.cc @@ -155,57 +155,57 @@ void POP3_Analyzer::ProcessRequest(int length, const char* line) break; case detail::AUTH_PLAIN: + { + // Format: "authorization identityauthentication + // identitypassword" + char* str = (char*)decoded->Bytes(); + int len = decoded->Len(); + char* end = str + len; + char* s; + char* e; + + for ( s = str; s < end && *s; ++s ) + ; + ++s; + + for ( e = s; e < end && *e; ++e ) + ; + + if ( e >= end ) { - // Format: "authorization identityauthentication - // identitypassword" - char* str = (char*)decoded->Bytes(); - int len = decoded->Len(); - char* end = str + len; - char* s; - char* e; - - for ( s = str; s < end && *s; ++s ) - ; - ++s; - - for ( e = s; e < end && *e; ++e ) - ; - - if ( e >= end ) - { - Weird("pop3_malformed_auth_plain"); - delete decoded; - return; - } - - user = s; - s = e + 1; - - if ( s >= end ) - { - Weird("pop3_malformed_auth_plain"); - delete decoded; - return; - } - - password.assign(s, len - (s - str)); - - break; + Weird("pop3_malformed_auth_plain"); + delete decoded; + return; } + user = s; + s = e + 1; + + if ( s >= end ) + { + Weird("pop3_malformed_auth_plain"); + delete decoded; + return; + } + + password.assign(s, len - (s - str)); + + break; + } + case detail::AUTH_CRAM_MD5: - { // Format: "userpassword-hash" - const char* s; - const char* str = (char*)decoded->CheckString(); + { // Format: "userpassword-hash" + const char* s; + const char* str = (char*)decoded->CheckString(); - for ( s = str; *s && *s != '\t' && *s != ' '; ++s ) - ; + for ( s = str; *s && *s != '\t' && *s != ' '; ++s ) + ; - user = std::string(str, s); - password = ""; + user = std::string(str, s); + password = ""; - break; - } + break; + } case detail::AUTH: break; @@ -694,16 +694,16 @@ void POP3_Analyzer::ProcessReply(int length, const char* line) case detail::TOP: case detail::RETR: - { - int data_len = end_of_line - line; - if ( ! mail ) - // ProcessReply is only called if orig == false - BeginData(false); - ProcessData(data_len, line); - if ( requestForMultiLine == true ) - multiLine = true; - break; - } + { + int data_len = end_of_line - line; + if ( ! mail ) + // ProcessReply is only called if orig == false + BeginData(false); + ProcessData(data_len, line); + if ( requestForMultiLine == true ) + multiLine = true; + break; + } case detail::CAPA: ProtocolConfirmation(); diff --git a/src/analyzer/protocol/rpc/Portmap.cc b/src/analyzer/protocol/rpc/Portmap.cc index eee978812d..94b9f4e603 100644 --- a/src/analyzer/protocol/rpc/Portmap.cc +++ b/src/analyzer/protocol/rpc/Portmap.cc @@ -32,42 +32,42 @@ bool PortmapperInterp::RPC_BuildCall(RPC_CallInfo* c, const u_char*& buf, int& n break; case PMAPPROC_SET: - { - auto m = ExtractMapping(buf, n); - if ( ! m ) - return false; - c->AddVal(std::move(m)); - } + { + auto m = ExtractMapping(buf, n); + if ( ! m ) + return false; + c->AddVal(std::move(m)); + } break; case PMAPPROC_UNSET: - { - auto m = ExtractMapping(buf, n); - if ( ! m ) - return false; - c->AddVal(std::move(m)); - } + { + auto m = ExtractMapping(buf, n); + if ( ! m ) + return false; + c->AddVal(std::move(m)); + } break; case PMAPPROC_GETPORT: - { - auto pr = ExtractPortRequest(buf, n); - if ( ! pr ) - return false; - c->AddVal(std::move(pr)); - } + { + auto pr = ExtractPortRequest(buf, n); + if ( ! pr ) + return false; + c->AddVal(std::move(pr)); + } break; case PMAPPROC_DUMP: break; case PMAPPROC_CALLIT: - { - auto call_it = ExtractCallItRequest(buf, n); - if ( ! call_it ) - return false; - c->AddVal(std::move(call_it)); - } + { + auto call_it = ExtractCallItRequest(buf, n); + if ( ! call_it ) + return false; + c->AddVal(std::move(call_it)); + } break; default: diff --git a/src/analyzer/protocol/rpc/RPC.cc b/src/analyzer/protocol/rpc/RPC.cc index f06d996313..f8bef3a887 100644 --- a/src/analyzer/protocol/rpc/RPC.cc +++ b/src/analyzer/protocol/rpc/RPC.cc @@ -636,75 +636,73 @@ void Contents_RPC::DeliverStream(int len, const u_char* data, bool orig) // no break. fall through case WAIT_FOR_MARKER: + { + bool got_marker = marker_buf.ConsumeChunk(data, len); + + if ( got_marker ) { - bool got_marker = marker_buf.ConsumeChunk(data, len); + const u_char* dummy_p = marker_buf.GetBuf(); + int dummy_len = (int)marker_buf.GetFill(); - if ( got_marker ) + // have full marker + marker = extract_XDR_uint32(dummy_p, dummy_len); + marker_buf.Init(4, 4); + + if ( ! dummy_p ) { - const u_char* dummy_p = marker_buf.GetBuf(); - int dummy_len = (int)marker_buf.GetFill(); - - // have full marker - marker = extract_XDR_uint32(dummy_p, dummy_len); - marker_buf.Init(4, 4); - - if ( ! dummy_p ) - { - reporter->AnalyzerError(this, - "inconsistent RPC record marker extraction"); - return; - } - - last_frag = (marker & 0x80000000) != 0; - marker &= 0x7fffffff; - // printf("%.6f %d marker= %u <> last_frag= %d <> expected=%llu <> - // processed= %llu <> len = %d\n", run_state::network_time, IsOrig(), - // marker, - // last_frag, msg_buf.GetExpected(), msg_buf.GetProcessed(), len); - - if ( ! msg_buf.AddToExpected(marker) ) - Conn()->Weird("RPC_message_too_long", - util::fmt("%" PRId64, msg_buf.GetExpected())); - - if ( last_frag ) - state = WAIT_FOR_LAST_DATA; - else - state = WAIT_FOR_DATA; + reporter->AnalyzerError(this, "inconsistent RPC record marker extraction"); + return; } + + last_frag = (marker & 0x80000000) != 0; + marker &= 0x7fffffff; + // printf("%.6f %d marker= %u <> last_frag= %d <> expected=%llu <> + // processed= %llu <> len = %d\n", run_state::network_time, IsOrig(), + // marker, + // last_frag, msg_buf.GetExpected(), msg_buf.GetProcessed(), len); + + if ( ! msg_buf.AddToExpected(marker) ) + Conn()->Weird("RPC_message_too_long", + util::fmt("%" PRId64, msg_buf.GetExpected())); + + if ( last_frag ) + state = WAIT_FOR_LAST_DATA; + else + state = WAIT_FOR_DATA; } + } // Else remain in state. Haven't got the full 4 bytes // for the marker yet. break; case WAIT_FOR_DATA: case WAIT_FOR_LAST_DATA: + { + bool got_all_data = msg_buf.ConsumeChunk(data, len); + + if ( got_all_data ) { - bool got_all_data = msg_buf.ConsumeChunk(data, len); - - if ( got_all_data ) + // Got all the data we expected. Now let's + // see whether there is another fragment + // coming or whether we just finished the + // last fragment. + if ( state == WAIT_FOR_LAST_DATA ) { - // Got all the data we expected. Now let's - // see whether there is another fragment - // coming or whether we just finished the - // last fragment. - if ( state == WAIT_FOR_LAST_DATA ) - { - const u_char* dummy_p = msg_buf.GetBuf(); - int dummy_len = (int)msg_buf.GetFill(); + const u_char* dummy_p = msg_buf.GetBuf(); + int dummy_len = (int)msg_buf.GetFill(); - if ( ! interp->DeliverRPC(dummy_p, dummy_len, - (int)msg_buf.GetExpected(), IsOrig(), - start_time, last_time) ) - Conn()->Weird("partial_RPC"); + if ( ! interp->DeliverRPC(dummy_p, dummy_len, (int)msg_buf.GetExpected(), + IsOrig(), start_time, last_time) ) + Conn()->Weird("partial_RPC"); - state = WAIT_FOR_MESSAGE; - } - else - state = WAIT_FOR_MARKER; + state = WAIT_FOR_MESSAGE; } - // Else remain in state. Haven't read all the data - // yet. + else + state = WAIT_FOR_MARKER; } + // Else remain in state. Haven't read all the data + // yet. + } break; } // end switch } // end while diff --git a/src/broker/Data.cc b/src/broker/Data.cc index bf13a6fd96..8045edb6b7 100644 --- a/src/broker/Data.cc +++ b/src/broker/Data.cc @@ -134,14 +134,14 @@ struct val_converter case TYPE_STRING: return make_intrusive(a.size(), a.data()); case TYPE_FILE: - { - auto file = File::Get(a.data()); + { + auto file = File::Get(a.data()); - if ( file ) - return make_intrusive(std::move(file)); + if ( file ) + return make_intrusive(std::move(file)); - return nullptr; - } + return nullptr; + } default: return nullptr; } @@ -842,231 +842,231 @@ broker::expected val_to_data(const Val* v) case TYPE_COUNT: return {v->AsCount()}; case TYPE_PORT: - { - auto p = v->AsPortVal(); - return {broker::port(p->Port(), to_broker_port_proto(p->PortType()))}; - } + { + auto p = v->AsPortVal(); + return {broker::port(p->Port(), to_broker_port_proto(p->PortType()))}; + } case TYPE_ADDR: - { - auto a = v->AsAddr(); - in6_addr tmp; - a.CopyIPv6(&tmp); - return {broker::address(reinterpret_cast(&tmp), - broker::address::family::ipv6, - broker::address::byte_order::network)}; - } + { + auto a = v->AsAddr(); + in6_addr tmp; + a.CopyIPv6(&tmp); + return {broker::address(reinterpret_cast(&tmp), + broker::address::family::ipv6, + broker::address::byte_order::network)}; + } break; case TYPE_SUBNET: - { - auto s = v->AsSubNet(); - in6_addr tmp; - s.Prefix().CopyIPv6(&tmp); - auto a = broker::address(reinterpret_cast(&tmp), - broker::address::family::ipv6, - broker::address::byte_order::network); - return {broker::subnet(std::move(a), s.Length())}; - } + { + auto s = v->AsSubNet(); + in6_addr tmp; + s.Prefix().CopyIPv6(&tmp); + auto a = broker::address(reinterpret_cast(&tmp), + broker::address::family::ipv6, + broker::address::byte_order::network); + return {broker::subnet(std::move(a), s.Length())}; + } break; case TYPE_DOUBLE: return {v->AsDouble()}; case TYPE_TIME: - { - auto secs = broker::fractional_seconds{v->AsTime()}; - auto since_epoch = std::chrono::duration_cast(secs); - return {broker::timestamp{since_epoch}}; - } + { + auto secs = broker::fractional_seconds{v->AsTime()}; + auto since_epoch = std::chrono::duration_cast(secs); + return {broker::timestamp{since_epoch}}; + } case TYPE_INTERVAL: - { - auto secs = broker::fractional_seconds{v->AsInterval()}; - return {std::chrono::duration_cast(secs)}; - } + { + auto secs = broker::fractional_seconds{v->AsInterval()}; + return {std::chrono::duration_cast(secs)}; + } case TYPE_ENUM: - { - auto enum_type = v->GetType()->AsEnumType(); - auto enum_name = enum_type->Lookup(v->AsEnum()); - return {broker::enum_value(enum_name ? enum_name : "")}; - } + { + auto enum_type = v->GetType()->AsEnumType(); + auto enum_name = enum_type->Lookup(v->AsEnum()); + return {broker::enum_value(enum_name ? enum_name : "")}; + } case TYPE_STRING: - { - auto s = v->AsString(); - return {string(reinterpret_cast(s->Bytes()), s->Len())}; - } + { + auto s = v->AsString(); + return {string(reinterpret_cast(s->Bytes()), s->Len())}; + } case TYPE_FILE: return {string(v->AsFile()->Name())}; case TYPE_FUNC: + { + const Func* f = v->AsFunc(); + std::string name(f->Name()); + + broker::vector rval; + rval.push_back(name); + + if ( name.find("lambda_<") == 0 ) { - const Func* f = v->AsFunc(); - std::string name(f->Name()); - - broker::vector rval; - rval.push_back(name); - - if ( name.find("lambda_<") == 0 ) + // Only ScriptFuncs have closures. + if ( auto b = dynamic_cast(f) ) { - // Only ScriptFuncs have closures. - if ( auto b = dynamic_cast(f) ) - { - auto bc = b->SerializeClosure(); - if ( ! bc ) - return broker::ec::invalid_data; - - rval.emplace_back(std::move(*bc)); - } - else - { - reporter->InternalWarning("Closure with non-ScriptFunc"); + auto bc = b->SerializeClosure(); + if ( ! bc ) return broker::ec::invalid_data; - } + + rval.emplace_back(std::move(*bc)); + } + else + { + reporter->InternalWarning("Closure with non-ScriptFunc"); + return broker::ec::invalid_data; + } + } + + return {std::move(rval)}; + } + case TYPE_TABLE: + { + auto is_set = v->GetType()->IsSet(); + auto table = v->AsTable(); + auto table_val = v->AsTableVal(); + broker::data rval; + + if ( is_set ) + rval = broker::set(); + else + rval = broker::table(); + + for ( const auto& te : *table ) + { + auto hk = te.GetHashKey(); + auto* entry = te.GetValue(); + + auto vl = table_val->RecreateIndex(*hk); + + broker::vector composite_key; + composite_key.reserve(vl->Length()); + + for ( auto k = 0; k < vl->Length(); ++k ) + { + auto key_part = val_to_data(vl->Idx(k).get()); + + if ( ! key_part ) + return broker::ec::invalid_data; + + composite_key.emplace_back(move(*key_part)); } - return {std::move(rval)}; - } - case TYPE_TABLE: - { - auto is_set = v->GetType()->IsSet(); - auto table = v->AsTable(); - auto table_val = v->AsTableVal(); - broker::data rval; + broker::data key; + + if ( composite_key.size() == 1 ) + key = move(composite_key[0]); + else + key = move(composite_key); if ( is_set ) - rval = broker::set(); + caf::get(rval).emplace(move(key)); else - rval = broker::table(); - - for ( const auto& te : *table ) { - auto hk = te.GetHashKey(); - auto* entry = te.GetValue(); + auto val = val_to_data(entry->GetVal().get()); - auto vl = table_val->RecreateIndex(*hk); + if ( ! val ) + return broker::ec::invalid_data; - broker::vector composite_key; - composite_key.reserve(vl->Length()); - - for ( auto k = 0; k < vl->Length(); ++k ) - { - auto key_part = val_to_data(vl->Idx(k).get()); - - if ( ! key_part ) - return broker::ec::invalid_data; - - composite_key.emplace_back(move(*key_part)); - } - - broker::data key; - - if ( composite_key.size() == 1 ) - key = move(composite_key[0]); - else - key = move(composite_key); - - if ( is_set ) - caf::get(rval).emplace(move(key)); - else - { - auto val = val_to_data(entry->GetVal().get()); - - if ( ! val ) - return broker::ec::invalid_data; - - caf::get(rval).emplace(move(key), move(*val)); - } + caf::get(rval).emplace(move(key), move(*val)); } - - return {std::move(rval)}; } + + return {std::move(rval)}; + } case TYPE_VECTOR: + { + auto vec = v->AsVectorVal(); + broker::vector rval; + rval.reserve(vec->Size()); + + for ( auto i = 0u; i < vec->Size(); ++i ) { - auto vec = v->AsVectorVal(); - broker::vector rval; - rval.reserve(vec->Size()); + auto item_val = vec->ValAt(i); - for ( auto i = 0u; i < vec->Size(); ++i ) - { - auto item_val = vec->ValAt(i); + if ( ! item_val ) + continue; - if ( ! item_val ) - continue; + auto item = val_to_data(item_val.get()); - auto item = val_to_data(item_val.get()); + if ( ! item ) + return broker::ec::invalid_data; - if ( ! item ) - return broker::ec::invalid_data; - - rval.emplace_back(move(*item)); - } - - return {std::move(rval)}; + rval.emplace_back(move(*item)); } + + return {std::move(rval)}; + } case TYPE_LIST: + { + // We don't really support lists on the broker side. + // So we just pretend that it is a vector instead. + auto list = v->AsListVal(); + broker::vector rval; + rval.reserve(list->Length()); + + for ( auto i = 0; i < list->Length(); ++i ) { - // We don't really support lists on the broker side. - // So we just pretend that it is a vector instead. - auto list = v->AsListVal(); - broker::vector rval; - rval.reserve(list->Length()); + const auto& item_val = list->Idx(i); - for ( auto i = 0; i < list->Length(); ++i ) - { - const auto& item_val = list->Idx(i); + if ( ! item_val ) + continue; - if ( ! item_val ) - continue; + auto item = val_to_data(item_val.get()); - auto item = val_to_data(item_val.get()); + if ( ! item ) + return broker::ec::invalid_data; - if ( ! item ) - return broker::ec::invalid_data; - - rval.emplace_back(move(*item)); - } - - return {std::move(rval)}; + rval.emplace_back(move(*item)); } + + return {std::move(rval)}; + } case TYPE_RECORD: + { + auto rec = v->AsRecordVal(); + broker::vector rval; + size_t num_fields = v->GetType()->AsRecordType()->NumFields(); + rval.reserve(num_fields); + + for ( size_t i = 0; i < num_fields; ++i ) { - auto rec = v->AsRecordVal(); - broker::vector rval; - size_t num_fields = v->GetType()->AsRecordType()->NumFields(); - rval.reserve(num_fields); + auto item_val = rec->GetFieldOrDefault(i); - for ( size_t i = 0; i < num_fields; ++i ) + if ( ! item_val ) { - auto item_val = rec->GetFieldOrDefault(i); - - if ( ! item_val ) - { - rval.emplace_back(broker::nil); - continue; - } - - auto item = val_to_data(item_val.get()); - - if ( ! item ) - return broker::ec::invalid_data; - - rval.emplace_back(move(*item)); + rval.emplace_back(broker::nil); + continue; } - return {std::move(rval)}; + auto item = val_to_data(item_val.get()); + + if ( ! item ) + return broker::ec::invalid_data; + + rval.emplace_back(move(*item)); } + + return {std::move(rval)}; + } case TYPE_PATTERN: - { - const RE_Matcher* p = v->AsPattern(); - broker::vector rval = {p->PatternText(), p->AnywherePatternText()}; - return {std::move(rval)}; - } + { + const RE_Matcher* p = v->AsPattern(); + broker::vector rval = {p->PatternText(), p->AnywherePatternText()}; + return {std::move(rval)}; + } case TYPE_OPAQUE: + { + auto c = v->AsOpaqueVal()->Serialize(); + if ( ! c ) { - auto c = v->AsOpaqueVal()->Serialize(); - if ( ! c ) - { - reporter->Error("unsupported opaque type for serialization"); - break; - } - - return {c}; + reporter->Error("unsupported opaque type for serialization"); + break; } + + return {c}; + } default: reporter->Error("unsupported Broker::Data type: %s", type_name(v->GetType()->Tag())); break; diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index bf11f840ff..65a70c4316 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -1024,22 +1024,22 @@ void Manager::DispatchMessage(const broker::topic& topic, broker::data msg) break; case broker::zeek::Message::Type::Batch: + { + broker::zeek::Batch batch(std::move(msg)); + + if ( ! batch.valid() ) { - broker::zeek::Batch batch(std::move(msg)); - - if ( ! batch.valid() ) - { - reporter->Warning("received invalid broker Batch: %s", - broker::to_string(batch).data()); - return; - } - - for ( auto& i : batch.batch() ) - DispatchMessage(topic, std::move(i)); - - break; + reporter->Warning("received invalid broker Batch: %s", + broker::to_string(batch).data()); + return; } + for ( auto& i : batch.batch() ) + DispatchMessage(topic, std::move(i)); + + break; + } + default: // We ignore unknown types so that we could add more in the // future if we had too. diff --git a/src/broker/Store.cc b/src/broker/Store.cc index 5a36fc9f47..d548657a17 100644 --- a/src/broker/Store.cc +++ b/src/broker/Store.cc @@ -69,11 +69,10 @@ broker::backend_options to_backend_options(broker::backend backend, RecordVal* o switch ( backend ) { case broker::backend::sqlite: - { - auto path = - options->GetFieldAs(0)->GetFieldAs(0)->CheckString(); - return {{"path", path}}; - } + { + auto path = options->GetFieldAs(0)->GetFieldAs(0)->CheckString(); + return {{"path", path}}; + } default: break; diff --git a/src/file_analysis/analyzer/x509/X509.cc b/src/file_analysis/analyzer/x509/X509.cc index 659c2f9f63..20e43514eb 100644 --- a/src/file_analysis/analyzer/x509/X509.cc +++ b/src/file_analysis/analyzer/x509/X509.cc @@ -493,32 +493,32 @@ unsigned int X509::KeyLength(EVP_PKEY* key) #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: + { + BIGNUM* ec_order = BN_new(); + if ( ! ec_order ) + // could not malloc bignum? + return 0; + + const EC_GROUP* group = EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(key)); + + if ( ! group ) { - BIGNUM* ec_order = BN_new(); - if ( ! ec_order ) - // could not malloc bignum? - return 0; - - const EC_GROUP* group = EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(key)); - - if ( ! group ) - { - // unknown ex-group - BN_free(ec_order); - return 0; - } - - if ( ! EC_GROUP_get_order(group, ec_order, NULL) ) - { - // could not get ec-group-order - BN_free(ec_order); - return 0; - } - - unsigned int length = BN_num_bits(ec_order); + // unknown ex-group BN_free(ec_order); - return length; + return 0; } + + if ( ! EC_GROUP_get_order(group, ec_order, NULL) ) + { + // could not get ec-group-order + BN_free(ec_order); + return 0; + } + + unsigned int length = BN_num_bits(ec_order); + BN_free(ec_order); + return length; + } #endif default: return 0; // unknown public key type diff --git a/src/input/Manager.cc b/src/input/Manager.cc index 63c4ff64a1..2869bfb9d2 100644 --- a/src/input/Manager.cc +++ b/src/input/Manager.cc @@ -841,28 +841,28 @@ bool Manager::IsCompatibleType(Type* t, bool atomic_only) return ! atomic_only; case TYPE_TABLE: - { - if ( atomic_only ) - return false; + { + if ( atomic_only ) + return false; - if ( ! t->IsSet() ) - return false; + if ( ! t->IsSet() ) + return false; - const auto& indices = t->AsSetType()->GetIndices(); + const auto& indices = t->AsSetType()->GetIndices(); - if ( indices->GetTypes().size() != 1 ) - return false; + if ( indices->GetTypes().size() != 1 ) + return false; - return IsCompatibleType(indices->GetPureType().get(), true); - } + return IsCompatibleType(indices->GetPureType().get(), true); + } case TYPE_VECTOR: - { - if ( atomic_only ) - return false; + { + if ( atomic_only ) + return false; - return IsCompatibleType(t->AsVectorType()->Yield().get(), true); - } + return IsCompatibleType(t->AsVectorType()->Yield().get(), true); + } default: return false; @@ -1999,65 +1999,65 @@ int Manager::GetValueLength(const Value* val) const case TYPE_STRING: case TYPE_ENUM: - { - length += val->val.string_val.length + 1; - break; - } + { + length += val->val.string_val.length + 1; + break; + } case TYPE_ADDR: + { + switch ( val->val.addr_val.family ) { - switch ( val->val.addr_val.family ) - { - case IPv4: - length += sizeof(val->val.addr_val.in.in4); - break; - case IPv6: - length += sizeof(val->val.addr_val.in.in6); - break; - default: - assert(false); - } + case IPv4: + length += sizeof(val->val.addr_val.in.in4); + break; + case IPv6: + length += sizeof(val->val.addr_val.in.in6); + break; + default: + assert(false); } + } break; case TYPE_SUBNET: + { + switch ( val->val.subnet_val.prefix.family ) { - switch ( val->val.subnet_val.prefix.family ) - { - case IPv4: - length += sizeof(val->val.subnet_val.prefix.in.in4) + - sizeof(val->val.subnet_val.length); - break; - case IPv6: - length += sizeof(val->val.subnet_val.prefix.in.in6) + - sizeof(val->val.subnet_val.length); - break; - default: - assert(false); - } + case IPv4: + length += sizeof(val->val.subnet_val.prefix.in.in4) + + sizeof(val->val.subnet_val.length); + break; + case IPv6: + length += sizeof(val->val.subnet_val.prefix.in.in6) + + sizeof(val->val.subnet_val.length); + break; + default: + assert(false); } + } break; case TYPE_PATTERN: - { - length += strlen(val->val.pattern_text_val) + 1; - break; - } + { + length += strlen(val->val.pattern_text_val) + 1; + break; + } case TYPE_TABLE: - { - for ( int i = 0; i < val->val.set_val.size; i++ ) - length += GetValueLength(val->val.set_val.vals[i]); - break; - } + { + for ( int i = 0; i < val->val.set_val.size; i++ ) + length += GetValueLength(val->val.set_val.vals[i]); + break; + } case TYPE_VECTOR: - { - int j = val->val.vector_val.size; - for ( int i = 0; i < j; i++ ) - length += GetValueLength(val->val.vector_val.vals[i]); - break; - } + { + int j = val->val.vector_val.size; + for ( int i = 0; i < j; i++ ) + length += GetValueLength(val->val.vector_val.vals[i]); + break; + } default: reporter->InternalError("unsupported type %d for GetValueLength", val->type); @@ -2084,16 +2084,16 @@ int Manager::CopyValue(char* data, const int startpos, const Value* val) const return sizeof(val->val.uint_val); case TYPE_PORT: - { - int length = 0; - memcpy(data + startpos, (const void*)&(val->val.port_val.port), - sizeof(val->val.port_val.port)); - length += sizeof(val->val.port_val.port); - memcpy(data + startpos + length, (const void*)&(val->val.port_val.proto), - sizeof(val->val.port_val.proto)); - length += sizeof(val->val.port_val.proto); - return length; - } + { + int length = 0; + memcpy(data + startpos, (const void*)&(val->val.port_val.port), + sizeof(val->val.port_val.port)); + length += sizeof(val->val.port_val.port); + memcpy(data + startpos + length, (const void*)&(val->val.port_val.proto), + sizeof(val->val.port_val.proto)); + length += sizeof(val->val.port_val.proto); + return length; + } case TYPE_DOUBLE: case TYPE_TIME: @@ -2104,92 +2104,92 @@ int Manager::CopyValue(char* data, const int startpos, const Value* val) const case TYPE_STRING: case TYPE_ENUM: - { - memcpy(data + startpos, val->val.string_val.data, val->val.string_val.length); - // Add a \0 to the end. To be able to hash zero-length - // strings and differentiate from !present. - memset(data + startpos + val->val.string_val.length, 0, 1); - return val->val.string_val.length + 1; - } + { + memcpy(data + startpos, val->val.string_val.data, val->val.string_val.length); + // Add a \0 to the end. To be able to hash zero-length + // strings and differentiate from !present. + memset(data + startpos + val->val.string_val.length, 0, 1); + return val->val.string_val.length + 1; + } case TYPE_ADDR: + { + int length = 0; + switch ( val->val.addr_val.family ) { - int length = 0; - switch ( val->val.addr_val.family ) - { - case IPv4: - length = sizeof(val->val.addr_val.in.in4); - memcpy(data + startpos, (const char*)&(val->val.addr_val.in.in4), length); - break; + case IPv4: + length = sizeof(val->val.addr_val.in.in4); + memcpy(data + startpos, (const char*)&(val->val.addr_val.in.in4), length); + break; - case IPv6: - length = sizeof(val->val.addr_val.in.in6); - memcpy(data + startpos, (const char*)&(val->val.addr_val.in.in6), length); - break; + case IPv6: + length = sizeof(val->val.addr_val.in.in6); + memcpy(data + startpos, (const char*)&(val->val.addr_val.in.in6), length); + break; - default: - assert(false); - } - - return length; + default: + assert(false); } + return length; + } + case TYPE_SUBNET: + { + int length = 0; + switch ( val->val.subnet_val.prefix.family ) { - int length = 0; - switch ( val->val.subnet_val.prefix.family ) - { - case IPv4: - length = sizeof(val->val.addr_val.in.in4); - memcpy(data + startpos, (const char*)&(val->val.subnet_val.prefix.in.in4), - length); - break; + case IPv4: + length = sizeof(val->val.addr_val.in.in4); + memcpy(data + startpos, (const char*)&(val->val.subnet_val.prefix.in.in4), + length); + break; - case IPv6: - length = sizeof(val->val.addr_val.in.in6); - memcpy(data + startpos, (const char*)&(val->val.subnet_val.prefix.in.in6), - length); - break; + case IPv6: + length = sizeof(val->val.addr_val.in.in6); + memcpy(data + startpos, (const char*)&(val->val.subnet_val.prefix.in.in6), + length); + break; - default: - assert(false); - } - - int lengthlength = sizeof(val->val.subnet_val.length); - memcpy(data + startpos + length, (const char*)&(val->val.subnet_val.length), - lengthlength); - length += lengthlength; - - return length; + default: + assert(false); } + int lengthlength = sizeof(val->val.subnet_val.length); + memcpy(data + startpos + length, (const char*)&(val->val.subnet_val.length), + lengthlength); + length += lengthlength; + + return length; + } + case TYPE_PATTERN: - { - // include null-terminator - int length = strlen(val->val.pattern_text_val) + 1; - memcpy(data + startpos, val->val.pattern_text_val, length); - return length; - } + { + // include null-terminator + int length = strlen(val->val.pattern_text_val) + 1; + memcpy(data + startpos, val->val.pattern_text_val, length); + return length; + } case TYPE_TABLE: - { - int length = 0; - int j = val->val.set_val.size; - for ( int i = 0; i < j; i++ ) - length += CopyValue(data, startpos + length, val->val.set_val.vals[i]); + { + int length = 0; + int j = val->val.set_val.size; + for ( int i = 0; i < j; i++ ) + length += CopyValue(data, startpos + length, val->val.set_val.vals[i]); - return length; - } + return length; + } case TYPE_VECTOR: - { - int length = 0; - int j = val->val.vector_val.size; - for ( int i = 0; i < j; i++ ) - length += CopyValue(data, startpos + length, val->val.vector_val.vals[i]); + { + int length = 0; + int j = val->val.vector_val.size; + for ( int i = 0; i < j; i++ ) + length += CopyValue(data, startpos + length, val->val.vector_val.vals[i]); - return length; - } + return length; + } default: reporter->InternalError("unsupported type %d for CopyValue", val->type); @@ -2284,134 +2284,133 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, Type* request_type, return new IntervalVal(val->val.double_val); case TYPE_STRING: - { - String* s = new String((const u_char*)val->val.string_val.data, - val->val.string_val.length, true); - return new StringVal(s); - } + { + String* s = new String((const u_char*)val->val.string_val.data, + val->val.string_val.length, true); + return new StringVal(s); + } case TYPE_PORT: return val_mgr->Port(val->val.port_val.port, val->val.port_val.proto)->Ref(); case TYPE_ADDR: + { + IPAddr* addr = nullptr; + switch ( val->val.addr_val.family ) { - IPAddr* addr = nullptr; - switch ( val->val.addr_val.family ) - { - case IPv4: - addr = new IPAddr(val->val.addr_val.in.in4); - break; + case IPv4: + addr = new IPAddr(val->val.addr_val.in.in4); + break; - case IPv6: - addr = new IPAddr(val->val.addr_val.in.in6); - break; + case IPv6: + addr = new IPAddr(val->val.addr_val.in.in6); + break; - default: - assert(false); - } - - auto* addrval = new AddrVal(*addr); - delete addr; - return addrval; + default: + assert(false); } + auto* addrval = new AddrVal(*addr); + delete addr; + return addrval; + } + case TYPE_SUBNET: + { + IPAddr* addr = nullptr; + switch ( val->val.subnet_val.prefix.family ) { - IPAddr* addr = nullptr; - switch ( val->val.subnet_val.prefix.family ) - { - case IPv4: - addr = new IPAddr(val->val.subnet_val.prefix.in.in4); - break; + case IPv4: + addr = new IPAddr(val->val.subnet_val.prefix.in.in4); + break; - case IPv6: - addr = new IPAddr(val->val.subnet_val.prefix.in.in6); - break; + case IPv6: + addr = new IPAddr(val->val.subnet_val.prefix.in.in6); + break; - default: - assert(false); - } - - auto* subnetval = new SubNetVal(*addr, val->val.subnet_val.length); - delete addr; - return subnetval; + default: + assert(false); } + auto* subnetval = new SubNetVal(*addr, val->val.subnet_val.length); + delete addr; + return subnetval; + } + case TYPE_PATTERN: - { - auto* re = new RE_Matcher(val->val.pattern_text_val); - re->Compile(); - return new PatternVal(re); - } + { + auto* re = new RE_Matcher(val->val.pattern_text_val); + re->Compile(); + return new PatternVal(re); + } case TYPE_TABLE: + { + // all entries have to have the same type... + const auto& type = request_type->AsTableType()->GetIndices()->GetPureType(); + auto set_index = make_intrusive(type); + set_index->Append(type); + auto s = make_intrusive(std::move(set_index), nullptr); + auto t = make_intrusive(std::move(s)); + for ( int j = 0; j < val->val.set_val.size; j++ ) { - // all entries have to have the same type... - const auto& type = request_type->AsTableType()->GetIndices()->GetPureType(); - auto set_index = make_intrusive(type); - set_index->Append(type); - auto s = make_intrusive(std::move(set_index), nullptr); - auto t = make_intrusive(std::move(s)); - for ( int j = 0; j < val->val.set_val.size; j++ ) - { - Val* assignval = - ValueToVal(i, val->val.set_val.vals[j], type.get(), have_error); + Val* assignval = ValueToVal(i, val->val.set_val.vals[j], type.get(), have_error); - if ( have_error ) - return nullptr; + if ( have_error ) + return nullptr; - t->Assign({AdoptRef{}, assignval}, nullptr); - } - - return t.release(); + t->Assign({AdoptRef{}, assignval}, nullptr); } + return t.release(); + } + case TYPE_VECTOR: + { + // all entries have to have the same type... + const auto& type = request_type->AsVectorType()->Yield(); + auto vt = make_intrusive(type); + auto v = make_intrusive(std::move(vt)); + + for ( int j = 0; j < val->val.vector_val.size; j++ ) { - // all entries have to have the same type... - const auto& type = request_type->AsVectorType()->Yield(); - auto vt = make_intrusive(type); - auto v = make_intrusive(std::move(vt)); + auto el = ValueToVal(i, val->val.vector_val.vals[j], type.get(), have_error); - for ( int j = 0; j < val->val.vector_val.size; j++ ) - { - auto el = ValueToVal(i, val->val.vector_val.vals[j], type.get(), have_error); + if ( have_error ) + return nullptr; - if ( have_error ) - return nullptr; - - v->Assign(j, {AdoptRef{}, el}); - } - - return v.release(); + v->Assign(j, {AdoptRef{}, el}); } + return v.release(); + } + case TYPE_ENUM: + { + // Convert to string first to not have to deal with missing + // \0's... + string enum_string(val->val.string_val.data, val->val.string_val.length); + + string module = zeek::detail::extract_module_name(enum_string.c_str()); + string var = zeek::detail::extract_var_name(enum_string.c_str()); + + // Well, this is kind of stupid, because EnumType just + // mangles the module name and the var name together again... + // but well. + bro_int_t index = request_type->AsEnumType()->Lookup(module, var.c_str()); + if ( index == -1 ) { - // Convert to string first to not have to deal with missing - // \0's... - string enum_string(val->val.string_val.data, val->val.string_val.length); + Warning(i, "Value '%s' for stream '%s' is not a valid enum.", enum_string.c_str(), + i->name.c_str()); - string module = zeek::detail::extract_module_name(enum_string.c_str()); - string var = zeek::detail::extract_var_name(enum_string.c_str()); - - // Well, this is kind of stupid, because EnumType just - // mangles the module name and the var name together again... - // but well. - bro_int_t index = request_type->AsEnumType()->Lookup(module, var.c_str()); - if ( index == -1 ) - { - Warning(i, "Value '%s' for stream '%s' is not a valid enum.", - enum_string.c_str(), i->name.c_str()); - - have_error = true; - return nullptr; - } - - auto rval = request_type->AsEnumType()->GetEnumVal(index); - return rval.release(); + have_error = true; + return nullptr; } + auto rval = request_type->AsEnumType()->GetEnumVal(index); + return rval.release(); + } + default: reporter->InternalError("Unsupported type for input_read in stream %s", i->name.c_str()); diff --git a/src/input/readers/ascii/Ascii.cc b/src/input/readers/ascii/Ascii.cc index fb83073bc4..2a001f04fa 100644 --- a/src/input/readers/ascii/Ascii.cc +++ b/src/input/readers/ascii/Ascii.cc @@ -281,59 +281,59 @@ bool Ascii::DoUpdate() switch ( Info().mode ) { case MODE_REREAD: + { + // check if the file has changed + struct stat sb; + if ( stat(fname.c_str(), &sb) == -1 ) { - // check if the file has changed - struct stat sb; - if ( stat(fname.c_str(), &sb) == -1 ) - { - FailWarn(fail_on_file_problem, Fmt("Could not get stat for %s", fname.c_str()), - true); + FailWarn(fail_on_file_problem, Fmt("Could not get stat for %s", fname.c_str()), + true); - file.close(); - return ! fail_on_file_problem; - } - - if ( sb.st_ino == ino && sb.st_mtime == mtime ) - // no change - return true; - - // Warn again in case of trouble if the file changes. The comparison to 0 - // is to suppress an extra warning that we'd otherwise get on the initial - // inode assignment. - if ( ino != 0 ) - StopWarningSuppression(); - - mtime = sb.st_mtime; - ino = sb.st_ino; - // File changed. Fall through to re-read. + file.close(); + return ! fail_on_file_problem; } + if ( sb.st_ino == ino && sb.st_mtime == mtime ) + // no change + return true; + + // Warn again in case of trouble if the file changes. The comparison to 0 + // is to suppress an extra warning that we'd otherwise get on the initial + // inode assignment. + if ( ino != 0 ) + StopWarningSuppression(); + + mtime = sb.st_mtime; + ino = sb.st_ino; + // File changed. Fall through to re-read. + } + case MODE_MANUAL: case MODE_STREAM: + { + // dirty, fix me. (well, apparently after trying seeking, etc + // - this is not that bad) + if ( file.is_open() ) { - // dirty, fix me. (well, apparently after trying seeking, etc - // - this is not that bad) - if ( file.is_open() ) + if ( Info().mode == MODE_STREAM ) { - if ( Info().mode == MODE_STREAM ) + file.clear(); // remove end of file evil bits + if ( ! ReadHeader(true) ) { - file.clear(); // remove end of file evil bits - if ( ! ReadHeader(true) ) - { - return ! fail_on_file_problem; // header reading failed - } - - break; + return ! fail_on_file_problem; // header reading failed } - file.close(); + break; } - OpenFile(); - - break; + file.close(); } + OpenFile(); + + break; + } + default: assert(false); } diff --git a/src/input/readers/benchmark/Benchmark.cc b/src/input/readers/benchmark/Benchmark.cc index 0b92ad6ec8..89beb3a9eb 100644 --- a/src/input/readers/benchmark/Benchmark.cc +++ b/src/input/readers/benchmark/Benchmark.cc @@ -134,12 +134,12 @@ threading::Value* Benchmark::EntryToVal(TypeTag type, TypeTag subtype) assert(false); // no enums, please. case TYPE_STRING: - { - std::string rnd = RandomString(10); - val->val.string_val.data = util::copy_string(rnd.c_str()); - val->val.string_val.length = rnd.size(); - break; - } + { + std::string rnd = RandomString(10); + val->val.string_val.data = util::copy_string(rnd.c_str()); + val->val.string_val.length = rnd.size(); + break; + } case TYPE_BOOL: val->val.int_val = 1; // we never lie. @@ -168,10 +168,10 @@ threading::Value* Benchmark::EntryToVal(TypeTag type, TypeTag subtype) break; case TYPE_SUBNET: - { - val->val.subnet_val.prefix = ascii->ParseAddr("192.168.17.1"); - val->val.subnet_val.length = 16; - } + { + val->val.subnet_val.prefix = ascii->ParseAddr("192.168.17.1"); + val->val.subnet_val.length = 16; + } break; case TYPE_ADDR: diff --git a/src/input/readers/binary/Binary.cc b/src/input/readers/binary/Binary.cc index 526a48bc82..a12bab3023 100644 --- a/src/input/readers/binary/Binary.cc +++ b/src/input/readers/binary/Binary.cc @@ -199,20 +199,20 @@ bool Binary::DoUpdate() switch ( Info().mode ) { case MODE_REREAD: + { + switch ( UpdateModificationTime() ) { - switch ( UpdateModificationTime() ) - { - case -1: - return false; // error - case 0: - return true; // no change - case 1: - break; // file changed. reread. - default: - assert(false); - } - // fallthrough + case -1: + return false; // error + case 0: + return true; // no change + case 1: + break; // file changed. reread. + default: + assert(false); } + // fallthrough + } case MODE_MANUAL: case MODE_STREAM: diff --git a/src/input/readers/config/Config.cc b/src/input/readers/config/Config.cc index 2bafa9c30d..011498f059 100644 --- a/src/input/readers/config/Config.cc +++ b/src/input/readers/config/Config.cc @@ -118,54 +118,54 @@ bool Config::DoUpdate() switch ( Info().mode ) { case MODE_REREAD: + { + // check if the file has changed + struct stat sb; + if ( stat(Info().source, &sb) == -1 ) { - // check if the file has changed - struct stat sb; - if ( stat(Info().source, &sb) == -1 ) - { - FailWarn(fail_on_file_problem, Fmt("Could not get stat for %s", Info().source), - true); + FailWarn(fail_on_file_problem, Fmt("Could not get stat for %s", Info().source), + true); - file.close(); - return ! fail_on_file_problem; - } - - if ( sb.st_ino == ino && sb.st_mtime == mtime ) - // no change - return true; - - // Warn again in case of trouble if the file changes. The comparison to 0 - // is to suppress an extra warning that we'd otherwise get on the initial - // inode assignment. - if ( ino != 0 ) - StopWarningSuppression(); - - mtime = sb.st_mtime; - ino = sb.st_ino; - // File changed. Fall through to re-read. + file.close(); + return ! fail_on_file_problem; } + if ( sb.st_ino == ino && sb.st_mtime == mtime ) + // no change + return true; + + // Warn again in case of trouble if the file changes. The comparison to 0 + // is to suppress an extra warning that we'd otherwise get on the initial + // inode assignment. + if ( ino != 0 ) + StopWarningSuppression(); + + mtime = sb.st_mtime; + ino = sb.st_ino; + // File changed. Fall through to re-read. + } + case MODE_MANUAL: case MODE_STREAM: + { + // dirty, fix me. (well, apparently after trying seeking, etc + // - this is not that bad) + if ( file.is_open() ) { - // dirty, fix me. (well, apparently after trying seeking, etc - // - this is not that bad) - if ( file.is_open() ) + if ( Info().mode == MODE_STREAM ) { - if ( Info().mode == MODE_STREAM ) - { - file.clear(); // remove end of file evil bits - break; - } - - file.close(); + file.clear(); // remove end of file evil bits + break; } - OpenFile(); - - break; + file.close(); } + OpenFile(); + + break; + } + default: assert(false); } diff --git a/src/input/readers/raw/Raw.cc b/src/input/readers/raw/Raw.cc index 27b1c54831..1d938f6be4 100644 --- a/src/input/readers/raw/Raw.cc +++ b/src/input/readers/raw/Raw.cc @@ -558,27 +558,27 @@ bool Raw::DoUpdate() switch ( Info().mode ) { case MODE_REREAD: + { + assert(childpid == -1); // mode may not be used to execute child programs + // check if the file has changed + struct stat sb; + if ( stat(fname.c_str(), &sb) == -1 ) { - assert(childpid == -1); // mode may not be used to execute child programs - // check if the file has changed - struct stat sb; - if ( stat(fname.c_str(), &sb) == -1 ) - { - Error(Fmt("Could not get stat for %s", fname.c_str())); - return false; - } - - if ( sb.st_ino == ino && sb.st_mtime == mtime ) - // no change - return true; - - mtime = sb.st_mtime; - ino = sb.st_ino; - // file changed. reread. - // - // fallthrough + Error(Fmt("Could not get stat for %s", fname.c_str())); + return false; } + if ( sb.st_ino == ino && sb.st_mtime == mtime ) + // no change + return true; + + mtime = sb.st_mtime; + ino = sb.st_ino; + // file changed. reread. + // + // fallthrough + } + case MODE_MANUAL: case MODE_STREAM: if ( Info().mode == MODE_STREAM && file ) diff --git a/src/input/readers/sqlite/SQLite.cc b/src/input/readers/sqlite/SQLite.cc index ebc1c52b5a..a415377cda 100644 --- a/src/input/readers/sqlite/SQLite.cc +++ b/src/input/readers/sqlite/SQLite.cc @@ -136,40 +136,40 @@ Value* SQLite::EntryToVal(sqlite3_stmt* st, const threading::Field* field, int p { case TYPE_ENUM: case TYPE_STRING: - { - const char* text = (const char*)sqlite3_column_text(st, pos); - int length = sqlite3_column_bytes(st, pos); + { + const char* text = (const char*)sqlite3_column_text(st, pos); + int length = sqlite3_column_bytes(st, pos); - char* out = new char[length]; - memcpy(out, text, length); + char* out = new char[length]; + memcpy(out, text, length); - val->val.string_val.length = length; - val->val.string_val.data = out; - break; - } + val->val.string_val.length = length; + val->val.string_val.data = out; + break; + } case TYPE_BOOL: + { + if ( sqlite3_column_type(st, pos) != SQLITE_INTEGER ) { - if ( sqlite3_column_type(st, pos) != SQLITE_INTEGER ) - { - Error("Invalid data type for boolean - expected Integer"); - delete val; - return nullptr; - } - - int res = sqlite3_column_int(st, pos); - - if ( res == 0 || res == 1 ) - val->val.int_val = res; - else - { - Error(Fmt("Invalid value for boolean: %d", res)); - delete val; - return nullptr; - } - break; + Error("Invalid data type for boolean - expected Integer"); + delete val; + return nullptr; } + int res = sqlite3_column_int(st, pos); + + if ( res == 0 || res == 1 ) + val->val.int_val = res; + else + { + Error(Fmt("Invalid value for boolean: %d", res)); + delete val; + return nullptr; + } + break; + } + case TYPE_INT: val->val.int_val = sqlite3_column_int64(st, pos); break; @@ -185,54 +185,54 @@ Value* SQLite::EntryToVal(sqlite3_stmt* st, const threading::Field* field, int p break; case TYPE_PORT: + { + val->val.port_val.port = sqlite3_column_int(st, pos); + val->val.port_val.proto = TRANSPORT_UNKNOWN; + if ( subpos != -1 ) { - val->val.port_val.port = sqlite3_column_int(st, pos); - val->val.port_val.proto = TRANSPORT_UNKNOWN; - if ( subpos != -1 ) - { - const char* text = (const char*)sqlite3_column_text(st, subpos); + const char* text = (const char*)sqlite3_column_text(st, subpos); - if ( text == 0 ) - Error("Port protocol definition did not contain text"); - else - { - std::string s(text, sqlite3_column_bytes(st, subpos)); - val->val.port_val.proto = io->ParseProto(s); - } + if ( text == 0 ) + Error("Port protocol definition did not contain text"); + else + { + std::string s(text, sqlite3_column_bytes(st, subpos)); + val->val.port_val.proto = io->ParseProto(s); } - break; } + break; + } case TYPE_SUBNET: - { - const char* text = (const char*)sqlite3_column_text(st, pos); - std::string s(text, sqlite3_column_bytes(st, pos)); - int pos = s.find('/'); - int width = atoi(s.substr(pos + 1).c_str()); - std::string addr = s.substr(0, pos); + { + const char* text = (const char*)sqlite3_column_text(st, pos); + std::string s(text, sqlite3_column_bytes(st, pos)); + int pos = s.find('/'); + int width = atoi(s.substr(pos + 1).c_str()); + std::string addr = s.substr(0, pos); - val->val.subnet_val.prefix = io->ParseAddr(addr); - val->val.subnet_val.length = width; - break; - } + val->val.subnet_val.prefix = io->ParseAddr(addr); + val->val.subnet_val.length = width; + break; + } case TYPE_ADDR: - { - const char* text = (const char*)sqlite3_column_text(st, pos); - std::string s(text, sqlite3_column_bytes(st, pos)); - val->val.addr_val = io->ParseAddr(s); - break; - } + { + const char* text = (const char*)sqlite3_column_text(st, pos); + std::string s(text, sqlite3_column_bytes(st, pos)); + val->val.addr_val = io->ParseAddr(s); + break; + } case TYPE_TABLE: case TYPE_VECTOR: - { - const char* text = (const char*)sqlite3_column_text(st, pos); - std::string s(text, sqlite3_column_bytes(st, pos)); - delete val; - val = io->ParseValue(s, "", field->type, field->subtype); - break; - } + { + const char* text = (const char*)sqlite3_column_text(st, pos); + std::string s(text, sqlite3_column_bytes(st, pos)); + delete val; + val = io->ParseValue(s, "", field->type, field->subtype); + break; + } default: Error(Fmt("unsupported field format %d", field->type)); diff --git a/src/logging/Manager.cc b/src/logging/Manager.cc index fe29d4ab92..8cd1adc099 100644 --- a/src/logging/Manager.cc +++ b/src/logging/Manager.cc @@ -952,24 +952,24 @@ threading::Value* Manager::ValToLogVal(Val* val, Type* ty) break; case TYPE_ENUM: + { + const char* s = val->GetType()->AsEnumType()->Lookup(val->InternalInt()); + + if ( s ) { - const char* s = val->GetType()->AsEnumType()->Lookup(val->InternalInt()); - - if ( s ) - { - lval->val.string_val.data = util::copy_string(s); - lval->val.string_val.length = strlen(s); - } - - else - { - val->GetType()->Error("enum type does not contain value", val); - lval->val.string_val.data = util::copy_string(""); - lval->val.string_val.length = 0; - } - break; + lval->val.string_val.data = util::copy_string(s); + lval->val.string_val.length = strlen(s); } + else + { + val->GetType()->Error("enum type does not contain value", val); + lval->val.string_val.data = util::copy_string(""); + lval->val.string_val.length = 0; + } + break; + } + case TYPE_COUNT: lval->val.uint_val = val->InternalUnsigned(); break; @@ -994,68 +994,68 @@ threading::Value* Manager::ValToLogVal(Val* val, Type* ty) break; case TYPE_STRING: - { - const String* s = val->AsString(); - char* buf = new char[s->Len()]; - memcpy(buf, s->Bytes(), s->Len()); + { + const String* s = val->AsString(); + char* buf = new char[s->Len()]; + memcpy(buf, s->Bytes(), s->Len()); - lval->val.string_val.data = buf; - lval->val.string_val.length = s->Len(); - break; - } + lval->val.string_val.data = buf; + lval->val.string_val.length = s->Len(); + break; + } case TYPE_FILE: - { - const File* f = val->AsFile(); - string s = f->Name(); - lval->val.string_val.data = util::copy_string(s.c_str()); - lval->val.string_val.length = s.size(); - break; - } + { + const File* f = val->AsFile(); + string s = f->Name(); + lval->val.string_val.data = util::copy_string(s.c_str()); + lval->val.string_val.length = s.size(); + break; + } case TYPE_FUNC: - { - ODesc d; - const Func* f = val->AsFunc(); - f->Describe(&d); - const char* s = d.Description(); - lval->val.string_val.data = util::copy_string(s); - lval->val.string_val.length = strlen(s); - break; - } + { + ODesc d; + const Func* f = val->AsFunc(); + f->Describe(&d); + const char* s = d.Description(); + lval->val.string_val.data = util::copy_string(s); + lval->val.string_val.length = strlen(s); + break; + } case TYPE_TABLE: - { - auto set = val->AsTableVal()->ToPureListVal(); - if ( ! set ) - // ToPureListVal has reported an internal warning - // already. Just keep going by making something up. - set = make_intrusive(TYPE_INT); + { + auto set = val->AsTableVal()->ToPureListVal(); + if ( ! set ) + // ToPureListVal has reported an internal warning + // already. Just keep going by making something up. + set = make_intrusive(TYPE_INT); - lval->val.set_val.size = set->Length(); - lval->val.set_val.vals = new threading::Value*[lval->val.set_val.size]; + lval->val.set_val.size = set->Length(); + lval->val.set_val.vals = new threading::Value*[lval->val.set_val.size]; - for ( bro_int_t i = 0; i < lval->val.set_val.size; i++ ) - lval->val.set_val.vals[i] = ValToLogVal(set->Idx(i).get()); + for ( bro_int_t i = 0; i < lval->val.set_val.size; i++ ) + lval->val.set_val.vals[i] = ValToLogVal(set->Idx(i).get()); - break; - } + break; + } case TYPE_VECTOR: + { + VectorVal* vec = val->AsVectorVal(); + lval->val.vector_val.size = vec->Size(); + lval->val.vector_val.vals = new threading::Value*[lval->val.vector_val.size]; + + for ( bro_int_t i = 0; i < lval->val.vector_val.size; i++ ) { - VectorVal* vec = val->AsVectorVal(); - lval->val.vector_val.size = vec->Size(); - lval->val.vector_val.vals = new threading::Value*[lval->val.vector_val.size]; - - for ( bro_int_t i = 0; i < lval->val.vector_val.size; i++ ) - { - lval->val.vector_val.vals[i] = - ValToLogVal(vec->ValAt(i).get(), vec->GetType()->Yield().get()); - } - - break; + lval->val.vector_val.vals[i] = + ValToLogVal(vec->ValAt(i).get(), vec->GetType()->Yield().get()); } + break; + } + default: reporter->InternalError("unsupported type %s for log_write", type_name(lval->type)); } diff --git a/src/logging/writers/sqlite/SQLite.cc b/src/logging/writers/sqlite/SQLite.cc index 6bdaf718fa..440c62d01c 100644 --- a/src/logging/writers/sqlite/SQLite.cc +++ b/src/logging/writers/sqlite/SQLite.cc @@ -254,16 +254,16 @@ int SQLite::AddParams(Value* val, int pos) return sqlite3_bind_int(st, pos, val->val.port_val.port); case TYPE_SUBNET: - { - string out = io->Render(val->val.subnet_val); - return sqlite3_bind_text(st, pos, out.data(), out.size(), SQLITE_TRANSIENT); - } + { + string out = io->Render(val->val.subnet_val); + return sqlite3_bind_text(st, pos, out.data(), out.size(), SQLITE_TRANSIENT); + } case TYPE_ADDR: - { - string out = io->Render(val->val.addr_val); - return sqlite3_bind_text(st, pos, out.data(), out.size(), SQLITE_TRANSIENT); - } + { + string out = io->Render(val->val.addr_val); + return sqlite3_bind_text(st, pos, out.data(), out.size(), SQLITE_TRANSIENT); + } case TYPE_TIME: case TYPE_INTERVAL: @@ -274,59 +274,59 @@ int SQLite::AddParams(Value* val, int pos) case TYPE_STRING: case TYPE_FILE: case TYPE_FUNC: - { - if ( ! val->val.string_val.length || val->val.string_val.length == 0 ) - return sqlite3_bind_null(st, pos); + { + if ( ! val->val.string_val.length || val->val.string_val.length == 0 ) + return sqlite3_bind_null(st, pos); - return sqlite3_bind_text(st, pos, val->val.string_val.data, - val->val.string_val.length, SQLITE_TRANSIENT); - } + return sqlite3_bind_text(st, pos, val->val.string_val.data, val->val.string_val.length, + SQLITE_TRANSIENT); + } case TYPE_TABLE: - { - ODesc desc; - desc.Clear(); - desc.EnableEscaping(); - desc.AddEscapeSequence(set_separator); + { + ODesc desc; + desc.Clear(); + desc.EnableEscaping(); + desc.AddEscapeSequence(set_separator); - if ( ! val->val.set_val.size ) - desc.Add(empty_field); - else - for ( bro_int_t j = 0; j < val->val.set_val.size; j++ ) - { - if ( j > 0 ) - desc.AddRaw(set_separator); + if ( ! val->val.set_val.size ) + desc.Add(empty_field); + else + for ( bro_int_t j = 0; j < val->val.set_val.size; j++ ) + { + if ( j > 0 ) + desc.AddRaw(set_separator); - io->Describe(&desc, val->val.set_val.vals[j], fields[pos - 1]->name); - } + io->Describe(&desc, val->val.set_val.vals[j], fields[pos - 1]->name); + } - desc.RemoveEscapeSequence(set_separator); - return sqlite3_bind_text(st, pos, (const char*)desc.Bytes(), desc.Len(), - SQLITE_TRANSIENT); - } + desc.RemoveEscapeSequence(set_separator); + return sqlite3_bind_text(st, pos, (const char*)desc.Bytes(), desc.Len(), + SQLITE_TRANSIENT); + } case TYPE_VECTOR: - { - ODesc desc; - desc.Clear(); - desc.EnableEscaping(); - desc.AddEscapeSequence(set_separator); + { + ODesc desc; + desc.Clear(); + desc.EnableEscaping(); + desc.AddEscapeSequence(set_separator); - if ( ! val->val.vector_val.size ) - desc.Add(empty_field); - else - for ( bro_int_t j = 0; j < val->val.vector_val.size; j++ ) - { - if ( j > 0 ) - desc.AddRaw(set_separator); + if ( ! val->val.vector_val.size ) + desc.Add(empty_field); + else + for ( bro_int_t j = 0; j < val->val.vector_val.size; j++ ) + { + if ( j > 0 ) + desc.AddRaw(set_separator); - io->Describe(&desc, val->val.vector_val.vals[j], fields[pos - 1]->name); - } + io->Describe(&desc, val->val.vector_val.vals[j], fields[pos - 1]->name); + } - desc.RemoveEscapeSequence(set_separator); - return sqlite3_bind_text(st, pos, (const char*)desc.Bytes(), desc.Len(), - SQLITE_TRANSIENT); - } + desc.RemoveEscapeSequence(set_separator); + return sqlite3_bind_text(st, pos, (const char*)desc.Bytes(), desc.Len(), + SQLITE_TRANSIENT); + } default: Error(Fmt("unsupported field format %d", val->type)); diff --git a/src/packet_analysis/protocol/arp/ARP.cc b/src/packet_analysis/protocol/arp/ARP.cc index 00da3182a2..ce70264058 100644 --- a/src/packet_analysis/protocol/arp/ARP.cc +++ b/src/packet_analysis/protocol/arp/ARP.cc @@ -115,11 +115,11 @@ bool ARPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) break; default: - { - // don't know how to proceed - BadARPEvent(ah, "unknown-arp-hw-address (hrd=%i)", ntohs(ah->ar_hrd)); - return false; - } + { + // don't know how to proceed + BadARPEvent(ah, "unknown-arp-hw-address (hrd=%i)", ntohs(ah->ar_hrd)); + return false; + } } // Note: We don't support IPv6 addresses. @@ -136,11 +136,11 @@ bool ARPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) break; default: - { - // don't know how to proceed - BadARPEvent(ah, "unknown-arp-proto-address (pro=%i)", ntohs(ah->ar_pro)); - return false; - } + { + // don't know how to proceed + BadARPEvent(ah, "unknown-arp-proto-address (pro=%i)", ntohs(ah->ar_pro)); + return false; + } } // Check MAC src address = ARP sender MAC address. @@ -167,18 +167,18 @@ bool ARPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) case ARPOP_REVREPLY: case ARPOP_INVREQUEST: case ARPOP_INVREPLY: - { - // don't know how to handle the opcode - BadARPEvent(ah, "unimplemented-arp-opcode (%i)", ntohs(ah->ar_op)); - return false; - } + { + // don't know how to handle the opcode + BadARPEvent(ah, "unimplemented-arp-opcode (%i)", ntohs(ah->ar_op)); + return false; + } default: - { - // invalid opcode - BadARPEvent(ah, "invalid-arp-opcode (opcode=%i)", ntohs(ah->ar_op)); - return false; - } + { + // invalid opcode + BadARPEvent(ah, "invalid-arp-opcode (opcode=%i)", ntohs(ah->ar_op)); + return false; + } } // Leave packet analyzer land diff --git a/src/packet_analysis/protocol/icmp/ICMP.cc b/src/packet_analysis/protocol/icmp/ICMP.cc index b6cf3689c3..4913859b18 100644 --- a/src/packet_analysis/protocol/icmp/ICMP.cc +++ b/src/packet_analysis/protocol/icmp/ICMP.cc @@ -274,36 +274,36 @@ TransportProto ICMPAnalyzer::GetContextProtocol(const IP_Hdr* ip_hdr, uint32_t* switch ( proto ) { case TRANSPORT_ICMP: - { - const struct icmp* icmpp = (const struct icmp*)transport_hdr; - bool is_one_way; // dummy - *src_port = ntohs(icmpp->icmp_type); + { + const struct icmp* icmpp = (const struct icmp*)transport_hdr; + bool is_one_way; // dummy + *src_port = ntohs(icmpp->icmp_type); - if ( ip4 ) - *dst_port = - ntohs(ICMP4_counterpart(icmpp->icmp_type, icmpp->icmp_code, is_one_way)); - else - *dst_port = - ntohs(ICMP6_counterpart(icmpp->icmp_type, icmpp->icmp_code, is_one_way)); + if ( ip4 ) + *dst_port = + ntohs(ICMP4_counterpart(icmpp->icmp_type, icmpp->icmp_code, is_one_way)); + else + *dst_port = + ntohs(ICMP6_counterpart(icmpp->icmp_type, icmpp->icmp_code, is_one_way)); - break; - } + break; + } case TRANSPORT_TCP: - { - const struct tcphdr* tp = (const struct tcphdr*)transport_hdr; - *src_port = ntohs(tp->th_sport); - *dst_port = ntohs(tp->th_dport); - break; - } + { + const struct tcphdr* tp = (const struct tcphdr*)transport_hdr; + *src_port = ntohs(tp->th_sport); + *dst_port = ntohs(tp->th_dport); + break; + } case TRANSPORT_UDP: - { - const struct udphdr* up = (const struct udphdr*)transport_hdr; - *src_port = ntohs(up->uh_sport); - *dst_port = ntohs(up->uh_dport); - break; - } + { + const struct udphdr* up = (const struct udphdr*)transport_hdr; + *src_port = ntohs(up->uh_sport); + *dst_port = ntohs(up->uh_dport); + break; + } default: *src_port = *dst_port = ntohs(0); @@ -749,10 +749,10 @@ zeek::VectorValPtr ICMPAnalyzer::BuildNDOptionsVal(int caplen, const u_char* dat } default: - { - set_payload_field = true; - break; - } + { + set_payload_field = true; + break; + } } if ( set_payload_field ) diff --git a/src/packet_analysis/protocol/wrapper/Wrapper.cc b/src/packet_analysis/protocol/wrapper/Wrapper.cc index eb35de24d8..f88e6ce3b6 100644 --- a/src/packet_analysis/protocol/wrapper/Wrapper.cc +++ b/src/packet_analysis/protocol/wrapper/Wrapper.cc @@ -48,45 +48,45 @@ bool WrapperAnalyzer::Analyze(Packet* packet, const uint8_t*& data) // 802.1q / 802.1ad case 0x8100: case 0x9100: + { + if ( data + 4 >= end_of_data ) { - if ( data + 4 >= end_of_data ) - { - Weird("truncated_link_header", packet); - return false; - } - - auto& vlan_ref = saw_vlan ? packet->inner_vlan : packet->vlan; - vlan_ref = ((data[0] << 8u) + data[1]) & 0xfff; - protocol = ((data[2] << 8u) + data[3]); - data += 4; // Skip the vlan header - saw_vlan = true; - packet->eth_type = protocol; + Weird("truncated_link_header", packet); + return false; } + + auto& vlan_ref = saw_vlan ? packet->inner_vlan : packet->vlan; + vlan_ref = ((data[0] << 8u) + data[1]) & 0xfff; + protocol = ((data[2] << 8u) + data[3]); + data += 4; // Skip the vlan header + saw_vlan = true; + packet->eth_type = protocol; + } break; // PPPoE carried over the ethernet frame. case 0x8864: + { + if ( data + 8 >= end_of_data ) { - if ( data + 8 >= end_of_data ) - { - Weird("truncated_link_header", packet); - return false; - } - - protocol = (data[6] << 8u) + data[7]; - data += 8; // Skip the PPPoE session and PPP header - - if ( protocol == 0x0021 ) - packet->l3_proto = L3_IPV4; - else if ( protocol == 0x0057 ) - packet->l3_proto = L3_IPV6; - else - { - // Neither IPv4 nor IPv6. - Weird("non_ip_packet_in_pppoe_encapsulation", packet); - return false; - } + Weird("truncated_link_header", packet); + return false; } + + protocol = (data[6] << 8u) + data[7]; + data += 8; // Skip the PPPoE session and PPP header + + if ( protocol == 0x0021 ) + packet->l3_proto = L3_IPV4; + else if ( protocol == 0x0057 ) + packet->l3_proto = L3_IPV6; + else + { + // Neither IPv4 nor IPv6. + Weird("non_ip_packet_in_pppoe_encapsulation", packet); + return false; + } + } break; } } diff --git a/src/plugin/Plugin.cc b/src/plugin/Plugin.cc index 69bb7f79e8..c569b1afeb 100644 --- a/src/plugin/Plugin.cc +++ b/src/plugin/Plugin.cc @@ -168,57 +168,57 @@ void HookArgument::Describe(ODesc* d) const break; case WRITER_INFO: + { + d->Add(arg.winfo->path); + d->Add("("); + d->Add(arg.winfo->network_time); + d->Add(","); + d->Add(arg.winfo->rotation_interval); + d->Add(","); + d->Add(arg.winfo->rotation_base); + + if ( arg.winfo->config.size() > 0 ) { - d->Add(arg.winfo->path); - d->Add("("); - d->Add(arg.winfo->network_time); - d->Add(","); - d->Add(arg.winfo->rotation_interval); - d->Add(","); - d->Add(arg.winfo->rotation_base); + bool first = true; + d->Add("config: {"); - if ( arg.winfo->config.size() > 0 ) + for ( auto& v : arg.winfo->config ) { - bool first = true; - d->Add("config: {"); - - for ( auto& v : arg.winfo->config ) - { - if ( ! first ) - d->Add(", "); - - d->Add(v.first); - d->Add(": "); - d->Add(v.second); - first = false; - } - - d->Add("}"); - } - - d->Add(")"); - } - break; - - case THREAD_FIELDS: - { - d->Add("{"); - - for ( int i = 0; i < tfields.first; i++ ) - { - const threading::Field* f = tfields.second[i]; - - if ( i > 0 ) + if ( ! first ) d->Add(", "); - d->Add(f->name); - d->Add(" ("); - d->Add(f->TypeName()); - d->Add(")"); + d->Add(v.first); + d->Add(": "); + d->Add(v.second); + first = false; } d->Add("}"); } + + d->Add(")"); + } + break; + + case THREAD_FIELDS: + { + d->Add("{"); + + for ( int i = 0; i < tfields.first; i++ ) + { + const threading::Field* f = tfields.second[i]; + + if ( i > 0 ) + d->Add(", "); + + d->Add(f->name); + d->Add(" ("); + d->Add(f->TypeName()); + d->Add(")"); + } + + d->Add("}"); + } break; case LOCATION: diff --git a/src/script_opt/CPP/Consts.cc b/src/script_opt/CPP/Consts.cc index e69a9b963b..c21a1db9b8 100644 --- a/src/script_opt/CPP/Consts.cc +++ b/src/script_opt/CPP/Consts.cc @@ -127,17 +127,17 @@ bool CPPCompile::AddConstant(const ValPtr& vp) case TYPE_ADDR: case TYPE_SUBNET: - { - auto prefix = (tag == TYPE_ADDR) ? "Addr" : "SubNet"; + { + auto prefix = (tag == TYPE_ADDR) ? "Addr" : "SubNet"; - Emit("%sValPtr %s;", prefix, const_name); + Emit("%sValPtr %s;", prefix, const_name); - ODesc d; - v->Describe(&d); + ODesc d; + v->Describe(&d); - AddInit(v, const_name, - string("make_intrusive<") + prefix + "Val>(\"" + d.Description() + "\")"); - } + AddInit(v, const_name, + string("make_intrusive<") + prefix + "Val>(\"" + d.Description() + "\")"); + } break; case TYPE_FUNC: @@ -151,15 +151,15 @@ bool CPPCompile::AddConstant(const ValPtr& vp) break; case TYPE_FILE: - { - Emit("FileValPtr %s;", const_name); + { + Emit("FileValPtr %s;", const_name); - auto f = cast_intrusive(vp)->Get(); + auto f = cast_intrusive(vp)->Get(); - AddInit(v, const_name, - string("make_intrusive(") + "make_intrusive(\"" + f->Name() + - "\", \"w\"))"); - } + AddInit(v, const_name, + string("make_intrusive(") + "make_intrusive(\"" + f->Name() + + "\", \"w\"))"); + } break; default: diff --git a/src/script_opt/CPP/Inits.cc b/src/script_opt/CPP/Inits.cc index d75d3bcc73..d6f41da620 100644 --- a/src/script_opt/CPP/Inits.cc +++ b/src/script_opt/CPP/Inits.cc @@ -79,17 +79,17 @@ bool CPPCompile::IsSimpleInitExpr(const ExprPtr& e) const return true; case EXPR_RECORD_COERCE: - { // look for coercion of empty record - auto op = e->GetOp1(); + { // look for coercion of empty record + auto op = e->GetOp1(); - if ( op->Tag() != EXPR_RECORD_CONSTRUCTOR ) - return false; + if ( op->Tag() != EXPR_RECORD_CONSTRUCTOR ) + return false; - auto rc = static_cast(op.get()); - const auto& exprs = rc->Op()->AsListExpr()->Exprs(); + auto rc = static_cast(op.get()); + const auto& exprs = rc->Op()->AsListExpr()->Exprs(); - return exprs.length() == 0; - } + return exprs.length() == 0; + } default: return false; @@ -235,16 +235,16 @@ void CPPCompile::GenPreInit(const Type* t) break; case TYPE_RECORD: - { - string name; + { + string name; - if ( t->GetName() != "" ) - name = string("\"") + t->GetName() + string("\""); - else - name = "nullptr"; + if ( t->GetName() != "" ) + name = string("\"") + t->GetName() + string("\""); + else + name = "nullptr"; - pre_init = string("get_record_type__CPP(") + name + ")"; - } + pre_init = string("get_record_type__CPP(") + name + ")"; + } break; case TYPE_LIST: diff --git a/src/script_opt/CPP/RuntimeVec.cc b/src/script_opt/CPP/RuntimeVec.cc index 84a07c816d..3b8eff9c1f 100644 --- a/src/script_opt/CPP/RuntimeVec.cc +++ b/src/script_opt/CPP/RuntimeVec.cc @@ -66,16 +66,16 @@ static VectorTypePtr base_vector_type__CPP(const VectorTypePtr& vt) switch ( vt->Yield()->InternalType() ) \ { \ case TYPE_INTERNAL_INT: \ - { \ - VEC_OP1_KERNEL(AsInt, IntVal, op) \ - break; \ - } \ + { \ + VEC_OP1_KERNEL(AsInt, IntVal, op) \ + break; \ + } \ \ case TYPE_INTERNAL_UNSIGNED: \ - { \ - VEC_OP1_KERNEL(AsCount, CountVal, op) \ - break; \ - } \ + { \ + VEC_OP1_KERNEL(AsCount, CountVal, op) \ + break; \ + } \ \ double_kernel \ \ @@ -126,19 +126,19 @@ VEC_OP1(comp, ~, ) switch ( vt->Yield()->InternalType() ) \ { \ case TYPE_INTERNAL_INT: \ - { \ - if ( vt->Yield()->Tag() == TYPE_BOOL ) \ - VEC_OP2_KERNEL(AsBool, BoolVal, op) \ - else \ - VEC_OP2_KERNEL(AsInt, IntVal, op) \ - break; \ - } \ + { \ + if ( vt->Yield()->Tag() == TYPE_BOOL ) \ + VEC_OP2_KERNEL(AsBool, BoolVal, op) \ + else \ + VEC_OP2_KERNEL(AsInt, IntVal, op) \ + break; \ + } \ \ case TYPE_INTERNAL_UNSIGNED: \ - { \ - VEC_OP2_KERNEL(AsCount, CountVal, op) \ - break; \ - } \ + { \ + VEC_OP2_KERNEL(AsCount, CountVal, op) \ + break; \ + } \ \ double_kernel \ \ @@ -184,22 +184,22 @@ VEC_OP2(oror, ||, ) switch ( vt->Yield()->InternalType() ) \ { \ case TYPE_INTERNAL_INT: \ - { \ - VEC_OP2_KERNEL(AsInt, BoolVal, op) \ - break; \ - } \ + { \ + VEC_OP2_KERNEL(AsInt, BoolVal, op) \ + break; \ + } \ \ case TYPE_INTERNAL_UNSIGNED: \ - { \ - VEC_OP2_KERNEL(AsCount, BoolVal, op) \ - break; \ - } \ + { \ + VEC_OP2_KERNEL(AsCount, BoolVal, op) \ + break; \ + } \ \ case TYPE_INTERNAL_DOUBLE: \ - { \ - VEC_OP2_KERNEL(AsDouble, BoolVal, op) \ - break; \ - } \ + { \ + VEC_OP2_KERNEL(AsDouble, BoolVal, op) \ + break; \ + } \ \ default: \ break; \ diff --git a/src/script_opt/CPP/Stmts.cc b/src/script_opt/CPP/Stmts.cc index 33b28faac8..47d8f713a9 100644 --- a/src/script_opt/CPP/Stmts.cc +++ b/src/script_opt/CPP/Stmts.cc @@ -18,15 +18,15 @@ void CPPCompile::GenStmt(const Stmt* s) break; case STMT_LIST: - { - // These always occur in contexts surrounded by {}'s, - // so no need to add them explicitly. - auto sl = s->AsStmtList(); - const auto& stmts = sl->Stmts(); + { + // These always occur in contexts surrounded by {}'s, + // so no need to add them explicitly. + auto sl = s->AsStmtList(); + const auto& stmts = sl->Stmts(); - for ( const auto& stmt : stmts ) - GenStmt(stmt); - } + for ( const auto& stmt : stmts ) + GenStmt(stmt); + } break; case STMT_EXPR: @@ -82,10 +82,10 @@ void CPPCompile::GenStmt(const Stmt* s) break; case STMT_PRINT: - { - auto el = static_cast(s)->ExprList(); - Emit("do_print_stmt({%s});", GenExpr(el, GEN_VAL_PTR)); - } + { + auto el = static_cast(s)->ExprList(); + Emit("do_print_stmt({%s});", GenExpr(el, GEN_VAL_PTR)); + } break; case STMT_FALLTHROUGH: diff --git a/src/script_opt/CPP/Types.cc b/src/script_opt/CPP/Types.cc index 388b32973c..1e04a33206 100644 --- a/src/script_opt/CPP/Types.cc +++ b/src/script_opt/CPP/Types.cc @@ -466,19 +466,19 @@ void CPPCompile::RegisterType(const TypePtr& tp) break; case TYPE_TYPE: - { - const auto& tt = t->AsTypeType()->GetType(); - NoteNonRecordInitDependency(t, tt); - RegisterType(tt); - } + { + const auto& tt = t->AsTypeType()->GetType(); + NoteNonRecordInitDependency(t, tt); + RegisterType(tt); + } break; case TYPE_VECTOR: - { - const auto& yield = t->AsVectorType()->Yield(); - NoteNonRecordInitDependency(t, yield); - RegisterType(yield); - } + { + const auto& yield = t->AsVectorType()->Yield(); + NoteNonRecordInitDependency(t, yield); + RegisterType(yield); + } break; case TYPE_LIST: diff --git a/src/script_opt/Expr.cc b/src/script_opt/Expr.cc index ab4bb4a18d..c87ef21b31 100644 --- a/src/script_opt/Expr.cc +++ b/src/script_opt/Expr.cc @@ -189,28 +189,28 @@ bool Expr::IsReducedConditional(Reducer* c) const return IsReduced(c); case EXPR_IN: + { + auto op1 = GetOp1(); + auto op2 = GetOp2(); + + if ( op1->Tag() != EXPR_NAME && op1->Tag() != EXPR_LIST ) + return NonReduced(this); + + if ( op2->GetType()->Tag() != TYPE_TABLE || ! op2->IsReduced(c) ) + return NonReduced(this); + + if ( op1->Tag() == EXPR_LIST ) { - auto op1 = GetOp1(); - auto op2 = GetOp2(); + auto l1 = op1->AsListExpr(); + auto& l1_e = l1->Exprs(); - if ( op1->Tag() != EXPR_NAME && op1->Tag() != EXPR_LIST ) + if ( l1_e.length() < 1 || l1_e.length() > 2 ) return NonReduced(this); - - if ( op2->GetType()->Tag() != TYPE_TABLE || ! op2->IsReduced(c) ) - return NonReduced(this); - - if ( op1->Tag() == EXPR_LIST ) - { - auto l1 = op1->AsListExpr(); - auto& l1_e = l1->Exprs(); - - if ( l1_e.length() < 1 || l1_e.length() > 2 ) - return NonReduced(this); - } - - return true; } + return true; + } + case EXPR_EQ: case EXPR_NE: case EXPR_LE: @@ -324,41 +324,41 @@ ExprPtr Expr::ReduceToConditional(Reducer* c, StmtPtr& red_stmt) return Reduce(c, red_stmt); case EXPR_IN: + { + // This is complicated because there are lots of forms + // of "in" expressions, and we're only interested in + // those with 1 or 2 indices, into a table. + auto op1 = GetOp1(); + auto op2 = GetOp2(); + + if ( c->Optimizing() ) + return Reduce(c, red_stmt); + + if ( op2->GetType()->Tag() != TYPE_TABLE ) + // Not a table de-reference. + return Reduce(c, red_stmt); + + if ( op1->Tag() == EXPR_LIST ) { - // This is complicated because there are lots of forms - // of "in" expressions, and we're only interested in - // those with 1 or 2 indices, into a table. - auto op1 = GetOp1(); - auto op2 = GetOp2(); + auto l1 = op1->AsListExpr(); + auto& l1_e = l1->Exprs(); - if ( c->Optimizing() ) + if ( l1_e.length() < 1 || l1_e.length() > 2 ) + // Wrong number of indices. return Reduce(c, red_stmt); - - if ( op2->GetType()->Tag() != TYPE_TABLE ) - // Not a table de-reference. - return Reduce(c, red_stmt); - - if ( op1->Tag() == EXPR_LIST ) - { - auto l1 = op1->AsListExpr(); - auto& l1_e = l1->Exprs(); - - if ( l1_e.length() < 1 || l1_e.length() > 2 ) - // Wrong number of indices. - return Reduce(c, red_stmt); - } - - if ( ! op1->IsReduced(c) || ! op2->IsReduced(c) ) - { - auto red2_stmt = ReduceToSingletons(c); - auto res = ReduceToConditional(c, red_stmt); - red_stmt = MergeStmts(red2_stmt, red_stmt); - return res; - } - - return ThisPtr(); } + if ( ! op1->IsReduced(c) || ! op2->IsReduced(c) ) + { + auto red2_stmt = ReduceToSingletons(c); + auto res = ReduceToConditional(c, red_stmt); + red_stmt = MergeStmts(red2_stmt, red_stmt); + return res; + } + + return ThisPtr(); + } + case EXPR_EQ: case EXPR_NE: case EXPR_LE: @@ -1489,10 +1489,10 @@ bool RefExpr::HasReducedOps(Reducer* c) const return op->AsFieldExpr()->Op()->IsReduced(c); case EXPR_INDEX: - { - auto ind = op->AsIndexExpr(); - return ind->Op1()->IsReduced(c) && ind->Op2()->IsReduced(c); - } + { + auto ind = op->AsIndexExpr(); + return ind->Op1()->IsReduced(c) && ind->Op2()->IsReduced(c); + } case EXPR_LIST: return op->IsReduced(c); diff --git a/src/script_opt/GenIDDefs.cc b/src/script_opt/GenIDDefs.cc index ef6fdbe295..440316019d 100644 --- a/src/script_opt/GenIDDefs.cc +++ b/src/script_opt/GenIDDefs.cc @@ -67,140 +67,140 @@ TraversalCode GenIDDefs::PreStmt(const Stmt* s) switch ( s->Tag() ) { case STMT_CATCH_RETURN: - { - auto cr = s->AsCatchReturnStmt(); - auto block = cr->Block(); + { + auto cr = s->AsCatchReturnStmt(); + auto block = cr->Block(); - StartConfluenceBlock(s); - block->Traverse(this); - EndConfluenceBlock(); + StartConfluenceBlock(s); + block->Traverse(this); + EndConfluenceBlock(); - auto retvar = cr->RetVar(); - if ( retvar ) - TrackID(retvar->Id()); + auto retvar = cr->RetVar(); + if ( retvar ) + TrackID(retvar->Id()); - return TC_ABORTSTMT; - } + return TC_ABORTSTMT; + } case STMT_IF: - { - auto i = s->AsIfStmt(); - auto cond = i->StmtExpr(); - auto t_branch = i->TrueBranch(); - auto f_branch = i->FalseBranch(); + { + auto i = s->AsIfStmt(); + auto cond = i->StmtExpr(); + auto t_branch = i->TrueBranch(); + auto f_branch = i->FalseBranch(); - cond->Traverse(this); + cond->Traverse(this); - StartConfluenceBlock(s); + StartConfluenceBlock(s); - t_branch->Traverse(this); - if ( ! t_branch->NoFlowAfter(false) ) - BranchBeyond(curr_stmt, s, true); + t_branch->Traverse(this); + if ( ! t_branch->NoFlowAfter(false) ) + BranchBeyond(curr_stmt, s, true); - f_branch->Traverse(this); - if ( ! f_branch->NoFlowAfter(false) ) - BranchBeyond(curr_stmt, s, true); + f_branch->Traverse(this); + if ( ! f_branch->NoFlowAfter(false) ) + BranchBeyond(curr_stmt, s, true); - EndConfluenceBlock(true); + EndConfluenceBlock(true); - return TC_ABORTSTMT; - } + return TC_ABORTSTMT; + } case STMT_SWITCH: + { + auto sw = s->AsSwitchStmt(); + auto e = sw->StmtExpr(); + + e->Traverse(this); + + StartConfluenceBlock(sw); + + for ( const auto& c : *sw->Cases() ) { - auto sw = s->AsSwitchStmt(); - auto e = sw->StmtExpr(); + auto body = c->Body(); - e->Traverse(this); + auto exprs = c->ExprCases(); + if ( exprs ) + exprs->Traverse(this); - StartConfluenceBlock(sw); - - for ( const auto& c : *sw->Cases() ) + auto type_ids = c->TypeCases(); + if ( type_ids ) { - auto body = c->Body(); - - auto exprs = c->ExprCases(); - if ( exprs ) - exprs->Traverse(this); - - auto type_ids = c->TypeCases(); - if ( type_ids ) - { - for ( const auto& id : *type_ids ) - if ( id->Name() ) - TrackID(id); - } - - body->Traverse(this); + for ( const auto& id : *type_ids ) + if ( id->Name() ) + TrackID(id); } - EndConfluenceBlock(sw->HasDefault()); - - return TC_ABORTSTMT; + body->Traverse(this); } + EndConfluenceBlock(sw->HasDefault()); + + return TC_ABORTSTMT; + } + case STMT_FOR: - { - auto f = s->AsForStmt(); + { + auto f = s->AsForStmt(); - auto ids = f->LoopVars(); - auto e = f->LoopExpr(); - auto body = f->LoopBody(); - auto val_var = f->ValueVar(); + auto ids = f->LoopVars(); + auto e = f->LoopExpr(); + auto body = f->LoopBody(); + auto val_var = f->ValueVar(); - e->Traverse(this); + e->Traverse(this); - for ( const auto& id : *ids ) - TrackID(id); + for ( const auto& id : *ids ) + TrackID(id); - if ( val_var ) - TrackID(val_var); + if ( val_var ) + TrackID(val_var); - StartConfluenceBlock(s); - body->Traverse(this); + StartConfluenceBlock(s); + body->Traverse(this); - if ( ! body->NoFlowAfter(false) ) - BranchBackTo(curr_stmt, s, true); + if ( ! body->NoFlowAfter(false) ) + BranchBackTo(curr_stmt, s, true); - EndConfluenceBlock(); + EndConfluenceBlock(); - return TC_ABORTSTMT; - } + return TC_ABORTSTMT; + } case STMT_WHILE: - { - auto w = s->AsWhileStmt(); + { + auto w = s->AsWhileStmt(); - StartConfluenceBlock(s); + StartConfluenceBlock(s); - auto cond_pred_stmt = w->CondPredStmt(); - if ( cond_pred_stmt ) - cond_pred_stmt->Traverse(this); + auto cond_pred_stmt = w->CondPredStmt(); + if ( cond_pred_stmt ) + cond_pred_stmt->Traverse(this); - // Important to traverse the condition in its version - // interpreted as a statement, so that when evaluating - // its variable usage, that's done in the context of - // *after* cond_pred_stmt executes, rather than as - // part of that execution. - auto cond_stmt = w->ConditionAsStmt(); - cond_stmt->Traverse(this); + // Important to traverse the condition in its version + // interpreted as a statement, so that when evaluating + // its variable usage, that's done in the context of + // *after* cond_pred_stmt executes, rather than as + // part of that execution. + auto cond_stmt = w->ConditionAsStmt(); + cond_stmt->Traverse(this); - auto body = w->Body(); - body->Traverse(this); + auto body = w->Body(); + body->Traverse(this); - if ( ! body->NoFlowAfter(false) ) - BranchBackTo(curr_stmt, s, true); + if ( ! body->NoFlowAfter(false) ) + BranchBackTo(curr_stmt, s, true); - EndConfluenceBlock(); + EndConfluenceBlock(); - return TC_ABORTSTMT; - } + return TC_ABORTSTMT; + } case STMT_WHEN: - { - // ### punt on these for now, need to reflect on bindings. - return TC_ABORTSTMT; - } + { + // ### punt on these for now, need to reflect on bindings. + return TC_ABORTSTMT; + } default: return TC_CONTINUE; @@ -212,22 +212,22 @@ TraversalCode GenIDDefs::PostStmt(const Stmt* s) switch ( s->Tag() ) { case STMT_INIT: + { + auto init = s->AsInitStmt(); + auto& inits = init->Inits(); + + for ( const auto& id : inits ) { - auto init = s->AsInitStmt(); - auto& inits = init->Inits(); + auto id_t = id->GetType(); - for ( const auto& id : inits ) - { - auto id_t = id->GetType(); - - // Only aggregates get initialized. - if ( zeek::IsAggr(id->GetType()->Tag()) ) - TrackID(id); - } - - break; + // Only aggregates get initialized. + if ( zeek::IsAggr(id->GetType()->Tag()) ) + TrackID(id); } + break; + } + case STMT_RETURN: ReturnAt(s); break; @@ -237,21 +237,21 @@ TraversalCode GenIDDefs::PostStmt(const Stmt* s) break; case STMT_BREAK: + { + auto target = FindBreakTarget(); + + if ( target ) + BranchBeyond(s, target, false); + + else { - auto target = FindBreakTarget(); - - if ( target ) - BranchBeyond(s, target, false); - - else - { - ASSERT(func_flavor == FUNC_FLAVOR_HOOK); - ReturnAt(s); - } - - break; + ASSERT(func_flavor == FUNC_FLAVOR_HOOK); + ReturnAt(s); } + break; + } + case STMT_FALLTHROUGH: // No need to do anything, the work all occurs // with NoFlowAfter. @@ -275,29 +275,29 @@ TraversalCode GenIDDefs::PreExpr(const Expr* e) break; case EXPR_ASSIGN: + { + auto lhs = e->GetOp1(); + auto op2 = e->GetOp2(); + + if ( lhs->Tag() == EXPR_LIST && op2->GetType()->Tag() != TYPE_ANY ) { - auto lhs = e->GetOp1(); - auto op2 = e->GetOp2(); - - if ( lhs->Tag() == EXPR_LIST && op2->GetType()->Tag() != TYPE_ANY ) - { - // This combination occurs only for assignments used - // to initialize table entries. Treat it as references - // to both the lhs and the rhs, not as an assignment. - return TC_CONTINUE; - } - - op2->Traverse(this); - - if ( ! CheckLHS(lhs, op2) ) - // Not a simple assignment (or group of assignments), - // so analyze the accesses to check for use of - // possibly undefined values. - lhs->Traverse(this); - - return TC_ABORTSTMT; + // This combination occurs only for assignments used + // to initialize table entries. Treat it as references + // to both the lhs and the rhs, not as an assignment. + return TC_CONTINUE; } + op2->Traverse(this); + + if ( ! CheckLHS(lhs, op2) ) + // Not a simple assignment (or group of assignments), + // so analyze the accesses to check for use of + // possibly undefined values. + lhs->Traverse(this); + + return TC_ABORTSTMT; + } + case EXPR_COND: // Special hack. We turn off checking for usage issues // inside conditionals. This is because we use them heavily @@ -314,17 +314,17 @@ TraversalCode GenIDDefs::PreExpr(const Expr* e) return TC_ABORTSTMT; case EXPR_LAMBDA: - { - auto l = static_cast(e); - const auto& ids = l->OuterIDs(); + { + auto l = static_cast(e); + const auto& ids = l->OuterIDs(); - for ( auto& id : ids ) - CheckVarUsage(e, id); + for ( auto& id : ids ) + CheckVarUsage(e, id); - // Don't descend into the lambda body - we'll analyze and - // optimize it separately, as its own function. - return TC_ABORTSTMT; - } + // Don't descend into the lambda body - we'll analyze and + // optimize it separately, as its own function. + return TC_ABORTSTMT; + } default: break; @@ -360,29 +360,29 @@ bool GenIDDefs::CheckLHS(const ExprPtr& lhs, const ExprPtr& rhs) return CheckLHS(lhs->GetOp1(), rhs); case EXPR_NAME: - { - auto n = lhs->AsNameExpr(); - TrackID(n->Id(), rhs); - return true; - } + { + auto n = lhs->AsNameExpr(); + TrackID(n->Id(), rhs); + return true; + } case EXPR_LIST: - { // look for [a, b, c] = any_val - auto l = lhs->AsListExpr(); - for ( const auto& expr : l->Exprs() ) - { - if ( expr->Tag() != EXPR_NAME ) - // This will happen for table initializers, - // for example. - return false; + { // look for [a, b, c] = any_val + auto l = lhs->AsListExpr(); + for ( const auto& expr : l->Exprs() ) + { + if ( expr->Tag() != EXPR_NAME ) + // This will happen for table initializers, + // for example. + return false; - auto n = expr->AsNameExpr(); - TrackID(n->Id()); - } - - return true; + auto n = expr->AsNameExpr(); + TrackID(n->Id()); } + return true; + } + case EXPR_FIELD: // If we want to track record field initializations, // we'd handle that here. diff --git a/src/script_opt/ProfileFunc.cc b/src/script_opt/ProfileFunc.cc index eae018bac2..da6802ff99 100644 --- a/src/script_opt/ProfileFunc.cc +++ b/src/script_opt/ProfileFunc.cc @@ -129,49 +129,49 @@ TraversalCode ProfileFunc::PreStmt(const Stmt* s) break; case STMT_FOR: - { - auto sf = s->AsForStmt(); - auto loop_vars = sf->LoopVars(); - auto value_var = sf->ValueVar(); + { + auto sf = s->AsForStmt(); + auto loop_vars = sf->LoopVars(); + auto value_var = sf->ValueVar(); - for ( auto id : *loop_vars ) - locals.insert(id); + for ( auto id : *loop_vars ) + locals.insert(id); - if ( value_var ) - locals.insert(value_var.get()); - } + if ( value_var ) + locals.insert(value_var.get()); + } break; case STMT_SWITCH: + { + // If this is a type-case switch statement, then find the + // identifiers created so we can add them to our list of + // locals. Ideally this wouldn't be necessary since *surely* + // if one bothers to define such an identifier then it'll be + // subsequently used, and we'll pick up the local that way ... + // but if for some reason it's not, then we would have an + // incomplete list of locals that need to be tracked. + + auto sw = s->AsSwitchStmt(); + bool is_type_switch = false; + + for ( auto& c : *sw->Cases() ) { - // If this is a type-case switch statement, then find the - // identifiers created so we can add them to our list of - // locals. Ideally this wouldn't be necessary since *surely* - // if one bothers to define such an identifier then it'll be - // subsequently used, and we'll pick up the local that way ... - // but if for some reason it's not, then we would have an - // incomplete list of locals that need to be tracked. - - auto sw = s->AsSwitchStmt(); - bool is_type_switch = false; - - for ( auto& c : *sw->Cases() ) + auto idl = c->TypeCases(); + if ( idl ) { - auto idl = c->TypeCases(); - if ( idl ) - { - for ( auto id : *idl ) - locals.insert(id); + for ( auto id : *idl ) + locals.insert(id); - is_type_switch = true; - } + is_type_switch = true; } - - if ( is_type_switch ) - type_switches.insert(sw); - else - expr_switches.insert(sw); } + + if ( is_type_switch ) + type_switches.insert(sw); + else + expr_switches.insert(sw); + } break; default: @@ -194,46 +194,46 @@ TraversalCode ProfileFunc::PreExpr(const Expr* e) break; case EXPR_NAME: + { + auto n = e->AsNameExpr(); + auto id = n->Id(); + + if ( id->IsGlobal() ) { - auto n = e->AsNameExpr(); - auto id = n->Id(); + globals.insert(id); + all_globals.insert(id); - if ( id->IsGlobal() ) - { - globals.insert(id); - all_globals.insert(id); - - const auto& t = id->GetType(); - if ( t->Tag() == TYPE_FUNC && t->AsFuncType()->Flavor() == FUNC_FLAVOR_EVENT ) - events.insert(id->Name()); - } - - else - { - // This is a tad ugly. Unfortunately due to the - // weird way that Zeek function *declarations* work, - // there's no reliable way to get the list of - // parameters for a function *definition*, since - // they can have different names than what's present - // in the declaration. So we identify them directly, - // by knowing that they come at the beginning of the - // frame ... and being careful to avoid misconfusing - // a lambda capture with a low frame offset as a - // parameter. - if ( captures.count(id) == 0 && id->Offset() < num_params ) - params.insert(id); - - locals.insert(id); - } - - // Turns out that NameExpr's can be constructed using a - // different Type* than that of the identifier itself, - // so be sure we track the latter too. - TrackType(id->GetType()); - - break; + const auto& t = id->GetType(); + if ( t->Tag() == TYPE_FUNC && t->AsFuncType()->Flavor() == FUNC_FLAVOR_EVENT ) + events.insert(id->Name()); } + else + { + // This is a tad ugly. Unfortunately due to the + // weird way that Zeek function *declarations* work, + // there's no reliable way to get the list of + // parameters for a function *definition*, since + // they can have different names than what's present + // in the declaration. So we identify them directly, + // by knowing that they come at the beginning of the + // frame ... and being careful to avoid misconfusing + // a lambda capture with a low frame offset as a + // parameter. + if ( captures.count(id) == 0 && id->Offset() < num_params ) + params.insert(id); + + locals.insert(id); + } + + // Turns out that NameExpr's can be constructed using a + // different Type* than that of the identifier itself, + // so be sure we track the latter too. + TrackType(id->GetType()); + + break; + } + case EXPR_FIELD: if ( abs_rec_fields ) { @@ -265,130 +265,130 @@ TraversalCode ProfileFunc::PreExpr(const Expr* e) case EXPR_ADD_TO: case EXPR_REMOVE_FROM: case EXPR_ASSIGN: + { + if ( e->GetOp1()->Tag() == EXPR_REF ) { - if ( e->GetOp1()->Tag() == EXPR_REF ) - { - auto lhs = e->GetOp1()->GetOp1(); - if ( lhs->Tag() == EXPR_NAME ) - TrackAssignment(lhs->AsNameExpr()->Id()); - } - // else this isn't a direct assignment. - break; + auto lhs = e->GetOp1()->GetOp1(); + if ( lhs->Tag() == EXPR_NAME ) + TrackAssignment(lhs->AsNameExpr()->Id()); } + // else this isn't a direct assignment. + break; + } case EXPR_CALL: + { + auto c = e->AsCallExpr(); + auto f = c->Func(); + + if ( f->Tag() != EXPR_NAME ) { - auto c = e->AsCallExpr(); - auto f = c->Func(); + does_indirect_calls = true; + return TC_CONTINUE; + } - if ( f->Tag() != EXPR_NAME ) + auto n = f->AsNameExpr(); + auto func = n->Id(); + + if ( ! func->IsGlobal() ) + { + does_indirect_calls = true; + return TC_CONTINUE; + } + + all_globals.insert(func); + + auto func_v = func->GetVal(); + if ( func_v ) + { + auto func_vf = func_v->AsFunc(); + + if ( func_vf->GetKind() == Func::SCRIPT_FUNC ) { - does_indirect_calls = true; - return TC_CONTINUE; - } + auto bf = static_cast(func_vf); + script_calls.insert(bf); - auto n = f->AsNameExpr(); - auto func = n->Id(); - - if ( ! func->IsGlobal() ) - { - does_indirect_calls = true; - return TC_CONTINUE; - } - - all_globals.insert(func); - - auto func_v = func->GetVal(); - if ( func_v ) - { - auto func_vf = func_v->AsFunc(); - - if ( func_vf->GetKind() == Func::SCRIPT_FUNC ) - { - auto bf = static_cast(func_vf); - script_calls.insert(bf); - - if ( in_when ) - when_calls.insert(bf); - } - else - BiF_globals.insert(func); + if ( in_when ) + when_calls.insert(bf); } else - { - // We could complain, but for now we don't, because - // if we're invoked prior to full Zeek initialization, - // the value might indeed not there yet. - // printf("no function value for global %s\n", func->Name()); - } - - // Recurse into the arguments. - auto args = c->Args(); - args->Traverse(this); - - // Do the following explicitly, since we won't be recursing - // into the LHS global. - - // Note that the type of the expression and the type of the - // function can actually be *different* due to the NameExpr - // being constructed based on a forward reference and then - // the global getting a different (constructed) type when - // the function is actually declared. Geez. So hedge our - // bets. - TrackType(n->GetType()); - TrackType(func->GetType()); - - TrackID(func); - - return TC_ABORTSTMT; + BiF_globals.insert(func); } + else + { + // We could complain, but for now we don't, because + // if we're invoked prior to full Zeek initialization, + // the value might indeed not there yet. + // printf("no function value for global %s\n", func->Name()); + } + + // Recurse into the arguments. + auto args = c->Args(); + args->Traverse(this); + + // Do the following explicitly, since we won't be recursing + // into the LHS global. + + // Note that the type of the expression and the type of the + // function can actually be *different* due to the NameExpr + // being constructed based on a forward reference and then + // the global getting a different (constructed) type when + // the function is actually declared. Geez. So hedge our + // bets. + TrackType(n->GetType()); + TrackType(func->GetType()); + + TrackID(func); + + return TC_ABORTSTMT; + } case EXPR_EVENT: - { - auto ev = e->AsEventExpr()->Name(); - events.insert(ev); - addl_hashes.push_back(p_hash(ev)); - } + { + auto ev = e->AsEventExpr()->Name(); + events.insert(ev); + addl_hashes.push_back(p_hash(ev)); + } break; case EXPR_LAMBDA: + { + auto l = e->AsLambdaExpr(); + lambdas.push_back(l); + + for ( const auto& i : l->OuterIDs() ) { - auto l = e->AsLambdaExpr(); - lambdas.push_back(l); + locals.insert(i); + TrackID(i); - for ( const auto& i : l->OuterIDs() ) - { - locals.insert(i); - TrackID(i); - - // See above re EXPR_NAME regarding the following - // logic. - if ( captures.count(i) == 0 && i->Offset() < num_params ) - params.insert(i); - } - - // Avoid recursing into the body. - return TC_ABORTSTMT; + // See above re EXPR_NAME regarding the following + // logic. + if ( captures.count(i) == 0 && i->Offset() < num_params ) + params.insert(i); } + // Avoid recursing into the body. + return TC_ABORTSTMT; + } + case EXPR_SET_CONSTRUCTOR: - { - auto sc = static_cast(e); - const auto& attrs = sc->GetAttrs(); + { + auto sc = static_cast(e); + const auto& attrs = sc->GetAttrs(); - if ( attrs ) - constructor_attrs.insert(attrs.get()); - } + if ( attrs ) + constructor_attrs.insert(attrs.get()); + } break; case EXPR_TABLE_CONSTRUCTOR: - { - auto tc = static_cast(e); - const auto& attrs = tc->GetAttrs(); + { + auto tc = static_cast(e); + const auto& attrs = tc->GetAttrs(); - if ( attrs ) - constructor_attrs.insert(attrs.get()); - } + if ( attrs ) + constructor_attrs.insert(attrs.get()); + } break; default: @@ -560,46 +560,46 @@ void ProfileFuncs::TraverseValue(const ValPtr& v) break; case TYPE_RECORD: - { - auto r = cast_intrusive(v); - auto n = r->NumFields(); + { + auto r = cast_intrusive(v); + auto n = r->NumFields(); - for ( auto i = 0u; i < n; ++i ) - TraverseValue(r->GetField(i)); - } + for ( auto i = 0u; i < n; ++i ) + TraverseValue(r->GetField(i)); + } break; case TYPE_TABLE: - { - auto tv = cast_intrusive(v); - auto tv_map = tv->ToMap(); + { + auto tv = cast_intrusive(v); + auto tv_map = tv->ToMap(); - for ( auto& tv_i : tv_map ) - { - TraverseValue(tv_i.first); - TraverseValue(tv_i.second); - } + for ( auto& tv_i : tv_map ) + { + TraverseValue(tv_i.first); + TraverseValue(tv_i.second); } + } break; case TYPE_LIST: - { - auto lv = cast_intrusive(v); - auto n = lv->Length(); + { + auto lv = cast_intrusive(v); + auto n = lv->Length(); - for ( auto i = 0; i < n; ++i ) - TraverseValue(lv->Idx(i)); - } + for ( auto i = 0; i < n; ++i ) + TraverseValue(lv->Idx(i)); + } break; case TYPE_VECTOR: - { - auto vv = cast_intrusive(v); - auto n = vv->Size(); + { + auto vv = cast_intrusive(v); + auto n = vv->Size(); - for ( auto i = 0u; i < n; ++i ) - TraverseValue(vv->ValAt(i)); - } + for ( auto i = 0u; i < n; ++i ) + TraverseValue(vv->ValAt(i)); + } break; case TYPE_TYPE: @@ -759,82 +759,82 @@ p_hash_type ProfileFuncs::HashType(const Type* t) break; case TYPE_RECORD: + { + const auto& ft = t->AsRecordType(); + auto n = ft->NumFields(); + auto orig_n = ft->NumOrigFields(); + + h = merge_p_hashes(h, p_hash("record")); + + if ( full_record_hashes ) + h = merge_p_hashes(h, p_hash(n)); + else + h = merge_p_hashes(h, p_hash(orig_n)); + + for ( auto i = 0; i < n; ++i ) { - const auto& ft = t->AsRecordType(); - auto n = ft->NumFields(); - auto orig_n = ft->NumOrigFields(); + bool do_hash = full_record_hashes; + if ( ! do_hash ) + do_hash = (i < orig_n); - h = merge_p_hashes(h, p_hash("record")); + const auto& f = ft->FieldDecl(i); + auto type_h = HashType(f->type); - if ( full_record_hashes ) - h = merge_p_hashes(h, p_hash(n)); - else - h = merge_p_hashes(h, p_hash(orig_n)); - - for ( auto i = 0; i < n; ++i ) + if ( do_hash ) { - bool do_hash = full_record_hashes; - if ( ! do_hash ) - do_hash = (i < orig_n); - - const auto& f = ft->FieldDecl(i); - auto type_h = HashType(f->type); - - if ( do_hash ) - { - h = merge_p_hashes(h, p_hash(f->id)); - h = merge_p_hashes(h, type_h); - } - h = merge_p_hashes(h, p_hash(f->id)); - h = merge_p_hashes(h, HashType(f->type)); + h = merge_p_hashes(h, type_h); + } - // We don't hash the field name, as in some contexts - // those are ignored. + h = merge_p_hashes(h, p_hash(f->id)); + h = merge_p_hashes(h, HashType(f->type)); - if ( f->attrs ) - { - if ( do_hash ) - h = merge_p_hashes(h, HashAttrs(f->attrs)); - AnalyzeAttrs(f->attrs.get()); - } + // We don't hash the field name, as in some contexts + // those are ignored. + + if ( f->attrs ) + { + if ( do_hash ) + h = merge_p_hashes(h, HashAttrs(f->attrs)); + AnalyzeAttrs(f->attrs.get()); } } + } break; case TYPE_TABLE: - { - auto tbl = t->AsTableType(); - h = merge_p_hashes(h, p_hash("table")); - h = merge_p_hashes(h, p_hash("indices")); - h = merge_p_hashes(h, HashType(tbl->GetIndices())); - h = merge_p_hashes(h, p_hash("tbl-yield")); - h = merge_p_hashes(h, HashType(tbl->Yield())); - } + { + auto tbl = t->AsTableType(); + h = merge_p_hashes(h, p_hash("table")); + h = merge_p_hashes(h, p_hash("indices")); + h = merge_p_hashes(h, HashType(tbl->GetIndices())); + h = merge_p_hashes(h, p_hash("tbl-yield")); + h = merge_p_hashes(h, HashType(tbl->Yield())); + } break; case TYPE_FUNC: - { - auto ft = t->AsFuncType(); - auto flv = ft->FlavorString(); - h = merge_p_hashes(h, p_hash(flv)); - h = merge_p_hashes(h, p_hash("params")); - h = merge_p_hashes(h, HashType(ft->Params())); - h = merge_p_hashes(h, p_hash("func-yield")); - h = merge_p_hashes(h, HashType(ft->Yield())); - } + { + auto ft = t->AsFuncType(); + auto flv = ft->FlavorString(); + h = merge_p_hashes(h, p_hash(flv)); + h = merge_p_hashes(h, p_hash("params")); + h = merge_p_hashes(h, HashType(ft->Params())); + h = merge_p_hashes(h, p_hash("func-yield")); + h = merge_p_hashes(h, HashType(ft->Yield())); + } break; case TYPE_LIST: - { - auto& tl = t->AsTypeList()->GetTypes(); + { + auto& tl = t->AsTypeList()->GetTypes(); - h = merge_p_hashes(h, p_hash("list")); - h = merge_p_hashes(h, p_hash(tl.size())); + h = merge_p_hashes(h, p_hash("list")); + h = merge_p_hashes(h, p_hash(tl.size())); - for ( const auto& tl_i : tl ) - h = merge_p_hashes(h, HashType(tl_i)); - } + for ( const auto& tl_i : tl ) + h = merge_p_hashes(h, HashType(tl_i)); + } break; case TYPE_VECTOR: diff --git a/src/script_opt/Reduce.cc b/src/script_opt/Reduce.cc index aded187fe4..63ad87f5af 100644 --- a/src/script_opt/Reduce.cc +++ b/src/script_opt/Reduce.cc @@ -272,81 +272,81 @@ bool Reducer::SameExpr(const Expr* e1, const Expr* e2) reporter->InternalError("Unexpected tag in Reducer::SameExpr"); case EXPR_ANY_INDEX: - { - auto a1 = e1->AsAnyIndexExpr(); - auto a2 = e2->AsAnyIndexExpr(); + { + auto a1 = e1->AsAnyIndexExpr(); + auto a2 = e2->AsAnyIndexExpr(); - if ( a1->Index() != a2->Index() ) - return false; + if ( a1->Index() != a2->Index() ) + return false; - return SameOp(a1->GetOp1(), a2->GetOp1()); - } + return SameOp(a1->GetOp1(), a2->GetOp1()); + } case EXPR_FIELD: - { - auto f1 = e1->AsFieldExpr(); - auto f2 = e2->AsFieldExpr(); + { + auto f1 = e1->AsFieldExpr(); + auto f2 = e2->AsFieldExpr(); - if ( f1->Field() != f2->Field() ) - return false; + if ( f1->Field() != f2->Field() ) + return false; - return SameOp(f1->GetOp1(), f2->GetOp1()); - } + return SameOp(f1->GetOp1(), f2->GetOp1()); + } case EXPR_HAS_FIELD: - { - auto f1 = e1->AsHasFieldExpr(); - auto f2 = e2->AsHasFieldExpr(); + { + auto f1 = e1->AsHasFieldExpr(); + auto f2 = e2->AsHasFieldExpr(); - if ( f1->Field() != f2->Field() ) - return false; + if ( f1->Field() != f2->Field() ) + return false; - return SameOp(f1->GetOp1(), f2->GetOp1()); - } + return SameOp(f1->GetOp1(), f2->GetOp1()); + } case EXPR_LIST: - { - auto l1 = e1->AsListExpr()->Exprs(); - auto l2 = e2->AsListExpr()->Exprs(); + { + auto l1 = e1->AsListExpr()->Exprs(); + auto l2 = e2->AsListExpr()->Exprs(); - ASSERT(l1.length() == l2.length()); + ASSERT(l1.length() == l2.length()); - for ( int i = 0; i < l1.length(); ++i ) - if ( ! SameExpr(l1[i], l2[i]) ) - return false; + for ( int i = 0; i < l1.length(); ++i ) + if ( ! SameExpr(l1[i], l2[i]) ) + return false; - return true; - } + return true; + } case EXPR_CALL: - { - auto c1 = e1->AsCallExpr(); - auto c2 = e2->AsCallExpr(); - auto f1 = c1->Func(); - auto f2 = c2->Func(); + { + auto c1 = e1->AsCallExpr(); + auto c2 = e2->AsCallExpr(); + auto f1 = c1->Func(); + auto f2 = c2->Func(); - if ( f1 != f2 ) - return false; + if ( f1 != f2 ) + return false; - if ( ! f1->IsPure() ) - return false; + if ( ! f1->IsPure() ) + return false; - return SameExpr(c1->Args(), c2->Args()); - } + return SameExpr(c1->Args(), c2->Args()); + } case EXPR_LAMBDA: return false; case EXPR_IS: - { - if ( ! SameOp(e1->GetOp1(), e2->GetOp1()) ) - return false; + { + if ( ! SameOp(e1->GetOp1(), e2->GetOp1()) ) + return false; - auto i1 = e1->AsIsExpr(); - auto i2 = e2->AsIsExpr(); + auto i1 = e1->AsIsExpr(); + auto i2 = e2->AsIsExpr(); - return same_type(i1->TestType(), i2->TestType()); - } + return same_type(i1->TestType(), i2->TestType()); + } default: if ( ! e1->GetOp1() ) @@ -865,59 +865,59 @@ TraversalCode CSE_ValidityChecker::PreExpr(const Expr* e) switch ( t ) { case EXPR_ASSIGN: + { + auto lhs_ref = e->GetOp1()->AsRefExprPtr(); + auto lhs = lhs_ref->GetOp1()->AsNameExpr(); + + if ( CheckID(ids, lhs->Id(), false) ) { - auto lhs_ref = e->GetOp1()->AsRefExprPtr(); - auto lhs = lhs_ref->GetOp1()->AsNameExpr(); - - if ( CheckID(ids, lhs->Id(), false) ) - { - is_valid = false; - return TC_ABORTALL; - } - - // Note, we don't use CheckAggrMod() because this - // is a plain assignment. It might be changing a variable's - // binding to an aggregate, but it's not changing the - // aggregate itself. + is_valid = false; + return TC_ABORTALL; } + + // Note, we don't use CheckAggrMod() because this + // is a plain assignment. It might be changing a variable's + // binding to an aggregate, but it's not changing the + // aggregate itself. + } break; case EXPR_INDEX_ASSIGN: - { - auto lhs_aggr = e->GetOp1(); - auto lhs_aggr_id = lhs_aggr->AsNameExpr()->Id(); + { + auto lhs_aggr = e->GetOp1(); + auto lhs_aggr_id = lhs_aggr->AsNameExpr()->Id(); - if ( CheckID(ids, lhs_aggr_id, true) || CheckAggrMod(ids, e) ) - { - is_valid = false; - return TC_ABORTALL; - } + if ( CheckID(ids, lhs_aggr_id, true) || CheckAggrMod(ids, e) ) + { + is_valid = false; + return TC_ABORTALL; } + } break; case EXPR_FIELD_LHS_ASSIGN: + { + auto lhs = e->GetOp1(); + auto lhs_aggr_id = lhs->AsNameExpr()->Id(); + auto lhs_field = e->AsFieldLHSAssignExpr()->Field(); + + if ( lhs_field == field && same_type(lhs_aggr_id->GetType(), field_type) ) { - auto lhs = e->GetOp1(); - auto lhs_aggr_id = lhs->AsNameExpr()->Id(); - auto lhs_field = e->AsFieldLHSAssignExpr()->Field(); - - if ( lhs_field == field && same_type(lhs_aggr_id->GetType(), field_type) ) - { - // Potential assignment to the same field as for - // our expression of interest. Even if the - // identifier involved is not one we have our eye - // on, due to aggregate aliasing this could be - // altering the value of our expression, so bail. - is_valid = false; - return TC_ABORTALL; - } - - if ( CheckID(ids, lhs_aggr_id, true) || CheckAggrMod(ids, e) ) - { - is_valid = false; - return TC_ABORTALL; - } + // Potential assignment to the same field as for + // our expression of interest. Even if the + // identifier involved is not one we have our eye + // on, due to aggregate aliasing this could be + // altering the value of our expression, so bail. + is_valid = false; + return TC_ABORTALL; } + + if ( CheckID(ids, lhs_aggr_id, true) || CheckAggrMod(ids, e) ) + { + is_valid = false; + return TC_ABORTALL; + } + } break; case EXPR_APPEND_TO: @@ -931,14 +931,14 @@ TraversalCode CSE_ValidityChecker::PreExpr(const Expr* e) break; case EXPR_CALL: - { - for ( auto i : ids ) - if ( i->IsGlobal() || IsAggr(i->GetType()) ) - { - is_valid = false; - return TC_ABORTALL; - } - } + { + for ( auto i : ids ) + if ( i->IsGlobal() || IsAggr(i->GetType()) ) + { + is_valid = false; + return TC_ABORTALL; + } + } break; default: diff --git a/src/script_opt/UseDefs.cc b/src/script_opt/UseDefs.cc index 909da1bbe8..de204cc558 100644 --- a/src/script_opt/UseDefs.cc +++ b/src/script_opt/UseDefs.cc @@ -185,40 +185,40 @@ UDs UseDefs::PropagateUDs(const Stmt* s, UDs succ_UDs, const Stmt* succ_stmt, bo switch ( s->Tag() ) { case STMT_LIST: + { + auto sl = s->AsStmtList(); + const auto& stmts = sl->Stmts(); + + for ( int i = stmts.length(); --i >= 0; ) { - auto sl = s->AsStmtList(); - const auto& stmts = sl->Stmts(); + auto s_i = stmts[i]; - for ( int i = stmts.length(); --i >= 0; ) - { - auto s_i = stmts[i]; + const Stmt* succ; - const Stmt* succ; - - if ( i == stmts.length() - 1 ) - { // Very last statement. - succ = succ_stmt; - if ( successor2.find(s) != successor2.end() ) - successor2[s_i] = successor2[s]; - } - else - succ = stmts[i + 1]; - - succ_UDs = PropagateUDs(s_i, succ_UDs, succ, second_pass); + if ( i == stmts.length() - 1 ) + { // Very last statement. + succ = succ_stmt; + if ( successor2.find(s) != successor2.end() ) + successor2[s_i] = successor2[s]; } + else + succ = stmts[i + 1]; - return UseUDs(s, succ_UDs); + succ_UDs = PropagateUDs(s_i, succ_UDs, succ, second_pass); } + return UseUDs(s, succ_UDs); + } + case STMT_CATCH_RETURN: - { - auto cr = s->AsCatchReturnStmt(); - auto block = cr->Block(); + { + auto cr = s->AsCatchReturnStmt(); + auto block = cr->Block(); - auto uds = PropagateUDs(block.get(), succ_UDs, succ_stmt, second_pass); + auto uds = PropagateUDs(block.get(), succ_UDs, succ_stmt, second_pass); - return UseUDs(s, uds); - } + return UseUDs(s, uds); + } case STMT_NULL: case STMT_NEXT: @@ -238,55 +238,55 @@ UDs UseDefs::PropagateUDs(const Stmt* s, UDs succ_UDs, const Stmt* succ_stmt, bo case STMT_ADD: case STMT_DELETE: case STMT_RETURN: - { - auto e = static_cast(s)->StmtExpr(); + { + auto e = static_cast(s)->StmtExpr(); - if ( e ) - return CreateExprUDs(s, e, succ_UDs); - else - return UseUDs(s, succ_UDs); - } + if ( e ) + return CreateExprUDs(s, e, succ_UDs); + else + return UseUDs(s, succ_UDs); + } case STMT_EXPR: - { - auto e = s->AsExprStmt()->StmtExpr(); + { + auto e = s->AsExprStmt()->StmtExpr(); - if ( e->Tag() != EXPR_ASSIGN ) - return CreateExprUDs(s, e, succ_UDs); + if ( e->Tag() != EXPR_ASSIGN ) + return CreateExprUDs(s, e, succ_UDs); - // Change in use-defs as here we have a definition. - auto a = e->AsAssignExpr(); - auto lhs_ref = a->GetOp1(); + // Change in use-defs as here we have a definition. + auto a = e->AsAssignExpr(); + auto lhs_ref = a->GetOp1(); - if ( lhs_ref->Tag() != EXPR_REF ) - // Since we're working on reduced form ... - reporter->InternalError("lhs inconsistency in UseDefs::ExprUDs"); + if ( lhs_ref->Tag() != EXPR_REF ) + // Since we're working on reduced form ... + reporter->InternalError("lhs inconsistency in UseDefs::ExprUDs"); - auto lhs_var = lhs_ref->GetOp1(); - auto lhs_id = lhs_var->AsNameExpr()->Id(); - auto lhs_UDs = RemoveID(lhs_id, succ_UDs); - auto rhs_UDs = ExprUDs(a->GetOp2().get()); - auto uds = UD_Union(lhs_UDs, rhs_UDs); + auto lhs_var = lhs_ref->GetOp1(); + auto lhs_id = lhs_var->AsNameExpr()->Id(); + auto lhs_UDs = RemoveID(lhs_id, succ_UDs); + auto rhs_UDs = ExprUDs(a->GetOp2().get()); + auto uds = UD_Union(lhs_UDs, rhs_UDs); - if ( ! second_pass ) - successor[s] = succ_stmt; + if ( ! second_pass ) + successor[s] = succ_stmt; - return CreateUDs(s, uds); - } + return CreateUDs(s, uds); + } case STMT_IF: - { - auto i = s->AsIfStmt(); - auto cond = i->StmtExpr(); + { + auto i = s->AsIfStmt(); + auto cond = i->StmtExpr(); - auto cond_UDs = ExprUDs(cond); - auto true_UDs = PropagateUDs(i->TrueBranch(), succ_UDs, succ_stmt, second_pass); - auto false_UDs = PropagateUDs(i->FalseBranch(), succ_UDs, succ_stmt, second_pass); + auto cond_UDs = ExprUDs(cond); + auto true_UDs = PropagateUDs(i->TrueBranch(), succ_UDs, succ_stmt, second_pass); + auto false_UDs = PropagateUDs(i->FalseBranch(), succ_UDs, succ_stmt, second_pass); - auto uds = CreateUDs(s, UD_Union(cond_UDs, true_UDs, false_UDs)); + auto uds = CreateUDs(s, UD_Union(cond_UDs, true_UDs, false_UDs)); - return uds; - } + return uds; + } case STMT_INIT: if ( ! second_pass ) @@ -304,112 +304,112 @@ UDs UseDefs::PropagateUDs(const Stmt* s, UDs succ_UDs, const Stmt* succ_stmt, bo return UseUDs(s, succ_UDs); case STMT_SWITCH: + { + auto sw_UDs = std::make_shared(); + + auto sw = s->AsSwitchStmt(); + auto cases = sw->Cases(); + + for ( const auto& c : *cases ) { - auto sw_UDs = std::make_shared(); + auto body = c->Body(); + auto uds = PropagateUDs(body, succ_UDs, succ_stmt, second_pass); - auto sw = s->AsSwitchStmt(); - auto cases = sw->Cases(); - - for ( const auto& c : *cases ) + auto exprs = c->ExprCases(); + if ( exprs ) { - auto body = c->Body(); - auto uds = PropagateUDs(body, succ_UDs, succ_stmt, second_pass); - - auto exprs = c->ExprCases(); - if ( exprs ) - { - auto e_UDs = ExprUDs(exprs); - uds = UD_Union(uds, e_UDs); - } - - auto type_ids = c->TypeCases(); - if ( type_ids ) - for ( const auto& id : *type_ids ) - uds = RemoveID(id, uds); - - FoldInUDs(sw_UDs, uds); + auto e_UDs = ExprUDs(exprs); + uds = UD_Union(uds, e_UDs); } - auto e_UDs = ExprUDs(sw->StmtExpr()); + auto type_ids = c->TypeCases(); + if ( type_ids ) + for ( const auto& id : *type_ids ) + uds = RemoveID(id, uds); - if ( sw->HasDefault() ) - FoldInUDs(sw_UDs, e_UDs); - else - // keep successor definitions in the mix - FoldInUDs(sw_UDs, succ_UDs, e_UDs); - - return CreateUDs(s, sw_UDs); + FoldInUDs(sw_UDs, uds); } + auto e_UDs = ExprUDs(sw->StmtExpr()); + + if ( sw->HasDefault() ) + FoldInUDs(sw_UDs, e_UDs); + else + // keep successor definitions in the mix + FoldInUDs(sw_UDs, succ_UDs, e_UDs); + + return CreateUDs(s, sw_UDs); + } + case STMT_FOR: - { - auto f = s->AsForStmt(); - auto body = f->LoopBody(); + { + auto f = s->AsForStmt(); + auto body = f->LoopBody(); - // The loop body has two potential successors, itself - // and the successor of the entire "for" statement. - successor2[body] = succ_stmt; - auto body_UDs = PropagateUDs(body, succ_UDs, body, second_pass); + // The loop body has two potential successors, itself + // and the successor of the entire "for" statement. + successor2[body] = succ_stmt; + auto body_UDs = PropagateUDs(body, succ_UDs, body, second_pass); - auto e = f->LoopExpr(); - auto f_UDs = ExprUDs(e); - FoldInUDs(f_UDs, body_UDs); + auto e = f->LoopExpr(); + auto f_UDs = ExprUDs(e); + FoldInUDs(f_UDs, body_UDs); - // Confluence: loop the top UDs back around to the bottom. - auto bottom_UDs = UD_Union(f_UDs, succ_UDs); - (void)PropagateUDs(body, bottom_UDs, body, true); + // Confluence: loop the top UDs back around to the bottom. + auto bottom_UDs = UD_Union(f_UDs, succ_UDs); + (void)PropagateUDs(body, bottom_UDs, body, true); - auto ids = f->LoopVars(); - for ( const auto& id : *ids ) - RemoveUDFrom(f_UDs, id); + auto ids = f->LoopVars(); + for ( const auto& id : *ids ) + RemoveUDFrom(f_UDs, id); - auto val_var = f->ValueVar(); - if ( val_var ) - RemoveUDFrom(f_UDs, val_var.get()); + auto val_var = f->ValueVar(); + if ( val_var ) + RemoveUDFrom(f_UDs, val_var.get()); - // The loop might not execute at all. - FoldInUDs(f_UDs, succ_UDs); + // The loop might not execute at all. + FoldInUDs(f_UDs, succ_UDs); - return CreateUDs(s, f_UDs); - } + return CreateUDs(s, f_UDs); + } case STMT_WHILE: + { + auto w = s->AsWhileStmt(); + auto body = w->Body(); + auto cond_stmt = w->CondPredStmt(); + + // See note above for STMT_FOR regarding propagating + // around the loop. + auto succ = cond_stmt ? cond_stmt : body; + successor2[body.get()] = succ_stmt; + auto body_UDs = PropagateUDs(body.get(), succ_UDs, succ.get(), second_pass); + + const auto& cond = w->Condition(); + auto w_UDs = UD_Union(ExprUDs(cond.get()), body_UDs); + FoldInUDs(w_UDs, body_UDs); + + if ( cond_stmt ) { - auto w = s->AsWhileStmt(); - auto body = w->Body(); - auto cond_stmt = w->CondPredStmt(); + // Create a successor for the cond_stmt + // that has the correct UDs associated with it. + const auto& c_as_s = w->ConditionAsStmt(); + auto c_as_s_UDs = std::make_shared(w_UDs); + CreateUDs(c_as_s.get(), c_as_s_UDs); - // See note above for STMT_FOR regarding propagating - // around the loop. - auto succ = cond_stmt ? cond_stmt : body; - successor2[body.get()] = succ_stmt; - auto body_UDs = PropagateUDs(body.get(), succ_UDs, succ.get(), second_pass); - - const auto& cond = w->Condition(); - auto w_UDs = UD_Union(ExprUDs(cond.get()), body_UDs); - FoldInUDs(w_UDs, body_UDs); - - if ( cond_stmt ) - { - // Create a successor for the cond_stmt - // that has the correct UDs associated with it. - const auto& c_as_s = w->ConditionAsStmt(); - auto c_as_s_UDs = std::make_shared(w_UDs); - CreateUDs(c_as_s.get(), c_as_s_UDs); - - w_UDs = PropagateUDs(cond_stmt, w_UDs, c_as_s, second_pass); - } - - // Confluence: loop the top UDs back around to the bottom. - auto bottom_UDs = UD_Union(w_UDs, succ_UDs); - (void)PropagateUDs(body, bottom_UDs, succ, true); - - // The loop might not execute at all. - FoldInUDs(w_UDs, succ_UDs); - - return CreateUDs(s, w_UDs); + w_UDs = PropagateUDs(cond_stmt, w_UDs, c_as_s, second_pass); } + // Confluence: loop the top UDs back around to the bottom. + auto bottom_UDs = UD_Union(w_UDs, succ_UDs); + (void)PropagateUDs(body, bottom_UDs, succ, true); + + // The loop might not execute at all. + FoldInUDs(w_UDs, succ_UDs); + + return CreateUDs(s, w_UDs); + } + default: reporter->InternalError("non-reduced statement in use-def analysis"); } @@ -454,12 +454,12 @@ UDs UseDefs::ExprUDs(const Expr* e) break; case EXPR_FIELD_LHS_ASSIGN: - { - AddInExprUDs(uds, e->GetOp1().get()); - auto rhs_UDs = ExprUDs(e->GetOp2().get()); - uds = UD_Union(uds, rhs_UDs); - break; - } + { + AddInExprUDs(uds, e->GetOp1().get()); + auto rhs_UDs = ExprUDs(e->GetOp2().get()); + uds = UD_Union(uds, rhs_UDs); + break; + } case EXPR_INCR: case EXPR_DECR: @@ -467,41 +467,41 @@ UDs UseDefs::ExprUDs(const Expr* e) break; case EXPR_RECORD_CONSTRUCTOR: - { - auto r = static_cast(e); - AddInExprUDs(uds, r->Op().get()); - break; - } + { + auto r = static_cast(e); + AddInExprUDs(uds, r->Op().get()); + break; + } case EXPR_CONST: break; case EXPR_LAMBDA: - { - auto l = static_cast(e); - auto ids = l->OuterIDs(); + { + auto l = static_cast(e); + auto ids = l->OuterIDs(); - for ( const auto& id : ids ) - AddID(uds, id); - break; - } + for ( const auto& id : ids ) + AddID(uds, id); + break; + } case EXPR_CALL: - { - auto c = e->AsCallExpr(); - AddInExprUDs(uds, c->Func()); - AddInExprUDs(uds, c->Args()); - break; - } + { + auto c = e->AsCallExpr(); + AddInExprUDs(uds, c->Func()); + AddInExprUDs(uds, c->Args()); + break; + } case EXPR_LIST: - { - auto l = e->AsListExpr(); - for ( const auto& l_e : l->Exprs() ) - AddInExprUDs(uds, l_e); + { + auto l = e->AsListExpr(); + for ( const auto& l_e : l->Exprs() ) + AddInExprUDs(uds, l_e); - break; - } + break; + } default: auto op1 = e->GetOp1(); @@ -532,11 +532,11 @@ void UseDefs::AddInExprUDs(UDs uds, const Expr* e) break; case EXPR_LIST: - { - auto l = e->AsListExpr(); - for ( const auto& l_e : l->Exprs() ) - AddInExprUDs(uds, l_e); - } + { + auto l = e->AsListExpr(); + for ( const auto& l_e : l->Exprs() ) + AddInExprUDs(uds, l_e); + } break; case EXPR_EVENT: diff --git a/src/script_opt/ZAM/AM-Opt.cc b/src/script_opt/ZAM/AM-Opt.cc index b2ad28bc51..5af22bee01 100644 --- a/src/script_opt/ZAM/AM-Opt.cc +++ b/src/script_opt/ZAM/AM-Opt.cc @@ -362,43 +362,43 @@ void ZAMCompiler::ComputeFrameLifetimes() { case OP_NEXT_TABLE_ITER_VV: case OP_NEXT_TABLE_ITER_VAL_VAR_VVV: + { + // These assign to an arbitrary long list of variables. + auto& iter_vars = inst->aux->loop_vars; + auto depth = inst->loop_depth; + + for ( auto v : iter_vars ) { - // These assign to an arbitrary long list of variables. - auto& iter_vars = inst->aux->loop_vars; - auto depth = inst->loop_depth; + CheckSlotAssignment(v, inst); - for ( auto v : iter_vars ) - { - CheckSlotAssignment(v, inst); - - // Also mark it as usage throughout the - // loop. Otherwise, we risk pruning the - // variable if it happens to not be used - // (which will mess up the iteration logic) - // or doubling it up with some other value - // inside the loop (which will fail when - // the loop var has memory management - // associated with it). - ExtendLifetime(v, EndOfLoop(inst, depth)); - } - - // No need to check the additional "var" associated - // with OP_NEXT_TABLE_ITER_VAL_VAR_VVV as that's - // a slot-1 assignment. However, similar to other - // loop variables, mark this as a usage. - if ( inst->op == OP_NEXT_TABLE_ITER_VAL_VAR_VVV ) - ExtendLifetime(inst->v1, EndOfLoop(inst, depth)); + // Also mark it as usage throughout the + // loop. Otherwise, we risk pruning the + // variable if it happens to not be used + // (which will mess up the iteration logic) + // or doubling it up with some other value + // inside the loop (which will fail when + // the loop var has memory management + // associated with it). + ExtendLifetime(v, EndOfLoop(inst, depth)); } + + // No need to check the additional "var" associated + // with OP_NEXT_TABLE_ITER_VAL_VAR_VVV as that's + // a slot-1 assignment. However, similar to other + // loop variables, mark this as a usage. + if ( inst->op == OP_NEXT_TABLE_ITER_VAL_VAR_VVV ) + ExtendLifetime(inst->v1, EndOfLoop(inst, depth)); + } break; case OP_NEXT_TABLE_ITER_NO_VARS_VV: break; case OP_NEXT_TABLE_ITER_VAL_VAR_NO_VARS_VVV: - { - auto depth = inst->loop_depth; - ExtendLifetime(inst->v1, EndOfLoop(inst, depth)); - } + { + auto depth = inst->loop_depth; + ExtendLifetime(inst->v1, EndOfLoop(inst, depth)); + } break; case OP_NEXT_VECTOR_ITER_VVV: @@ -417,30 +417,30 @@ void ZAMCompiler::ComputeFrameLifetimes() case OP_INIT_TABLE_LOOP_VV: case OP_INIT_VECTOR_LOOP_VV: case OP_INIT_STRING_LOOP_VV: - { - // For all of these, the scope of the aggregate being - // looped over is the entire loop, even if it doesn't - // directly appear in it, and not just the initializer. - // For all three, the aggregate is in v1. - ASSERT(i < insts1.size() - 1); - auto succ = insts1[i + 1]; - ASSERT(succ->live); - auto depth = succ->loop_depth; - ExtendLifetime(inst->v1, EndOfLoop(succ, depth)); + { + // For all of these, the scope of the aggregate being + // looped over is the entire loop, even if it doesn't + // directly appear in it, and not just the initializer. + // For all three, the aggregate is in v1. + ASSERT(i < insts1.size() - 1); + auto succ = insts1[i + 1]; + ASSERT(succ->live); + auto depth = succ->loop_depth; + ExtendLifetime(inst->v1, EndOfLoop(succ, depth)); - // Important: we skip the usual UsesSlots analysis - // below since we've already set it, and don't want - // to perturb ExtendLifetime's consistency check. - continue; - } + // Important: we skip the usual UsesSlots analysis + // below since we've already set it, and don't want + // to perturb ExtendLifetime's consistency check. + continue; + } case OP_STORE_GLOBAL_V: - { - // Use of the global goes to here. - auto slot = frame_layout1[globalsI[inst->v1].id.get()]; - ExtendLifetime(slot, EndOfLoop(inst, 1)); - break; - } + { + // Use of the global goes to here. + auto slot = frame_layout1[globalsI[inst->v1].id.get()]; + ExtendLifetime(slot, EndOfLoop(inst, 1)); + break; + } default: // Look for slots in auxiliary information. @@ -559,15 +559,15 @@ void ZAMCompiler::ReMapFrame() { case OP_NEXT_TABLE_ITER_VV: case OP_NEXT_TABLE_ITER_VAL_VAR_VVV: + { + // Rewrite iteration variables. + auto& iter_vars = inst->aux->loop_vars; + for ( auto& v : iter_vars ) { - // Rewrite iteration variables. - auto& iter_vars = inst->aux->loop_vars; - for ( auto& v : iter_vars ) - { - ASSERT(v >= 0 && v < n1_slots); - v = frame1_to_frame2[v]; - } + ASSERT(v >= 0 && v < n1_slots); + v = frame1_to_frame2[v]; } + } break; default: diff --git a/src/script_opt/ZAM/Expr.cc b/src/script_opt/ZAM/Expr.cc index 35bdbd4a4f..41309849a0 100644 --- a/src/script_opt/ZAM/Expr.cc +++ b/src/script_opt/ZAM/Expr.cc @@ -24,32 +24,32 @@ const ZAMStmt ZAMCompiler::CompileExpr(const Expr* e) return CompileAssignExpr(static_cast(e)); case EXPR_INDEX_ASSIGN: - { - auto iae = static_cast(e); - auto t = iae->GetOp1()->GetType()->Tag(); - if ( t == TYPE_VECTOR ) - return AssignVecElems(iae); + { + auto iae = static_cast(e); + auto t = iae->GetOp1()->GetType()->Tag(); + if ( t == TYPE_VECTOR ) + return AssignVecElems(iae); - ASSERT(t == TYPE_TABLE); - return AssignTableElem(iae); - } + ASSERT(t == TYPE_TABLE); + return AssignTableElem(iae); + } case EXPR_FIELD_LHS_ASSIGN: - { - auto flhs = static_cast(e); - return CompileFieldLHSAssignExpr(flhs); - } + { + auto flhs = static_cast(e); + return CompileFieldLHSAssignExpr(flhs); + } case EXPR_SCHEDULE: return CompileScheduleExpr(static_cast(e)); case EXPR_EVENT: - { - auto ee = static_cast(e); - auto h = ee->Handler().Ptr(); - auto args = ee->Args(); - return EventHL(h, args); - } + { + auto ee = static_cast(e); + auto h = ee->Handler().Ptr(); + auto args = ee->Args(); + return EventHL(h, args); + } default: reporter->InternalError("bad statement type in ZAMCompile::CompileExpr"); @@ -1111,31 +1111,31 @@ const ZAMStmt ZAMCompiler::ArithCoerce(const NameExpr* n, const Expr* e) switch ( targ_it ) { case TYPE_INTERNAL_DOUBLE: - { - if ( op_it == TYPE_INTERNAL_INT ) - a = nt_is_vec ? OP_COERCE_DI_VEC_VV : OP_COERCE_DI_VV; - else - a = nt_is_vec ? OP_COERCE_DU_VEC_VV : OP_COERCE_DU_VV; - break; - } + { + if ( op_it == TYPE_INTERNAL_INT ) + a = nt_is_vec ? OP_COERCE_DI_VEC_VV : OP_COERCE_DI_VV; + else + a = nt_is_vec ? OP_COERCE_DU_VEC_VV : OP_COERCE_DU_VV; + break; + } case TYPE_INTERNAL_INT: - { - if ( op_it == TYPE_INTERNAL_UNSIGNED ) - a = nt_is_vec ? OP_COERCE_IU_VEC_VV : OP_COERCE_IU_VV; - else - a = nt_is_vec ? OP_COERCE_ID_VEC_VV : OP_COERCE_ID_VV; - break; - } + { + if ( op_it == TYPE_INTERNAL_UNSIGNED ) + a = nt_is_vec ? OP_COERCE_IU_VEC_VV : OP_COERCE_IU_VV; + else + a = nt_is_vec ? OP_COERCE_ID_VEC_VV : OP_COERCE_ID_VV; + break; + } case TYPE_INTERNAL_UNSIGNED: - { - if ( op_it == TYPE_INTERNAL_INT ) - a = nt_is_vec ? OP_COERCE_UI_VEC_VV : OP_COERCE_UI_VV; - else - a = nt_is_vec ? OP_COERCE_UD_VEC_VV : OP_COERCE_UD_VV; - break; - } + { + if ( op_it == TYPE_INTERNAL_INT ) + a = nt_is_vec ? OP_COERCE_UI_VEC_VV : OP_COERCE_UI_VV; + else + a = nt_is_vec ? OP_COERCE_UD_VEC_VV : OP_COERCE_UD_VV; + break; + } default: reporter->InternalError("bad target internal type in coercion"); diff --git a/src/script_opt/ZAM/Gen-ZAM.cc b/src/script_opt/ZAM/Gen-ZAM.cc index 40b8b9a820..f81e74b7bc 100644 --- a/src/script_opt/ZAM/Gen-ZAM.cc +++ b/src/script_opt/ZAM/Gen-ZAM.cc @@ -81,11 +81,11 @@ string find_type_accessor(ZAM_ExprType et) return "re_val"; default: - { - string acc = find_type_info(et).accessor; - transform(acc.begin(), acc.end(), acc.begin(), ::tolower); - return acc + "_val"; - } + { + string acc = find_type_info(et).accessor; + transform(acc.begin(), acc.end(), acc.begin(), ::tolower); + return acc + "_val"; + } } } diff --git a/src/script_opt/ZAM/Stmt.cc b/src/script_opt/ZAM/Stmt.cc index 14440537cf..01fbc3bcf7 100644 --- a/src/script_opt/ZAM/Stmt.cc +++ b/src/script_opt/ZAM/Stmt.cc @@ -36,11 +36,11 @@ const ZAMStmt ZAMCompiler::CompileStmt(const Stmt* s) return CompileDel(static_cast(s)); case STMT_EVENT: - { - auto es = static_cast(s); - auto e = static_cast(es->StmtExpr()); - return CompileExpr(e); - } + { + auto es = static_cast(s); + auto e = static_cast(es->StmtExpr()); + return CompileExpr(e); + } case STMT_WHILE: return CompileWhile(static_cast(s)); @@ -67,12 +67,12 @@ const ZAMStmt ZAMCompiler::CompileStmt(const Stmt* s) return CompileWhen(static_cast(s)); case STMT_CHECK_ANY_LEN: - { - auto cs = static_cast(s); - auto n = cs->StmtExpr()->AsNameExpr(); - auto expected_len = cs->ExpectedLen(); - return CheckAnyLenVi(n, expected_len); - } + { + auto cs = static_cast(s); + auto n = cs->StmtExpr()->AsNameExpr(); + auto expected_len = cs->ExpectedLen(); + return CheckAnyLenVi(n, expected_len); + } case STMT_NEXT: return CompileNext(); @@ -520,29 +520,29 @@ const ZAMStmt ZAMCompiler::ValueSwitch(const SwitchStmt* sw, const NameExpr* v, break; case TYPE_INTERNAL_STRING: - { - // This leaks, but only statically so not worth - // tracking the value for ultimate deletion. - auto sv = cv->AsString()->Render(); - std::string s(sv); - new_str_cases[s] = case_body_start; - delete[] sv; - break; - } + { + // This leaks, but only statically so not worth + // tracking the value for ultimate deletion. + auto sv = cv->AsString()->Render(); + std::string s(sv); + new_str_cases[s] = case_body_start; + delete[] sv; + break; + } case TYPE_INTERNAL_ADDR: - { - auto a = cv->AsAddr().AsString(); - new_str_cases[a] = case_body_start; - break; - } + { + auto a = cv->AsAddr().AsString(); + new_str_cases[a] = case_body_start; + break; + } case TYPE_INTERNAL_SUBNET: - { - auto n = cv->AsSubNet().AsString(); - new_str_cases[n] = case_body_start; - break; - } + { + auto n = cv->AsSubNet().AsString(); + new_str_cases[n] = case_body_start; + break; + } default: reporter->InternalError("bad recovered type when compiling switch"); diff --git a/src/threading/SerialTypes.cc b/src/threading/SerialTypes.cc index 6e8c89d915..a68640bc2f 100644 --- a/src/threading/SerialTypes.cc +++ b/src/threading/SerialTypes.cc @@ -144,23 +144,23 @@ bool Value::IsCompatibleType(Type* t, bool atomic_only) return ! atomic_only; case TYPE_TABLE: - { - if ( atomic_only ) - return false; + { + if ( atomic_only ) + return false; - if ( ! t->IsSet() ) - return false; + if ( ! t->IsSet() ) + return false; - return IsCompatibleType(t->AsSetType()->GetIndices()->GetPureType().get(), true); - } + return IsCompatibleType(t->AsSetType()->GetIndices()->GetPureType().get(), true); + } case TYPE_VECTOR: - { - if ( atomic_only ) - return false; + { + if ( atomic_only ) + return false; - return IsCompatibleType(t->AsVectorType()->Yield().get(), true); - } + return IsCompatibleType(t->AsVectorType()->Yield().get(), true); + } default: return false; @@ -193,81 +193,81 @@ bool Value::Read(detail::SerializationFormat* fmt) return fmt->Read(&val.uint_val, "uint"); case TYPE_PORT: + { + int proto; + if ( ! (fmt->Read(&val.port_val.port, "port") && fmt->Read(&proto, "proto")) ) { - int proto; - if ( ! (fmt->Read(&val.port_val.port, "port") && fmt->Read(&proto, "proto")) ) - { - return false; - } - - switch ( proto ) - { - case 0: - val.port_val.proto = TRANSPORT_UNKNOWN; - break; - case 1: - val.port_val.proto = TRANSPORT_TCP; - break; - case 2: - val.port_val.proto = TRANSPORT_UDP; - break; - case 3: - val.port_val.proto = TRANSPORT_ICMP; - break; - default: - return false; - } - - return true; + return false; } + switch ( proto ) + { + case 0: + val.port_val.proto = TRANSPORT_UNKNOWN; + break; + case 1: + val.port_val.proto = TRANSPORT_TCP; + break; + case 2: + val.port_val.proto = TRANSPORT_UDP; + break; + case 3: + val.port_val.proto = TRANSPORT_ICMP; + break; + default: + return false; + } + + return true; + } + case TYPE_ADDR: + { + char family; + + if ( ! fmt->Read(&family, "addr-family") ) + return false; + + switch ( family ) { - char family; + case 4: + val.addr_val.family = IPv4; + return fmt->Read(&val.addr_val.in.in4, "addr-in4"); - if ( ! fmt->Read(&family, "addr-family") ) - return false; - - switch ( family ) - { - case 4: - val.addr_val.family = IPv4; - return fmt->Read(&val.addr_val.in.in4, "addr-in4"); - - case 6: - val.addr_val.family = IPv6; - return fmt->Read(&val.addr_val.in.in6, "addr-in6"); - } - - // Can't be reached. - abort(); + case 6: + val.addr_val.family = IPv6; + return fmt->Read(&val.addr_val.in.in6, "addr-in6"); } + // Can't be reached. + abort(); + } + case TYPE_SUBNET: + { + char length; + char family; + + if ( ! (fmt->Read(&length, "subnet-len") && fmt->Read(&family, "subnet-family")) ) + return false; + + switch ( family ) { - char length; - char family; + case 4: + val.subnet_val.length = (uint8_t)length; + val.subnet_val.prefix.family = IPv4; + return fmt->Read(&val.subnet_val.prefix.in.in4, "subnet-in4"); - if ( ! (fmt->Read(&length, "subnet-len") && fmt->Read(&family, "subnet-family")) ) - return false; - - switch ( family ) - { - case 4: - val.subnet_val.length = (uint8_t)length; - val.subnet_val.prefix.family = IPv4; - return fmt->Read(&val.subnet_val.prefix.in.in4, "subnet-in4"); - - case 6: - val.subnet_val.length = (uint8_t)length; - val.subnet_val.prefix.family = IPv6; - return fmt->Read(&val.subnet_val.prefix.in.in6, "subnet-in6"); - } - - // Can't be reached. - abort(); + case 6: + val.subnet_val.length = (uint8_t)length; + val.subnet_val.prefix.family = IPv6; + return fmt->Read(&val.subnet_val.prefix.in.in6, "subnet-in6"); } + // Can't be reached. + abort(); + } + case TYPE_DOUBLE: case TYPE_TIME: case TYPE_INTERVAL: @@ -280,41 +280,41 @@ bool Value::Read(detail::SerializationFormat* fmt) return fmt->Read(&val.string_val.data, &val.string_val.length, "string"); case TYPE_TABLE: + { + if ( ! fmt->Read(&val.set_val.size, "set_size") ) + return false; + + val.set_val.vals = new Value*[val.set_val.size]; + + for ( bro_int_t i = 0; i < val.set_val.size; ++i ) { - if ( ! fmt->Read(&val.set_val.size, "set_size") ) + val.set_val.vals[i] = new Value; + + if ( ! val.set_val.vals[i]->Read(fmt) ) return false; - - val.set_val.vals = new Value*[val.set_val.size]; - - for ( bro_int_t i = 0; i < val.set_val.size; ++i ) - { - val.set_val.vals[i] = new Value; - - if ( ! val.set_val.vals[i]->Read(fmt) ) - return false; - } - - return true; } + return true; + } + case TYPE_VECTOR: + { + if ( ! fmt->Read(&val.vector_val.size, "vector_size") ) + return false; + + val.vector_val.vals = new Value*[val.vector_val.size]; + + for ( bro_int_t i = 0; i < val.vector_val.size; ++i ) { - if ( ! fmt->Read(&val.vector_val.size, "vector_size") ) + val.vector_val.vals[i] = new Value; + + if ( ! val.vector_val.vals[i]->Read(fmt) ) return false; - - val.vector_val.vals = new Value*[val.vector_val.size]; - - for ( bro_int_t i = 0; i < val.vector_val.size; ++i ) - { - val.vector_val.vals[i] = new Value; - - if ( ! val.vector_val.vals[i]->Read(fmt) ) - return false; - } - - return true; } + return true; + } + default: reporter->InternalError("unsupported type %s in Value::Read", type_name(type)); } @@ -344,42 +344,42 @@ bool Value::Write(detail::SerializationFormat* fmt) const return fmt->Write(val.port_val.port, "port") && fmt->Write(val.port_val.proto, "proto"); case TYPE_ADDR: + { + switch ( val.addr_val.family ) { - switch ( val.addr_val.family ) - { - case IPv4: - return fmt->Write((char)4, "addr-family") && - fmt->Write(val.addr_val.in.in4, "addr-in4"); + case IPv4: + return fmt->Write((char)4, "addr-family") && + fmt->Write(val.addr_val.in.in4, "addr-in4"); - case IPv6: - return fmt->Write((char)6, "addr-family") && - fmt->Write(val.addr_val.in.in6, "addr-in6"); - } - - // Can't be reached. - abort(); + case IPv6: + return fmt->Write((char)6, "addr-family") && + fmt->Write(val.addr_val.in.in6, "addr-in6"); } + // Can't be reached. + abort(); + } + case TYPE_SUBNET: + { + if ( ! fmt->Write((char)val.subnet_val.length, "subnet-length") ) + return false; + + switch ( val.subnet_val.prefix.family ) { - if ( ! fmt->Write((char)val.subnet_val.length, "subnet-length") ) - return false; + case IPv4: + return fmt->Write((char)4, "subnet-family") && + fmt->Write(val.subnet_val.prefix.in.in4, "subnet-in4"); - switch ( val.subnet_val.prefix.family ) - { - case IPv4: - return fmt->Write((char)4, "subnet-family") && - fmt->Write(val.subnet_val.prefix.in.in4, "subnet-in4"); - - case IPv6: - return fmt->Write((char)6, "subnet-family") && - fmt->Write(val.subnet_val.prefix.in.in6, "subnet-in6"); - } - - // Can't be reached. - abort(); + case IPv6: + return fmt->Write((char)6, "subnet-family") && + fmt->Write(val.subnet_val.prefix.in.in6, "subnet-in6"); } + // Can't be reached. + abort(); + } + case TYPE_DOUBLE: case TYPE_TIME: case TYPE_INTERVAL: @@ -392,33 +392,33 @@ bool Value::Write(detail::SerializationFormat* fmt) const return fmt->Write(val.string_val.data, val.string_val.length, "string"); case TYPE_TABLE: + { + if ( ! fmt->Write(val.set_val.size, "set_size") ) + return false; + + for ( int i = 0; i < val.set_val.size; ++i ) { - if ( ! fmt->Write(val.set_val.size, "set_size") ) + if ( ! val.set_val.vals[i]->Write(fmt) ) return false; - - for ( int i = 0; i < val.set_val.size; ++i ) - { - if ( ! val.set_val.vals[i]->Write(fmt) ) - return false; - } - - return true; } + return true; + } + case TYPE_VECTOR: + { + if ( ! fmt->Write(val.vector_val.size, "vector_size") ) + return false; + + for ( int i = 0; i < val.vector_val.size; ++i ) { - if ( ! fmt->Write(val.vector_val.size, "vector_size") ) + if ( ! val.vector_val.vals[i]->Write(fmt) ) return false; - - for ( int i = 0; i < val.vector_val.size; ++i ) - { - if ( ! val.vector_val.vals[i]->Write(fmt) ) - return false; - } - - return true; } + return true; + } + default: reporter->InternalError("unsupported type %s in Value::Write", type_name(type)); } @@ -464,204 +464,204 @@ Val* Value::ValueToVal(const std::string& source, const Value* val, bool& have_e return new IntervalVal(val->val.double_val); case TYPE_STRING: - { - auto* s = new String((const u_char*)val->val.string_val.data, - val->val.string_val.length, true); - return new StringVal(s); - } + { + auto* s = new String((const u_char*)val->val.string_val.data, + val->val.string_val.length, true); + return new StringVal(s); + } case TYPE_PORT: return val_mgr->Port(val->val.port_val.port, val->val.port_val.proto)->Ref(); case TYPE_ADDR: + { + IPAddr* addr = nullptr; + switch ( val->val.addr_val.family ) { - IPAddr* addr = nullptr; - switch ( val->val.addr_val.family ) - { - case IPv4: - addr = new IPAddr(val->val.addr_val.in.in4); - break; + case IPv4: + addr = new IPAddr(val->val.addr_val.in.in4); + break; - case IPv6: - addr = new IPAddr(val->val.addr_val.in.in6); - break; + case IPv6: + addr = new IPAddr(val->val.addr_val.in.in6); + break; - default: - assert(false); - } - - auto* addrval = new AddrVal(*addr); - delete addr; - return addrval; + default: + assert(false); } + auto* addrval = new AddrVal(*addr); + delete addr; + return addrval; + } + case TYPE_SUBNET: + { + IPAddr* addr = nullptr; + switch ( val->val.subnet_val.prefix.family ) { - IPAddr* addr = nullptr; - switch ( val->val.subnet_val.prefix.family ) - { - case IPv4: - addr = new IPAddr(val->val.subnet_val.prefix.in.in4); - break; + case IPv4: + addr = new IPAddr(val->val.subnet_val.prefix.in.in4); + break; - case IPv6: - addr = new IPAddr(val->val.subnet_val.prefix.in.in6); - break; + case IPv6: + addr = new IPAddr(val->val.subnet_val.prefix.in.in6); + break; - default: - assert(false); - } - - auto* subnetval = new SubNetVal(*addr, val->val.subnet_val.length); - delete addr; - return subnetval; + default: + assert(false); } + auto* subnetval = new SubNetVal(*addr, val->val.subnet_val.length); + delete addr; + return subnetval; + } + case TYPE_PATTERN: - { - auto* re = new RE_Matcher(val->val.pattern_text_val); - re->Compile(); - return new PatternVal(re); - } + { + auto* re = new RE_Matcher(val->val.pattern_text_val); + re->Compile(); + return new PatternVal(re); + } case TYPE_TABLE: + { + TypeListPtr set_index; + if ( val->val.set_val.size == 0 && + (val->subtype == TYPE_VOID || val->subtype == TYPE_ENUM) ) + // don't know type - unspecified table. + set_index = make_intrusive(); + else { - TypeListPtr set_index; - if ( val->val.set_val.size == 0 && - (val->subtype == TYPE_VOID || val->subtype == TYPE_ENUM) ) - // don't know type - unspecified table. - set_index = make_intrusive(); - else + // all entries have to have the same type... + TypeTag stag = val->subtype; + if ( stag == TYPE_VOID ) + stag = val->val.set_val.vals[0]->type; + + TypePtr index_type; + + if ( stag == TYPE_ENUM ) { - // all entries have to have the same type... - TypeTag stag = val->subtype; - if ( stag == TYPE_VOID ) - stag = val->val.set_val.vals[0]->type; + // Enums are not a base-type, so need to look it up. + const auto& sv = val->val.set_val.vals[0]->val.string_val; + std::string enum_name(sv.data, sv.length); + const auto& enum_id = detail::global_scope()->Find(enum_name); - TypePtr index_type; - - if ( stag == TYPE_ENUM ) + if ( ! enum_id ) { - // Enums are not a base-type, so need to look it up. - const auto& sv = val->val.set_val.vals[0]->val.string_val; - std::string enum_name(sv.data, sv.length); - const auto& enum_id = detail::global_scope()->Find(enum_name); + reporter->Warning("Value '%s' of source '%s' is not a valid enum.", + enum_name.data(), source.c_str()); - if ( ! enum_id ) - { - reporter->Warning("Value '%s' of source '%s' is not a valid enum.", - enum_name.data(), source.c_str()); - - have_error = true; - return nullptr; - } - - index_type = enum_id->GetType(); - } - else - index_type = base_type(stag); - - set_index = make_intrusive(index_type); - set_index->Append(std::move(index_type)); - } - - auto s = make_intrusive(std::move(set_index), nullptr); - auto t = make_intrusive(std::move(s)); - for ( int j = 0; j < val->val.set_val.size; j++ ) - { - Val* assignval = ValueToVal(source, val->val.set_val.vals[j], have_error); - if ( have_error ) + have_error = true; return nullptr; + } - t->Assign({AdoptRef{}, assignval}, nullptr); + index_type = enum_id->GetType(); } + else + index_type = base_type(stag); - return t.release(); + set_index = make_intrusive(index_type); + set_index->Append(std::move(index_type)); } + auto s = make_intrusive(std::move(set_index), nullptr); + auto t = make_intrusive(std::move(s)); + for ( int j = 0; j < val->val.set_val.size; j++ ) + { + Val* assignval = ValueToVal(source, val->val.set_val.vals[j], have_error); + if ( have_error ) + return nullptr; + + t->Assign({AdoptRef{}, assignval}, nullptr); + } + + return t.release(); + } + case TYPE_VECTOR: + { + TypePtr type; + + if ( val->val.vector_val.size == 0 && + (val->subtype == TYPE_VOID || val->subtype == TYPE_ENUM) ) + // don't know type - unspecified table. + type = base_type(TYPE_ANY); + else { - TypePtr type; - - if ( val->val.vector_val.size == 0 && - (val->subtype == TYPE_VOID || val->subtype == TYPE_ENUM) ) - // don't know type - unspecified table. - type = base_type(TYPE_ANY); - else + // all entries have to have the same type... + if ( val->subtype == TYPE_VOID ) + type = base_type(val->val.vector_val.vals[0]->type); + else if ( val->subtype == TYPE_ENUM ) { - // all entries have to have the same type... - if ( val->subtype == TYPE_VOID ) - type = base_type(val->val.vector_val.vals[0]->type); - else if ( val->subtype == TYPE_ENUM ) + // Enums are not a base-type, so need to look it up. + const auto& sv = val->val.vector_val.vals[0]->val.string_val; + std::string enum_name(sv.data, sv.length); + const auto& enum_id = detail::global_scope()->Find(enum_name); + + if ( ! enum_id ) { - // Enums are not a base-type, so need to look it up. - const auto& sv = val->val.vector_val.vals[0]->val.string_val; - std::string enum_name(sv.data, sv.length); - const auto& enum_id = detail::global_scope()->Find(enum_name); + reporter->Warning("Value '%s' of source '%s' is not a valid enum.", + enum_name.data(), source.c_str()); - if ( ! enum_id ) - { - reporter->Warning("Value '%s' of source '%s' is not a valid enum.", - enum_name.data(), source.c_str()); - - have_error = true; - return nullptr; - } - - type = enum_id->GetType(); - } - else - type = base_type(val->subtype); - } - - auto vt = make_intrusive(std::move(type)); - auto v = make_intrusive(std::move(vt)); - - for ( int j = 0; j < val->val.vector_val.size; j++ ) - { - auto el = ValueToVal(source, val->val.vector_val.vals[j], have_error); - if ( have_error ) + have_error = true; return nullptr; + } - v->Assign(j, {AdoptRef{}, el}); + type = enum_id->GetType(); } - - return v.release(); + else + type = base_type(val->subtype); } + auto vt = make_intrusive(std::move(type)); + auto v = make_intrusive(std::move(vt)); + + for ( int j = 0; j < val->val.vector_val.size; j++ ) + { + auto el = ValueToVal(source, val->val.vector_val.vals[j], have_error); + if ( have_error ) + return nullptr; + + v->Assign(j, {AdoptRef{}, el}); + } + + return v.release(); + } + case TYPE_ENUM: + { + // Convert to string first to not have to deal with missing + // \0's... + std::string enum_string(val->val.string_val.data, val->val.string_val.length); + + // let's try looking it up by global ID. + const auto& id = detail::lookup_ID(enum_string.c_str(), detail::GLOBAL_MODULE_NAME); + + if ( ! id || ! id->IsEnumConst() ) { - // Convert to string first to not have to deal with missing - // \0's... - std::string enum_string(val->val.string_val.data, val->val.string_val.length); + reporter->Warning("Value '%s' for source '%s' is not a valid enum.", + enum_string.c_str(), source.c_str()); - // let's try looking it up by global ID. - const auto& id = detail::lookup_ID(enum_string.c_str(), detail::GLOBAL_MODULE_NAME); - - if ( ! id || ! id->IsEnumConst() ) - { - reporter->Warning("Value '%s' for source '%s' is not a valid enum.", - enum_string.c_str(), source.c_str()); - - have_error = true; - return nullptr; - } - - EnumType* t = id->GetType()->AsEnumType(); - int intval = t->Lookup(id->ModuleName(), id->Name()); - if ( intval < 0 ) - { - reporter->Warning("Enum value '%s' for source '%s' not found.", - enum_string.c_str(), source.c_str()); - - have_error = true; - return nullptr; - } - - auto rval = t->GetEnumVal(intval); - return rval.release(); + have_error = true; + return nullptr; } + EnumType* t = id->GetType()->AsEnumType(); + int intval = t->Lookup(id->ModuleName(), id->Name()); + if ( intval < 0 ) + { + reporter->Warning("Enum value '%s' for source '%s' not found.", enum_string.c_str(), + source.c_str()); + + have_error = true; + return nullptr; + } + + auto rval = t->GetEnumVal(intval); + return rval.release(); + } + default: reporter->InternalError("Unsupported type in SerialTypes::ValueToVal from source %s", source.c_str()); diff --git a/src/threading/formatters/Ascii.cc b/src/threading/formatters/Ascii.cc index 9663ec560e..d475f11399 100644 --- a/src/threading/formatters/Ascii.cc +++ b/src/threading/formatters/Ascii.cc @@ -123,80 +123,80 @@ bool Ascii::Describe(ODesc* desc, Value* val, const string& name) const case TYPE_STRING: case TYPE_FILE: case TYPE_FUNC: + { + int size = val->val.string_val.length; + const char* data = val->val.string_val.data; + + if ( ! size ) { - int size = val->val.string_val.length; - const char* data = val->val.string_val.data; - - if ( ! size ) - { - desc->Add(separators.empty_field); - break; - } - - if ( escapeReservedContent(desc, separators.unset_field, data, size) ) - break; - - if ( escapeReservedContent(desc, separators.empty_field, data, size) ) - break; - - desc->AddN(data, size); + desc->Add(separators.empty_field); break; } + if ( escapeReservedContent(desc, separators.unset_field, data, size) ) + break; + + if ( escapeReservedContent(desc, separators.empty_field, data, size) ) + break; + + desc->AddN(data, size); + break; + } + case TYPE_TABLE: + { + if ( ! val->val.set_val.size ) { - if ( ! val->val.set_val.size ) - { - desc->Add(separators.empty_field); - break; - } - - desc->AddEscapeSequence(separators.set_separator); - - for ( bro_int_t j = 0; j < val->val.set_val.size; j++ ) - { - if ( j > 0 ) - desc->AddRaw(separators.set_separator); - - if ( ! Describe(desc, val->val.set_val.vals[j]) ) - { - desc->RemoveEscapeSequence(separators.set_separator); - return false; - } - } - - desc->RemoveEscapeSequence(separators.set_separator); - + desc->Add(separators.empty_field); break; } + desc->AddEscapeSequence(separators.set_separator); + + for ( bro_int_t j = 0; j < val->val.set_val.size; j++ ) + { + if ( j > 0 ) + desc->AddRaw(separators.set_separator); + + if ( ! Describe(desc, val->val.set_val.vals[j]) ) + { + desc->RemoveEscapeSequence(separators.set_separator); + return false; + } + } + + desc->RemoveEscapeSequence(separators.set_separator); + + break; + } + case TYPE_VECTOR: + { + if ( ! val->val.vector_val.size ) { - if ( ! val->val.vector_val.size ) - { - desc->Add(separators.empty_field); - break; - } - - desc->AddEscapeSequence(separators.set_separator); - - for ( bro_int_t j = 0; j < val->val.vector_val.size; j++ ) - { - if ( j > 0 ) - desc->AddRaw(separators.set_separator); - - if ( ! Describe(desc, val->val.vector_val.vals[j]) ) - { - desc->RemoveEscapeSequence(separators.set_separator); - return false; - } - } - - desc->RemoveEscapeSequence(separators.set_separator); - + desc->Add(separators.empty_field); break; } + desc->AddEscapeSequence(separators.set_separator); + + for ( bro_int_t j = 0; j < val->val.vector_val.size; j++ ) + { + if ( j > 0 ) + desc->AddRaw(separators.set_separator); + + if ( ! Describe(desc, val->val.vector_val.vals[j]) ) + { + desc->RemoveEscapeSequence(separators.set_separator); + return false; + } + } + + desc->RemoveEscapeSequence(separators.set_separator); + + break; + } + default: GetThread()->Warning( GetThread()->Fmt("Ascii writer unsupported field format %d", val->type)); @@ -222,30 +222,30 @@ Value* Ascii::ParseValue(const string& s, const string& name, TypeTag type, Type { case TYPE_ENUM: case TYPE_STRING: - { - string unescaped = util::get_unescaped_string(s); - val->val.string_val.length = unescaped.size(); - val->val.string_val.data = new char[val->val.string_val.length]; - // we do not need a zero-byte at the end - the input manager adds that explicitly - memcpy(val->val.string_val.data, unescaped.data(), unescaped.size()); - break; - } + { + string unescaped = util::get_unescaped_string(s); + val->val.string_val.length = unescaped.size(); + val->val.string_val.data = new char[val->val.string_val.length]; + // we do not need a zero-byte at the end - the input manager adds that explicitly + memcpy(val->val.string_val.data, unescaped.data(), unescaped.size()); + break; + } case TYPE_BOOL: + { + auto stripped = util::strstrip(s); + if ( stripped == "T" || stripped == "1" ) + val->val.int_val = 1; + else if ( stripped == "F" || stripped == "0" ) + val->val.int_val = 0; + else { - auto stripped = util::strstrip(s); - if ( stripped == "T" || stripped == "1" ) - val->val.int_val = 1; - else if ( stripped == "F" || stripped == "0" ) - val->val.int_val = 0; - else - { - GetThread()->Warning(GetThread()->Fmt("Field: %s Invalid value for boolean: %s", - name.c_str(), start)); - goto parse_error; - } - break; + GetThread()->Warning(GetThread()->Fmt("Field: %s Invalid value for boolean: %s", + name.c_str(), start)); + goto parse_error; } + break; + } case TYPE_INT: val->val.int_val = strtoll(start, &end, 10); @@ -268,91 +268,91 @@ Value* Ascii::ParseValue(const string& s, const string& name, TypeTag type, Type break; case TYPE_PORT: + { + auto stripped = util::strstrip(s); + val->val.port_val.proto = TRANSPORT_UNKNOWN; + pos = stripped.find('/'); + string numberpart; + if ( pos != std::string::npos && stripped.length() > pos + 1 ) { - auto stripped = util::strstrip(s); - val->val.port_val.proto = TRANSPORT_UNKNOWN; - pos = stripped.find('/'); - string numberpart; - if ( pos != std::string::npos && stripped.length() > pos + 1 ) - { - auto proto = stripped.substr(pos + 1); - if ( util::strtolower(proto) == "tcp" ) - val->val.port_val.proto = TRANSPORT_TCP; - else if ( util::strtolower(proto) == "udp" ) - val->val.port_val.proto = TRANSPORT_UDP; - else if ( util::strtolower(proto) == "icmp" ) - val->val.port_val.proto = TRANSPORT_ICMP; - else if ( util::strtolower(proto) == "unknown" ) - val->val.port_val.proto = TRANSPORT_UNKNOWN; - else - GetThread()->Warning(GetThread()->Fmt( - "Port '%s' contained unknown protocol '%s'", s.c_str(), proto.c_str())); - } - - if ( pos != std::string::npos && pos > 0 ) - { - numberpart = stripped.substr(0, pos); - start = numberpart.c_str(); - } - val->val.port_val.port = strtoull(start, &end, 10); - if ( CheckNumberError(start, end, true) ) - goto parse_error; + auto proto = stripped.substr(pos + 1); + if ( util::strtolower(proto) == "tcp" ) + val->val.port_val.proto = TRANSPORT_TCP; + else if ( util::strtolower(proto) == "udp" ) + val->val.port_val.proto = TRANSPORT_UDP; + else if ( util::strtolower(proto) == "icmp" ) + val->val.port_val.proto = TRANSPORT_ICMP; + else if ( util::strtolower(proto) == "unknown" ) + val->val.port_val.proto = TRANSPORT_UNKNOWN; + else + GetThread()->Warning(GetThread()->Fmt( + "Port '%s' contained unknown protocol '%s'", s.c_str(), proto.c_str())); } + + if ( pos != std::string::npos && pos > 0 ) + { + numberpart = stripped.substr(0, pos); + start = numberpart.c_str(); + } + val->val.port_val.port = strtoull(start, &end, 10); + if ( CheckNumberError(start, end, true) ) + goto parse_error; + } break; case TYPE_SUBNET: + { + string unescaped = util::strstrip(util::get_unescaped_string(s)); + size_t pos = unescaped.find('/'); + if ( pos == unescaped.npos ) { - string unescaped = util::strstrip(util::get_unescaped_string(s)); - size_t pos = unescaped.find('/'); - if ( pos == unescaped.npos ) - { - GetThread()->Warning(GetThread()->Fmt("Invalid value for subnet: %s", start)); - goto parse_error; - } - - string width_str = unescaped.substr(pos + 1); - uint8_t width = (uint8_t)strtol(width_str.c_str(), &end, 10); - - if ( CheckNumberError(start, end) ) - goto parse_error; - - string addr = unescaped.substr(0, pos); - - val->val.subnet_val.prefix = ParseAddr(addr); - val->val.subnet_val.length = width; - break; - } - - case TYPE_ADDR: - { - string unescaped = util::strstrip(util::get_unescaped_string(s)); - val->val.addr_val = ParseAddr(unescaped); - break; - } - - case TYPE_PATTERN: - { - string candidate = util::get_unescaped_string(s); - // A string is a candidate pattern iff it begins and ends with - // a '/'. Rather or not the rest of the string is legal will - // be determined later when it is given to the RE engine. - if ( candidate.size() >= 2 ) - { - if ( candidate.front() == candidate.back() && candidate.back() == '/' ) - { - // Remove the '/'s - candidate.erase(0, 1); - candidate.erase(candidate.size() - 1); - val->val.pattern_text_val = util::copy_string(candidate.c_str()); - break; - } - } - - GetThread()->Warning(GetThread()->Fmt("String '%s' contained no parseable pattern.", - candidate.c_str())); + GetThread()->Warning(GetThread()->Fmt("Invalid value for subnet: %s", start)); goto parse_error; } + string width_str = unescaped.substr(pos + 1); + uint8_t width = (uint8_t)strtol(width_str.c_str(), &end, 10); + + if ( CheckNumberError(start, end) ) + goto parse_error; + + string addr = unescaped.substr(0, pos); + + val->val.subnet_val.prefix = ParseAddr(addr); + val->val.subnet_val.length = width; + break; + } + + case TYPE_ADDR: + { + string unescaped = util::strstrip(util::get_unescaped_string(s)); + val->val.addr_val = ParseAddr(unescaped); + break; + } + + case TYPE_PATTERN: + { + string candidate = util::get_unescaped_string(s); + // A string is a candidate pattern iff it begins and ends with + // a '/'. Rather or not the rest of the string is legal will + // be determined later when it is given to the RE engine. + if ( candidate.size() >= 2 ) + { + if ( candidate.front() == candidate.back() && candidate.back() == '/' ) + { + // Remove the '/'s + candidate.erase(0, 1); + candidate.erase(candidate.size() - 1); + val->val.pattern_text_val = util::copy_string(candidate.c_str()); + break; + } + } + + GetThread()->Warning( + GetThread()->Fmt("String '%s' contained no parseable pattern.", candidate.c_str())); + goto parse_error; + } + case TYPE_TABLE: case TYPE_VECTOR: // First - common initialization diff --git a/src/threading/formatters/JSON.cc b/src/threading/formatters/JSON.cc index 838788ca46..5e3449cbdc 100644 --- a/src/threading/formatters/JSON.cc +++ b/src/threading/formatters/JSON.cc @@ -127,80 +127,79 @@ void JSON::BuildJSON(NullDoubleWriter& writer, Value* val, const std::string& na break; case TYPE_TIME: + { + if ( timestamps == TS_ISO8601 ) { - if ( timestamps == TS_ISO8601 ) + char buffer[40]; + char buffer2[48]; + time_t the_time = time_t(floor(val->val.double_val)); + struct tm t; + + if ( ! gmtime_r(&the_time, &t) || + ! strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%S", &t) ) { - char buffer[40]; - char buffer2[48]; - time_t the_time = time_t(floor(val->val.double_val)); - struct tm t; - - if ( ! gmtime_r(&the_time, &t) || - ! strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%S", &t) ) - { - GetThread()->Error(GetThread()->Fmt( - "json formatter: failure getting time: (%lf)", val->val.double_val)); - // This was a failure, doesn't really matter what gets put here - // but it should probably stand out... - writer.String("2000-01-01T00:00:00.000000"); - } - else - { - double integ; - double frac = modf(val->val.double_val, &integ); - - if ( frac < 0 ) - frac += 1; - - snprintf(buffer2, sizeof(buffer2), "%s.%06.0fZ", buffer, - fabs(frac) * 1000000); - writer.String(buffer2, strlen(buffer2)); - } + GetThread()->Error(GetThread()->Fmt( + "json formatter: failure getting time: (%lf)", val->val.double_val)); + // This was a failure, doesn't really matter what gets put here + // but it should probably stand out... + writer.String("2000-01-01T00:00:00.000000"); } - - else if ( timestamps == TS_EPOCH ) - writer.Double(val->val.double_val); - - else if ( timestamps == TS_MILLIS ) + else { - // ElasticSearch uses milliseconds for timestamps - writer.Uint64((uint64_t)(val->val.double_val * 1000)); - } + double integ; + double frac = modf(val->val.double_val, &integ); - break; + if ( frac < 0 ) + frac += 1; + + snprintf(buffer2, sizeof(buffer2), "%s.%06.0fZ", buffer, fabs(frac) * 1000000); + writer.String(buffer2, strlen(buffer2)); + } } + else if ( timestamps == TS_EPOCH ) + writer.Double(val->val.double_val); + + else if ( timestamps == TS_MILLIS ) + { + // ElasticSearch uses milliseconds for timestamps + writer.Uint64((uint64_t)(val->val.double_val * 1000)); + } + + break; + } + case TYPE_ENUM: case TYPE_STRING: case TYPE_FILE: case TYPE_FUNC: - { - writer.String(util::json_escape_utf8( - std::string(val->val.string_val.data, val->val.string_val.length))); - break; - } + { + writer.String(util::json_escape_utf8( + std::string(val->val.string_val.data, val->val.string_val.length))); + break; + } case TYPE_TABLE: - { - writer.StartArray(); + { + writer.StartArray(); - for ( bro_int_t idx = 0; idx < val->val.set_val.size; idx++ ) - BuildJSON(writer, val->val.set_val.vals[idx]); + for ( bro_int_t idx = 0; idx < val->val.set_val.size; idx++ ) + BuildJSON(writer, val->val.set_val.vals[idx]); - writer.EndArray(); - break; - } + writer.EndArray(); + break; + } case TYPE_VECTOR: - { - writer.StartArray(); + { + writer.StartArray(); - for ( bro_int_t idx = 0; idx < val->val.vector_val.size; idx++ ) - BuildJSON(writer, val->val.vector_val.vals[idx]); + for ( bro_int_t idx = 0; idx < val->val.vector_val.size; idx++ ) + BuildJSON(writer, val->val.vector_val.vals[idx]); - writer.EndArray(); - break; - } + writer.EndArray(); + break; + } default: reporter->Warning("Unhandled type in JSON::BuildJSON"); diff --git a/src/util.cc b/src/util.cc index 484bb5236c..14241481e6 100644 --- a/src/util.cc +++ b/src/util.cc @@ -183,67 +183,67 @@ int expand_escape(const char*& s) case '5': case '6': case '7': - { // \{1,3} - --s; // put back the first octal digit - const char* start = s; + { // \{1,3} + --s; // put back the first octal digit + const char* start = s; - // require at least one octal digit and parse at most three + // require at least one octal digit and parse at most three - int result = parse_octal_digit(*s++); + int result = parse_octal_digit(*s++); - if ( result < 0 ) - { - reporter->Error("bad octal escape: %s", start); - return 0; - } + if ( result < 0 ) + { + reporter->Error("bad octal escape: %s", start); + return 0; + } - // second digit? - int digit = parse_octal_digit(*s); + // second digit? + int digit = parse_octal_digit(*s); + + if ( digit >= 0 ) + { + result = (result << 3) | digit; + ++s; + + // third digit? + digit = parse_octal_digit(*s); if ( digit >= 0 ) { result = (result << 3) | digit; ++s; - - // third digit? - digit = parse_octal_digit(*s); - - if ( digit >= 0 ) - { - result = (result << 3) | digit; - ++s; - } } - - return result; } + return result; + } + case 'x': - { /* \x */ - const char* start = s; + { /* \x */ + const char* start = s; - // Look at most 2 characters, so that "\x0ddir" -> "^Mdir". + // Look at most 2 characters, so that "\x0ddir" -> "^Mdir". - int result = parse_hex_digit(*s++); + int result = parse_hex_digit(*s++); - if ( result < 0 ) - { - reporter->Error("bad hexadecimal escape: %s", start); - return 0; - } - - // second digit? - int digit = parse_hex_digit(*s); - - if ( digit >= 0 ) - { - result = (result << 4) | digit; - ++s; - } - - return result; + if ( result < 0 ) + { + reporter->Error("bad hexadecimal escape: %s", start); + return 0; } + // second digit? + int digit = parse_hex_digit(*s); + + if ( digit >= 0 ) + { + result = (result << 4) | digit; + ++s; + } + + return result; + } + default: return s[-1]; } diff --git a/src/zeekygen/Target.cc b/src/zeekygen/Target.cc index 04c8a1921d..b03d7b8e2b 100644 --- a/src/zeekygen/Target.cc +++ b/src/zeekygen/Target.cc @@ -81,38 +81,37 @@ static void write_plugin_components(FILE* f, const plugin::Plugin* p) switch ( component->Type() ) { case plugin::component::ANALYZER: - { - const analyzer::Component* c = - dynamic_cast(component); + { + const analyzer::Component* c = dynamic_cast(component); - if ( c ) - write_analyzer_component(f, c); - else - reporter->InternalError("component type mismatch"); - } + if ( c ) + write_analyzer_component(f, c); + else + reporter->InternalError("component type mismatch"); + } break; case plugin::component::PACKET_ANALYZER: - { - const packet_analysis::Component* c = - dynamic_cast(component); + { + const packet_analysis::Component* c = + dynamic_cast(component); - if ( c ) - write_analyzer_component(f, c); - else - reporter->InternalError("component type mismatch"); - } + if ( c ) + write_analyzer_component(f, c); + else + reporter->InternalError("component type mismatch"); + } break; case plugin::component::FILE_ANALYZER: - { - const auto* c = dynamic_cast(component); + { + const auto* c = dynamic_cast(component); - if ( c ) - write_analyzer_component(f, c); - else - reporter->InternalError("component type mismatch"); - } + if ( c ) + write_analyzer_component(f, c); + else + reporter->InternalError("component type mismatch"); + } break; case plugin::component::READER: diff --git a/src/zeekygen/utils.cc b/src/zeekygen/utils.cc index 1922727e83..b79e91fe88 100644 --- a/src/zeekygen/utils.cc +++ b/src/zeekygen/utils.cc @@ -170,19 +170,19 @@ std::optional source_code_range(const zeek::detail::ID* id) switch ( type->Tag() ) { case TYPE_FUNC: - { - const auto& v = id->GetVal(); + { + const auto& v = id->GetVal(); - if ( v && v->AsFunc()->GetBodies().size() == 1 ) - { - // Either a function or an event/hook with single body can - // report that single, continuous range. - loc = v->AsFunc()->GetBodies()[0].stmts->GetLocationInfo(); - ++extra_lines; - } - else - loc = id->GetLocationInfo(); + if ( v && v->AsFunc()->GetBodies().size() == 1 ) + { + // Either a function or an event/hook with single body can + // report that single, continuous range. + loc = v->AsFunc()->GetBodies()[0].stmts->GetLocationInfo(); + ++extra_lines; } + else + loc = id->GetLocationInfo(); + } break; case TYPE_ENUM: // Fallthrough