Migrate Tag classes to use IntrusivePtr

Deprecates various methods that previously took raw pointers
This commit is contained in:
Jon Siwek 2020-05-05 17:10:34 -07:00
parent b096e552d3
commit 1abed4fd4c
20 changed files with 174 additions and 85 deletions

3
NEWS
View file

@ -137,6 +137,9 @@ Deprecated Functionality
to associated ``Val`` type are now deprecated, the deprecation warning
message will advice what new method to use instead.
- Various methods of ``Tag`` classes are deprecated with the warning
message advising what new method to use instead.
Zeek 3.1.0
==========

View file

@ -4,37 +4,40 @@
#include "Val.h"
#include "IntrusivePtr.h"
Tag::Tag(EnumType* etype, type_t arg_type, subtype_t arg_subtype)
Tag::Tag(const IntrusivePtr<EnumType>& etype, type_t arg_type, subtype_t arg_subtype)
{
assert(arg_type > 0);
type = arg_type;
subtype = arg_subtype;
int64_t i = (int64_t)(type) | ((int64_t)subtype << 31);
Ref(etype);
val = etype->GetVal(i).release();
val = etype->GetVal(i);
}
Tag::Tag(EnumVal* arg_val)
Tag::Tag(EnumType* etype, type_t arg_type, subtype_t arg_subtype)
: Tag({NewRef{}, etype}, arg_type, arg_subtype)
{ }
Tag::Tag(IntrusivePtr<EnumVal> arg_val)
{
assert(arg_val);
val = arg_val;
Ref(val);
val = std::move(arg_val);
int64_t i = val->InternalInt();
type = i & 0xffffffff;
subtype = (i >> 31) & 0xffffffff;
}
Tag::Tag(EnumVal* arg_val)
: Tag({NewRef{}, arg_val})
{ }
Tag::Tag(const Tag& other)
{
type = other.type;
subtype = other.subtype;
val = other.val;
if ( val )
Ref(val);
}
Tag::Tag()
@ -44,11 +47,7 @@ Tag::Tag()
val = nullptr;
}
Tag::~Tag()
{
Unref(val);
val = nullptr;
}
Tag::~Tag() = default;
Tag& Tag::operator=(const Tag& other)
{
@ -56,11 +55,7 @@ Tag& Tag::operator=(const Tag& other)
{
type = other.type;
subtype = other.subtype;
Unref(val);
val = other.val;
if ( val )
Ref(val);
}
return *this;
@ -72,26 +67,28 @@ Tag& Tag::operator=(const Tag&& other) noexcept
{
type = other.type;
subtype = other.subtype;
Unref(val);
val = other.val;
other.val = nullptr;
val = std::move(other.val);
}
return *this;
}
EnumVal* Tag::AsEnumVal(EnumType* etype) const
const IntrusivePtr<EnumVal>& Tag::AsVal(const IntrusivePtr<EnumType>& etype) const
{
if ( ! val )
{
assert(type == 0 && subtype == 0);
Ref(etype);
val = etype->GetVal(0).release();
val = etype->GetVal(0);
}
return val;
}
EnumVal* Tag::AsEnumVal(EnumType* etype) const
{
return AsVal({NewRef{}, etype}).get();
}
std::string Tag::AsString() const
{
return fmt("%" PRIu32 "/%" PRIu32, type, subtype);

View file

@ -3,6 +3,7 @@
#pragma once
#include "zeek-config.h"
#include "IntrusivePtr.h"
#include <string>
@ -114,6 +115,9 @@ protected:
*
* @param etype the script-layer enum type associated with the tag.
*/
const IntrusivePtr<EnumVal>& AsVal(const IntrusivePtr<EnumType>& etype) const;
[[deprecated("Remove in v4.1. Use AsVal() instead.")]]
EnumVal* AsEnumVal(EnumType* etype) const;
/**
@ -127,6 +131,9 @@ protected:
* @param subtype The sub type, which is left to an analyzer for
* interpretation. By default it's set to zero.
*/
Tag(const IntrusivePtr<EnumType>& etype, type_t type, subtype_t subtype = 0);
[[deprecated("Remove in v4.1. Construct from IntrusivePtr& instead.")]]
Tag(EnumType* etype, type_t type, subtype_t subtype = 0);
/**
@ -134,10 +141,13 @@ protected:
*
* @param val An enum value of script type \c Analyzer::Tag.
*/
explicit Tag(IntrusivePtr<EnumVal> val);
[[deprecated("Remove in v4.1. Construct from IntrusivePtr instead.")]]
explicit Tag(EnumVal* val);
private:
type_t type; // Main type.
subtype_t subtype; // Subtype.
mutable EnumVal* val; // Script-layer value.
mutable IntrusivePtr<EnumVal> val; // Script-layer value.
};

