diff --git a/src/CompHash.cc b/src/CompHash.cc index 5a874241b4..2f19771637 100644 --- a/src/CompHash.cc +++ b/src/CompHash.cc @@ -265,7 +265,7 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0, kp1 = reinterpret_cast(kp+1); for ( unsigned int i = 0; i < vv->Size(); ++i ) { - const auto& val = vv->At(i); + auto val = vv->ValAt(i); unsigned int* kp = AlignAndPadType(kp1); *kp = i; kp1 = reinterpret_cast(kp+1); @@ -566,7 +566,7 @@ int CompositeHash::SingleTypeKeySize(Type* bt, const Val* v, VectorVal* vv = const_cast(v->AsVectorVal()); for ( unsigned int i = 0; i < vv->Size(); ++i ) { - const auto& val = vv->At(i); + auto val = vv->ValAt(i); sz = SizeAlign(sz, sizeof(unsigned int)); sz = SizeAlign(sz, sizeof(unsigned int)); if ( val ) diff --git a/src/Expr.cc b/src/Expr.cc index 9206978ddd..2876369145 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -277,7 +277,7 @@ const char* assign_to_index(ValPtr v1, ValPtr v2, ValPtr v3, for ( auto idx = 0u; idx < v_vect->Size(); idx++, first++ ) - v1_vect->Insert(first, v_vect->At(idx)); + v1_vect->Insert(first, v_vect->ValAt(idx)); } else if ( ! v1_vect->Assign(lv->Idx(0)->CoerceToUnsigned(), std::move(v3)) ) @@ -619,8 +619,11 @@ ValPtr UnaryExpr::Eval(Frame* f) const for ( unsigned int i = 0; i < v_op->Size(); ++i ) { - const auto& v_i = v_op->At(i); - result->Assign(i, v_i ? Fold(v_i.get()) : nullptr); + auto vop = v_op->ValAt(i); + if ( vop ) + result->Assign(i, Fold(vop.get())); + else + result->Assign(i, nullptr); } return result; @@ -708,11 +711,12 @@ ValPtr BinaryExpr::Eval(Frame* f) const for ( unsigned int i = 0; i < v_op1->Size(); ++i ) { - if ( v_op1->At(i) && v_op2->At(i) ) - v_result->Assign(i, Fold(v_op1->At(i).get(), v_op2->At(i).get())); + auto v1_i = v_op1->ValAt(i); + auto v2_i = v_op2->ValAt(i); + if ( v1_i && v2_i ) + v_result->Assign(i, Fold(v_op1->ValAt(i).get(), v_op2->ValAt(i).get())); else v_result->Assign(i, nullptr); - // SetError("undefined element in vector operation"); } return v_result; @@ -725,13 +729,12 @@ ValPtr BinaryExpr::Eval(Frame* f) const for ( unsigned int i = 0; i < vv->Size(); ++i ) { - if ( const auto& vv_i = vv->At(i) ) + auto vv_i = vv->ValAt(i); + if ( vv_i ) v_result->Assign(i, is_vec1 ? Fold(vv_i.get(), v2.get()) - : Fold(v1.get(), vv_i.get())); + : Fold(v1.get(), vv_i.get())); else v_result->Assign(i, nullptr); - - // SetError("Undefined element in vector operation"); } return v_result; @@ -1235,12 +1238,8 @@ ValPtr IncrExpr::Eval(Frame* f) const for ( unsigned int i = 0; i < v_vec->Size(); ++i ) { - const auto& elt = v_vec->At(i); - - if ( elt ) - v_vec->Assign(i, DoSingleEval(f, elt.get())); - else - v_vec->Assign(i, nullptr); + auto elt = v_vec->ValAt(i); + v_vec->Assign(i, DoSingleEval(f, elt.get())); } op->Assign(f, std::move(v_vec)); @@ -1863,18 +1862,13 @@ ValPtr BoolExpr::Eval(Frame* f) const for ( unsigned int i = 0; i < vec_v1->Size(); ++i ) { - const auto& op1 = vec_v1->At(i); - const auto& op2 = vec_v2->At(i); - if ( op1 && op2 ) - { - bool local_result = (tag == EXPR_AND_AND) ? - (! op1->IsZero() && ! op2->IsZero()) : - (! op1->IsZero() || ! op2->IsZero()); + const auto op1 = vec_v1->BoolAt(i); + const auto op2 = vec_v2->BoolAt(i); - result->Assign(i, val_mgr->Bool(local_result)); - } - else - result->Assign(i, nullptr); + bool local_result = + (tag == EXPR_AND_AND) ? (op1 && op2) : (op1 || op2); + + result->Assign(i, val_mgr->Bool(local_result)); } return result; @@ -2225,15 +2219,9 @@ ValPtr CondExpr::Eval(Frame* f) const for ( unsigned int i = 0; i < cond->Size(); ++i ) { - const auto& local_cond = cond->At(i); - - if ( local_cond ) - { - const auto& v = local_cond->IsZero() ? b->At(i) : a->At(i); - result->Assign(i, v); - } - else - result->Assign(i, nullptr); + auto local_cond = cond->BoolAt(i); + auto v = local_cond ? a->ValAt(i) : b->ValAt(i); + result->Assign(i, v); } return result; @@ -2912,8 +2900,8 @@ ValPtr IndexExpr::Eval(Frame* f) const for ( unsigned int i = 0; i < v_v2->Size(); ++i ) { - if ( v_v2->At(i)->AsBool() ) - v_result->Assign(v_result->Size() + 1, v_v1->At(i)); + if ( v_v2->BoolAt(i) ) + v_result->Assign(v_result->Size() + 1, v_v1->ValAt(i)); } } else @@ -2923,7 +2911,7 @@ ValPtr IndexExpr::Eval(Frame* f) const // Probably only do this if *all* are negative. v_result->Resize(v_v2->Size()); for ( unsigned int i = 0; i < v_v2->Size(); ++i ) - v_result->Assign(i, v_v1->At(v_v2->At(i)->CoerceToInt())); + v_result->Assign(i, v_v1->ValAt(v_v2->ValAt(i)->CoerceToInt())); } return v_result; @@ -2946,7 +2934,7 @@ ValPtr IndexExpr::Fold(Val* v1, Val* v2) const const ListVal* lv = v2->AsListVal(); if ( lv->Length() == 1 ) - v = vect->At(lv->Idx(0)->CoerceToUnsigned()); + v = vect->ValAt(lv->Idx(0)->CoerceToUnsigned()); else { size_t len = vect->Size(); @@ -2961,7 +2949,7 @@ ValPtr IndexExpr::Fold(Val* v1, Val* v2) const result->Resize(sub_length); for ( bro_int_t idx = first; idx < last; idx++ ) - result->Assign(idx - first, vect->At(idx)); + result->Assign(idx - first, vect->ValAt(idx)); } return result; @@ -3764,7 +3752,8 @@ ValPtr ArithCoerceExpr::Fold(Val* v) const for ( unsigned int i = 0; i < vv->Size(); ++i ) { - if ( const auto& elt = vv->At(i) ) + auto elt = vv->ValAt(i); + if ( elt ) result->Assign(i, FoldSingleVal(elt.get(), t)); else result->Assign(i, nullptr); @@ -4222,7 +4211,11 @@ ValPtr InExpr::Fold(Val* v1, Val* v2) const bool res; if ( is_vector(v2) ) - res = (bool)v2->AsVectorVal()->At(v1->AsListVal()->Idx(0)->CoerceToUnsigned()); + { + auto vv2 = v2->AsVectorVal(); + auto ind = v1->AsListVal()->Idx(0)->CoerceToUnsigned(); + res = ind < vv2->Size() && vv2->ValAt(ind); + } else res = (bool)v2->AsTableVal()->Find({NewRef{}, v1}); diff --git a/src/SmithWaterman.cc b/src/SmithWaterman.cc index 1b2fad0628..1b2bebea09 100644 --- a/src/SmithWaterman.cc +++ b/src/SmithWaterman.cc @@ -104,23 +104,23 @@ Substring::Vec* Substring::VecFromPolicy(VectorVal* vec) for ( unsigned int i = 0; i < vec->Size(); ++i ) { - const auto& v = vec->At(i); // get the RecordVal + auto v = vec->RecordValAt(i); if ( ! v ) continue; - const String* str = v->AsRecordVal()->GetFieldAs(0); + const String* str = v->GetFieldAs(0); auto* substr = new Substring(*str); - const VectorVal* aligns = v->AsRecordVal()->GetField(1)->AsVectorVal(); + const VectorVal* aligns = v->GetField(1)->AsVectorVal(); for ( unsigned int j = 1; j <= aligns->Size(); ++j ) { - const RecordVal* align = aligns->AsVectorVal()->At(j)->AsRecordVal(); + const RecordVal* align = aligns->AsVectorVal()->RecordValAt(j); const String* str = align->GetFieldAs(0); int index = align->GetFieldAs(1); substr->AddAlignment(str, index); } - bool new_alignment = v->AsRecordVal()->GetFieldAs(2); + bool new_alignment = v->GetFieldAs(2); substr->MarkNewAlignment(new_alignment); result->push_back(substr); diff --git a/src/Stmt.cc b/src/Stmt.cc index 646cf06d45..11381ed733 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -1326,10 +1326,6 @@ ValPtr ForStmt::DoExec(Frame* f, Val* v, StmtFlowType& flow) const for ( auto i = 0u; i <= vv->Size(); ++i ) { - // Skip unassigned vector indices. - if ( ! vv->At(i) ) - continue; - // Set the loop variable to the current index, and make // another pass over the loop body. f->SetElement((*loop_vars)[0], val_mgr->Count(i)); diff --git a/src/Val.cc b/src/Val.cc index 6b0b5b6d20..2068092cbf 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -588,7 +588,7 @@ static void BuildJSON(threading::formatter::JSON::NullDoubleWriter& writer, Val* auto* vval = val->AsVectorVal(); size_t size = vval->SizeVal()->AsCount(); for (size_t i = 0; i < size; i++) - BuildJSON(writer, vval->At(i).get(), only_loggable, re); + BuildJSON(writer, vval->ValAt(i).get(), only_loggable, re); writer.EndArray(); break; diff --git a/src/Val.h b/src/Val.h index 50c8b87e09..9eb639f10d 100644 --- a/src/Val.h +++ b/src/Val.h @@ -1299,24 +1299,6 @@ public: // Returns true if succcessful. bool AddTo(Val* v, bool is_first_init) const override; - /** - * Returns the element at a given index or nullptr if it does not exist. - * @param index The position in the vector of the element to return. - * @return The element at the given index or nullptr if the index - * does not exist (it's greater than or equal to vector's current size). - */ - ValPtr At(unsigned int index) const; - - /** - * Returns the given element treated as a Count type, to efficiently - * support a common type of vector access if we change the underlying - * vector representation. - * @param index The position in the vector of the element to return. - * @return The element's value, as a Count underlying representation. - */ - bro_uint_t CountAt(unsigned int index) const - { return At(index)->AsCount(); } - unsigned int Size() const { return vector_val->size(); } // Is there any way to reclaim previously-allocated memory when you @@ -1367,7 +1349,38 @@ public: */ VectorValPtr Order(Func* cmp_func = nullptr); + ValPtr ValAt(unsigned int index) const { return At(index); } + + /** + * Returns the given element in a given underlying representation. + * Enables efficient vector access. Caller must ensure that the + * index lies within the vector's range. + * @param index The position in the vector of the element to return. + * @return The element's underlying value. + */ + bro_uint_t CountAt(unsigned int index) const + { return (*vector_val)[index].uint_val; } + const RecordVal* RecordValAt(unsigned int index) const + { return (*vector_val)[index].record_val; } + bool BoolAt(unsigned int index) const + { return bool((*vector_val)[index].uint_val); } + const StringVal* StringValAt(unsigned int index) const + { return (*vector_val)[index].string_val; } + const String* StringAt(unsigned int index) const + { return StringValAt(index)->AsString(); } + protected: + /** + * Returns the element at a given index or nullptr if it does not exist. + * @param index The position in the vector of the element to return. + * @return The element at the given index or nullptr if the index + * does not exist (it's greater than or equal to vector's current size). + * + * Protected to ensure callers pick one of the differentiated accessors + * above, as appropriate, with ValAt() providing the original semantics. + */ + ValPtr At(unsigned int index) const; + void ValDescribe(ODesc* d) const override; ValPtr DoClone(CloneState* state) override; diff --git a/src/ZeekString.cc b/src/ZeekString.cc index f2537eb34a..f87714fab2 100644 --- a/src/ZeekString.cc +++ b/src/ZeekString.cc @@ -364,11 +364,11 @@ String::Vec* String::VecFromPolicy(VectorVal* vec) for ( unsigned int i = 0; i < vec->Size(); ++i ) { - const auto& v = vec->At(i); // get the RecordVal + auto v = vec->StringAt(i); if ( ! v ) continue; - String* string = new String(*(v->AsString())); + String* string = new String(*v); result->push_back(string); } diff --git a/src/analyzer/protocol/ssh/ssh-protocol.pac b/src/analyzer/protocol/ssh/ssh-protocol.pac index de38afde13..a8c8328ef0 100644 --- a/src/analyzer/protocol/ssh/ssh-protocol.pac +++ b/src/analyzer/protocol/ssh/ssh-protocol.pac @@ -456,11 +456,11 @@ refine connection SSH_Conn += { { for ( unsigned int j = 0; j < server_list->Size(); ++j ) { - if ( *(client_list->At(i)->AsStringVal()->AsString()) == *(server_list->At(j)->AsStringVal()->AsString()) ) + if ( *(client_list->StringAt(i)) == *(server_list->StringAt(j)) ) { kex_algorithm_.free(); - kex_algorithm_.init((const uint8 *) client_list->At(i)->AsStringVal()->Bytes(), - client_list->At(i)->AsStringVal()->Len()); + kex_algorithm_.init((const uint8 *) client_list->StringAt(i)->Bytes(), + client_list->StringAt(i)->Len()); // UNTESTED if ( update_kex_state_if_equal("rsa1024-sha1", KEX_RSA) ) diff --git a/src/broker/Data.cc b/src/broker/Data.cc index 6fdeb23cea..d8d03c709d 100644 --- a/src/broker/Data.cc +++ b/src/broker/Data.cc @@ -972,7 +972,7 @@ broker::expected val_to_data(const Val* v) for ( auto i = 0u; i < vec->Size(); ++i ) { - const auto& item_val = vec->At(i); + auto item_val = vec->ValAt(i); if ( ! item_val ) continue; diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index e24b11261b..c99ee1ba6d 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -443,7 +443,7 @@ bool Manager::PublishEvent(string topic, RecordVal* args) for ( auto i = 0u; i < vv->Size(); ++i ) { - const auto& val = vv->At(i)->AsRecordVal()->GetField(0); + const auto& val = vv->RecordValAt(i)->GetField(0); auto data_val = static_cast(val.get()); xs.emplace_back(data_val->data); } diff --git a/src/file_analysis/analyzer/x509/functions.bif b/src/file_analysis/analyzer/x509/functions.bif index a754ec19b0..3f18ed163f 100644 --- a/src/file_analysis/analyzer/x509/functions.bif +++ b/src/file_analysis/analyzer/x509/functions.bif @@ -37,7 +37,7 @@ STACK_OF(X509)* x509_get_untrusted_stack(zeek::VectorVal* certs_vec) for ( int i = 1; i < (int) certs_vec->Size(); ++i ) // start at 1 - 0 is host cert { - const auto& sv = certs_vec->At(i); + auto sv = certs_vec->ValAt(i); if ( ! sv ) continue; @@ -232,7 +232,7 @@ function x509_ocsp_verify%(certs: x509_opaque_vector, ocsp_reply: string, root_c // host certificate unsigned int index = 0; // to prevent overloading to 0pointer - const auto& sv = certs_vec->At(index); + auto sv = certs_vec->ValAt(index); if ( ! sv ) { zeek::emit_builtin_error("undefined value in certificate vector"); @@ -518,7 +518,7 @@ function x509_verify%(certs: x509_opaque_vector, root_certs: table_string_of_str // host certificate unsigned int index = 0; // to prevent overloading to 0pointer - const auto& sv = certs_vec->At(index); + auto sv = certs_vec->ValAt(index); if ( !sv ) { zeek::emit_builtin_error("undefined value in certificate vector"); diff --git a/src/logging/Manager.cc b/src/logging/Manager.cc index 77dd8205b9..27b2216262 100644 --- a/src/logging/Manager.cc +++ b/src/logging/Manager.cc @@ -1045,7 +1045,7 @@ threading::Value* Manager::ValToLogVal(Val* val, Type* ty) for ( bro_int_t i = 0; i < lval->val.vector_val.size; i++ ) { lval->val.vector_val.vals[i] = - ValToLogVal(vec->At(i).get(), + ValToLogVal(vec->ValAt(i).get(), vec->GetType()->Yield().get()); } diff --git a/src/strings.bif b/src/strings.bif index 6ef0918ec6..0d3812f267 100644 --- a/src/strings.bif +++ b/src/strings.bif @@ -104,7 +104,7 @@ function join_string_vec%(vec: string_vec, sep: string%): string if ( i > 0 ) d.Add(sep->CheckString(), 0); - const auto& e = v->At(i); + auto e = v->ValAt(i); // If the element is empty, skip it. if ( ! e ) diff --git a/src/supervisor/Supervisor.cc b/src/supervisor/Supervisor.cc index 76b760835b..f8d957c482 100644 --- a/src/supervisor/Supervisor.cc +++ b/src/supervisor/Supervisor.cc @@ -1255,7 +1255,7 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromRecord(const RecordVal* node) for ( auto i = 0u; i < scripts_val->Size(); ++i ) { - auto script = scripts_val->At(i)->AsStringVal()->ToStdString(); + auto script = scripts_val->StringValAt(i)->ToStdString(); rval.scripts.emplace_back(std::move(script)); } diff --git a/src/zeek.bif b/src/zeek.bif index 25c15d12dd..184c9280cb 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -815,7 +815,7 @@ function paraglob_init%(v: any%) : opaque of paraglob VectorVal* vv = v->AsVectorVal(); for ( unsigned int i = 0; i < vv->Size(); ++i ) { - const String* s = vv->At(i)->AsString(); + auto s = vv->StringAt(i); patterns.push_back(std::string(reinterpret_cast(s->Bytes()), s->Len())); } @@ -1293,7 +1293,7 @@ function any_set%(v: any%) : bool VectorVal* vv = v->AsVectorVal(); for ( unsigned int i = 0; i < vv->Size(); ++i ) - if ( vv->At(i) && vv->At(i)->AsBool() ) + if ( vv->BoolAt(i) ) return zeek::val_mgr->True(); return zeek::val_mgr->False(); @@ -1322,7 +1322,7 @@ function all_set%(v: any%) : bool VectorVal* vv = v->AsVectorVal(); for ( unsigned int i = 0; i < vv->Size(); ++i ) - if ( ! vv->At(i) || ! vv->At(i)->AsBool() ) + if ( ! vv->BoolAt(i) ) return zeek::val_mgr->False(); return zeek::val_mgr->True();