View file

@ -687,13 +687,8 @@ void Analyzer::ProtocolConfirmation(Tag arg_tag)
if ( ! protocol_confirmation )
return;
EnumVal* tval = arg_tag ? arg_tag.AsEnumVal() : tag.AsEnumVal();
mgr.Enqueue(protocol_confirmation,
ConnVal(),
IntrusivePtr{NewRef{}, tval},
val_mgr->Count(id)
);
const auto& tval = arg_tag ? arg_tag.AsVal() : tag.AsVal();
mgr.Enqueue(protocol_confirmation, ConnVal(), tval, val_mgr->Count(id));
}
void Analyzer::ProtocolViolation(const char* reason, const char* data, int len)
@ -701,27 +696,21 @@ void Analyzer::ProtocolViolation(const char* reason, const char* data, int len)
if ( ! protocol_violation )
return;
StringVal* r;
IntrusivePtr<StringVal> r;
if ( data && len )
{
const char *tmp = copy_string(reason);
r = new StringVal(fmt("%s [%s%s]", tmp,
r = make_intrusive<StringVal>(fmt("%s [%s%s]", tmp,
fmt_bytes(data, min(40, len)),
len > 40 ? "..." : ""));
delete [] tmp;
}
else
r = new StringVal(reason);
r = make_intrusive<StringVal>(reason);
EnumVal* tval = tag.AsEnumVal();
mgr.Enqueue(protocol_violation,
ConnVal(),
IntrusivePtr{NewRef{}, tval},
val_mgr->Count(id),
IntrusivePtr{AdoptRef{}, r}
);
const auto& tval = tag.AsVal();
mgr.Enqueue(protocol_violation, ConnVal(), tval, val_mgr->Count(id), std::move(r));
}
void Analyzer::AddTimer(analyzer_timer_func timer, double t,

View file

@ -572,8 +572,9 @@ void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp,
void Manager::ScheduleAnalyzer(const IPAddr& orig, const IPAddr& resp, PortVal* resp_p,
Val* analyzer, double timeout)
{
EnumVal* ev = analyzer->AsEnumVal();
return ScheduleAnalyzer(orig, resp, resp_p->Port(), resp_p->PortType(), Tag(ev), timeout);
IntrusivePtr<EnumVal> ev{NewRef{}, analyzer->AsEnumVal()};
return ScheduleAnalyzer(orig, resp, resp_p->Port(), resp_p->PortType(),
Tag(std::move(ev)), timeout);
}
Manager::tag_set Manager::GetScheduled(const Connection* conn)
@ -624,8 +625,7 @@ bool Manager::ApplyScheduledAnalyzers(Connection* conn, bool init, TransportLaye
if ( scheduled_analyzer_applied )
conn->EnqueueEvent(scheduled_analyzer_applied, nullptr,
conn->ConnVal(),
IntrusivePtr{NewRef{}, it->AsEnumVal()});
conn->ConnVal(), it->AsVal());
DBG_ANALYZER_ARGS(conn, "activated %s analyzer as scheduled",
analyzer_mgr->GetComponentName(*it).c_str());

View file

@ -6,7 +6,7 @@
const analyzer::Tag analyzer::Tag::Error;
analyzer::Tag::Tag(type_t type, subtype_t subtype)
: ::Tag(analyzer_mgr->GetTagEnumType(), type, subtype)
: ::Tag(analyzer_mgr->GetTagType(), type, subtype)
{
}
@ -16,7 +16,20 @@ analyzer::Tag& analyzer::Tag::operator=(const analyzer::Tag& other)
return *this;
}
const IntrusivePtr<EnumVal>& analyzer::Tag::AsVal() const
{
return ::Tag::AsVal(analyzer_mgr->GetTagType());
}
EnumVal* analyzer::Tag::AsEnumVal() const
{
return ::Tag::AsEnumVal(analyzer_mgr->GetTagEnumType());
return AsVal().get();
}
analyzer::Tag::Tag(IntrusivePtr<EnumVal> val)
: ::Tag(std::move(val))
{ }
analyzer::Tag::Tag(EnumVal* val)
: ::Tag({NewRef{}, val})
{ }

View file

@ -83,6 +83,9 @@ public:
*
* @param etype the script-layer enum type associated with the tag.
*/
const IntrusivePtr<EnumVal>& AsVal() const;
[[deprecated("Remove in v4.1. Use AsVal() instead.")]]
EnumVal* AsEnumVal() const;
static const Tag Error;
@ -109,7 +112,10 @@ protected:
*
* @param val An enum value of script type \c Analyzer::Tag.
*/
explicit Tag(EnumVal* val) : ::Tag(val) {}
explicit Tag(IntrusivePtr<EnumVal> val);
[[deprecated("Remove in v4.1. Construct from IntrusivePtr instead")]]
explicit Tag(EnumVal* val);
};
}

View file

@ -41,11 +41,12 @@ function Analyzer::__schedule_analyzer%(orig: addr, resp: addr, resp_p: port,
function __name%(atype: Analyzer::Tag%) : string
%{
return make_intrusive<StringVal>(analyzer_mgr->GetComponentName(atype));
const auto& n = analyzer_mgr->GetComponentName(IntrusivePtr{NewRef{}, atype->AsEnumVal()});
return make_intrusive<StringVal>(n);
%}
function __tag%(name: string%) : Analyzer::Tag
%{
analyzer::Tag t = analyzer_mgr->GetComponentTag(name->CheckString());
return IntrusivePtr{NewRef{}, t.AsEnumVal()};
return t.AsVal();
%}

View file

@ -156,12 +156,11 @@ void PIA_UDP::ActivateAnalyzer(analyzer::Tag tag, const Rule* rule)
if ( protocol_late_match )
{
// Queue late match event
EnumVal *tval = tag ? tag.AsEnumVal() : GetAnalyzerTag().AsEnumVal();
if ( ! tag )
tag = GetAnalyzerTag();
mgr.Enqueue(protocol_late_match,
ConnVal(),
IntrusivePtr{NewRef{}, tval}
);
const auto& tval = tag.AsVal();
mgr.Enqueue(protocol_late_match, ConnVal(), tval);
}
pkt_buffer.state = dpd_late_match_stop ? SKIPPING : MATCHING_ONLY;
@ -304,12 +303,11 @@ void PIA_TCP::ActivateAnalyzer(analyzer::Tag tag, const Rule* rule)
if ( protocol_late_match )
{
// Queue late match event
EnumVal *tval = tag ? tag.AsEnumVal() : GetAnalyzerTag().AsEnumVal();
if ( ! tag )
tag = GetAnalyzerTag();
mgr.Enqueue(protocol_late_match,
ConnVal(),
IntrusivePtr{NewRef{}, tval}
);
const auto& tval = tag.AsVal();
mgr.Enqueue(protocol_late_match, ConnVal(), tval);
}
stream_buffer.state = dpd_late_match_stop ? SKIPPING : MATCHING_ONLY;

View file

@ -21,7 +21,7 @@ static void analyzer_del_func(void* v)
AnalyzerSet::AnalyzerSet(File* arg_file) : file(arg_file)
{
auto t = make_intrusive<TypeList>();
t->Append({NewRef{}, file_mgr->GetTagEnumType()});
t->Append(file_mgr->GetTagType());
t->Append({NewRef{}, BifType::Record::Files::AnalyzerArgs});
analyzer_hash = new CompositeHash(std::move(t));
analyzer_map.SetDeleteFunc(analyzer_del_func);
@ -164,7 +164,7 @@ bool AnalyzerSet::RemoveMod::Perform(AnalyzerSet* set)
HashKey* AnalyzerSet::GetKey(const file_analysis::Tag& t, RecordVal* args) const
{
ListVal* lv = new ListVal(TYPE_ANY);
lv->Append({NewRef{}, t.AsEnumVal()});
lv->Append(t.AsVal());
lv->Append({NewRef{}, args});
HashKey* key = analyzer_hash->ComputeHash(lv, true);
Unref(lv);

View file

@ -422,13 +422,9 @@ string Manager::GetFileID(const analyzer::Tag& tag, Connection* c, bool is_orig)
DBG_LOG(DBG_FILE_ANALYSIS, "Raise get_file_handle() for protocol analyzer %s",
analyzer_mgr->GetComponentName(tag).c_str());
EnumVal* tagval = tag.AsEnumVal();
const auto& tagval = tag.AsVal();
mgr.Enqueue(get_file_handle,
IntrusivePtr{NewRef{}, tagval},
c->ConnVal(),
val_mgr->Bool(is_orig)
);
mgr.Enqueue(get_file_handle, tagval, c->ConnVal(), val_mgr->Bool(is_orig));
mgr.Drain(); // need file handle immediately so we don't have to buffer data
return current_file_id;
}

View file

@ -8,7 +8,7 @@ using namespace file_analysis;
const file_analysis::Tag file_analysis::Tag::Error;
file_analysis::Tag::Tag(type_t type, subtype_t subtype)
: ::Tag(file_mgr->GetTagEnumType(), type, subtype)
: ::Tag(file_mgr->GetTagType(), type, subtype)
{
}
@ -18,7 +18,20 @@ file_analysis::Tag& file_analysis::Tag::operator=(const file_analysis::Tag& othe
return *this;
}
const IntrusivePtr<EnumVal>& file_analysis::Tag::AsVal() const
{
return ::Tag::AsVal(file_mgr->GetTagType());
}
EnumVal* file_analysis::Tag::AsEnumVal() const
{
return ::Tag::AsEnumVal(file_mgr->GetTagEnumType());
return AsVal().get();
}
file_analysis::Tag::Tag(IntrusivePtr<EnumVal> val)
: ::Tag(std::move(val))
{ }
file_analysis::Tag::Tag(EnumVal* val)
: ::Tag({NewRef{}, val})
{ }

View file

@ -82,6 +82,9 @@ public:
*
* @param etype the script-layer enum type associated with the tag.
*/
const IntrusivePtr<EnumVal>& AsVal() const;
[[deprecated("Remove in v4.1. Use AsVal() instead.")]]
EnumVal* AsEnumVal() const;
static const Tag Error;
@ -107,7 +110,10 @@ protected:
*
* @param val An enum value of script type \c Files::Tag.
*/
explicit Tag(EnumVal* val) : ::Tag(val) {}
explicit Tag(IntrusivePtr<EnumVal> val);
[[deprecated("Remove in v4.1. Construct from IntrusivePtr instead.")]]
explicit Tag(EnumVal* val);
};
}

View file

@ -68,7 +68,8 @@ function Files::__stop%(file_id: string%): bool
## :zeek:see:`Files::analyzer_name`.
function Files::__analyzer_name%(tag: Files::Tag%) : string
%{
return make_intrusive<StringVal>(file_mgr->GetComponentName(tag));
const auto& n = file_mgr->GetComponentName(IntrusivePtr{NewRef{}, tag->AsEnumVal()});
return make_intrusive<StringVal>(n);
%}
## :zeek:see:`Files::file_exists`.

View file

@ -6,7 +6,7 @@
const input::Tag input::Tag::Error;
input::Tag::Tag(type_t type, subtype_t subtype)
: ::Tag(input_mgr->GetTagEnumType(), type, subtype)
: ::Tag(input_mgr->GetTagType(), type, subtype)
{
}
@ -16,7 +16,20 @@ input::Tag& input::Tag::operator=(const input::Tag& other)
return *this;
}
const IntrusivePtr<EnumVal>& input::Tag::AsVal() const
{
return ::Tag::AsVal(input_mgr->GetTagType());
}
EnumVal* input::Tag::AsEnumVal() const
{
return ::Tag::AsEnumVal(input_mgr->GetTagEnumType());
return AsVal().get();
}
input::Tag::Tag(IntrusivePtr<EnumVal> val)
: ::Tag(std::move(val))
{ }
input::Tag::Tag(EnumVal* val)
: ::Tag({NewRef{}, val})
{ }

View file

@ -83,6 +83,9 @@ public:
*
* @param etype the script-layer enum type associated with the tag.
*/
const IntrusivePtr<EnumVal>& AsVal() const;
[[deprecated("Remove in v4.1. Use AsVal() instead.")]]
EnumVal* AsEnumVal() const;
static const Tag Error;
@ -108,7 +111,10 @@ protected:
*
* @param val An enum value of script type \c Input::Reader.
*/
explicit Tag(EnumVal* val) : ::Tag(val) {}
explicit Tag(IntrusivePtr<EnumVal> val);
[[deprecated("Remove in v4.1. Construct from IntrusivePtr isntead.")]]
explicit Tag(EnumVal* val);
};
}

View file

@ -6,7 +6,7 @@
const logging::Tag logging::Tag::Error;
logging::Tag::Tag(type_t type, subtype_t subtype)
: ::Tag(log_mgr->GetTagEnumType(), type, subtype)
: ::Tag(log_mgr->GetTagType(), type, subtype)
{
}
@ -22,7 +22,20 @@ logging::Tag& logging::Tag::operator=(const logging::Tag&& other) noexcept
return *this;
}
const IntrusivePtr<EnumVal>& logging::Tag::AsVal() const
{
return ::Tag::AsVal(log_mgr->GetTagType());
}
EnumVal* logging::Tag::AsEnumVal() const
{
return ::Tag::AsEnumVal(log_mgr->GetTagEnumType());
return AsVal().get();
}
logging::Tag::Tag(IntrusivePtr<EnumVal> val)
: ::Tag(std::move(val))
{ }
logging::Tag::Tag(EnumVal* val)
: ::Tag({NewRef{}, val})
{ }

View file

@ -88,6 +88,9 @@ public:
*
* @param etype the script-layer enum type associated with the tag.
*/
const IntrusivePtr<EnumVal>& AsVal() const;
[[deprecated("Remove in v4.1. Use AsVal() instead.")]]
EnumVal* AsEnumVal() const;
static const Tag Error;
@ -113,7 +116,10 @@ protected:
*
* @param val An enum value of script type \c Log::Writer.
*/
explicit Tag(EnumVal* val) : ::Tag(val) {}
explicit Tag(IntrusivePtr<EnumVal> val);
[[deprecated("Remove in v4.1. Construct from IntrusivePtr instead.")]]
explicit Tag(EnumVal* val);
};
}

View file

@ -52,6 +52,9 @@ public:
/**
* @return The enum type associated with the script-layer "Tag".
*/
const IntrusivePtr<EnumType>& GetTagType() const;
[[deprecated("Remove in v4.1. Use GetTagType() instead.")]]
EnumType* GetTagEnumType() const;
/**
@ -68,6 +71,9 @@ public:
* @param val A component's enum value.
* @return The canonical component name.
*/
const std::string& GetComponentName(IntrusivePtr<EnumVal> val) const;
[[deprecated("Remove in v4.1. Use IntrusivePtr argument instead.")]]
const std::string& GetComponentName(Val* val) const;
/**
@ -156,6 +162,12 @@ std::list<C*> ComponentManager<T, C>::GetComponents() const
return rval;
}
template <class T, class C>
const IntrusivePtr<EnumType>& ComponentManager<T, C>::GetTagType() const
{
return tag_enum_type;
}
template <class T, class C>
EnumType* ComponentManager<T, C>::GetTagEnumType() const
{
@ -180,10 +192,16 @@ const std::string& ComponentManager<T, C>::GetComponentName(T tag) const
return error;
}
template <class T, class C>
const std::string& ComponentManager<T, C>::GetComponentName(IntrusivePtr<EnumVal> val) const
{
return GetComponentName(T(std::move(val)));
}
template <class T, class C>
const std::string& ComponentManager<T, C>::GetComponentName(Val* val) const
{
return GetComponentName(T(val->AsEnumVal()));
return GetComponentName(T({NewRef{}, val->AsEnumVal()}));
}
template <class T, class C>
@ -239,12 +257,12 @@ void ComponentManager<T, C>::RegisterComponent(C* component,
components_by_name.insert(std::make_pair(cname, component));
components_by_tag.insert(std::make_pair(component->Tag(), component));
components_by_val.insert(std::make_pair(
component->Tag().AsEnumVal()->InternalInt(), component));
component->Tag().AsVal()->InternalInt(), component));
// Install an identfier for enum value
std::string id = fmt("%s%s", prefix.c_str(), cname.c_str());
tag_enum_type->AddName(module, id.c_str(),
component->Tag().AsEnumVal()->InternalInt(), true,
component->Tag().AsVal()->InternalInt(), true,
nullptr);
}

View file

@ -35,7 +35,7 @@ static void write_plugin_section_heading(FILE* f, const plugin::Plugin* p)
static void write_analyzer_component(FILE* f, const analyzer::Component* c)
{
EnumType* atag = analyzer_mgr->GetTagEnumType();
const auto& atag = analyzer_mgr->GetTagType();
string tag = fmt("ANALYZER_%s", c->CanonicalName().c_str());
if ( atag->Lookup("Analyzer", tag.c_str()) < 0 )
@ -46,7 +46,7 @@ static void write_analyzer_component(FILE* f, const analyzer::Component* c)
static void write_analyzer_component(FILE* f, const file_analysis::Component* c)
{
EnumType* atag = file_mgr->GetTagEnumType();
const auto& atag = file_mgr->GetTagType();
string tag = fmt("ANALYZER_%s", c->CanonicalName().c_str());
if ( atag->Lookup("Files", tag.c_str()) < 0 )