mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 07:38:19 +00:00
GH-527: fix ref-counting issues in Frame unserialization
Coverity CIDs 1403968, 1403967
This commit is contained in:
parent
3080290a5e
commit
05bc680d3f
1 changed files with 57 additions and 6 deletions
63
src/Frame.cc
63
src/Frame.cc
|
@ -33,10 +33,11 @@ Frame::~Frame()
|
||||||
{
|
{
|
||||||
// Deleting a Frame that is a view is a no-op.
|
// Deleting a Frame that is a view is a no-op.
|
||||||
Unref(trigger);
|
Unref(trigger);
|
||||||
|
|
||||||
if ( closure )
|
|
||||||
Unref(closure);
|
Unref(closure);
|
||||||
|
|
||||||
|
for ( auto& i : outer_ids )
|
||||||
|
Unref(i);
|
||||||
|
|
||||||
Release();
|
Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,32 +318,57 @@ std::pair<bool, Frame*> Frame::Unserialize(const broker::vector& data)
|
||||||
|
|
||||||
has_vec = broker::get_if<broker::vector>(*where);
|
has_vec = broker::get_if<broker::vector>(*where);
|
||||||
if ( ! has_vec )
|
if ( ! has_vec )
|
||||||
|
{
|
||||||
|
for ( auto& i : outer_ids )
|
||||||
|
Unref(i);
|
||||||
|
|
||||||
return std::make_pair(false, nullptr);
|
return std::make_pair(false, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
std::advance(where, 1);
|
std::advance(where, 1);
|
||||||
|
|
||||||
auto closure_pair = Frame::Unserialize(*has_vec);
|
auto closure_pair = Frame::Unserialize(*has_vec);
|
||||||
if ( ! closure_pair.first )
|
if ( ! closure_pair.first )
|
||||||
|
{
|
||||||
|
for ( auto& i : outer_ids )
|
||||||
|
Unref(i);
|
||||||
|
|
||||||
return std::make_pair(false, nullptr);
|
return std::make_pair(false, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
closure = closure_pair.second;
|
closure = closure_pair.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto has_vec = broker::get_if<broker::vector>(*where);
|
auto has_vec = broker::get_if<broker::vector>(*where);
|
||||||
if ( ! has_vec )
|
if ( ! has_vec )
|
||||||
|
{
|
||||||
|
for ( auto& i : outer_ids )
|
||||||
|
Unref(i);
|
||||||
|
|
||||||
return std::make_pair(false, nullptr);
|
return std::make_pair(false, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
std::advance(where, 1);
|
std::advance(where, 1);
|
||||||
|
|
||||||
auto map_pair = UnserializeOffsetMap(*has_vec);
|
auto map_pair = UnserializeOffsetMap(*has_vec);
|
||||||
if ( ! map_pair.first )
|
if ( ! map_pair.first )
|
||||||
|
{
|
||||||
|
for ( auto& i : outer_ids )
|
||||||
|
Unref(i);
|
||||||
|
|
||||||
return std::make_pair(false, nullptr);
|
return std::make_pair(false, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
offset_map = std::move(map_pair.second);
|
offset_map = std::move(map_pair.second);
|
||||||
|
|
||||||
auto has_body = broker::get_if<broker::vector>(*where);
|
auto has_body = broker::get_if<broker::vector>(*where);
|
||||||
if ( ! has_body )
|
if ( ! has_body )
|
||||||
|
{
|
||||||
|
for ( auto& i : outer_ids )
|
||||||
|
Unref(i);
|
||||||
|
|
||||||
return std::make_pair(false, nullptr);
|
return std::make_pair(false, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
broker::vector body = *has_body;
|
broker::vector body = *has_body;
|
||||||
int frame_size = body.size();
|
int frame_size = body.size();
|
||||||
|
@ -350,6 +376,7 @@ std::pair<bool, Frame*> Frame::Unserialize(const broker::vector& data)
|
||||||
// We'll associate this frame with a function later.
|
// We'll associate this frame with a function later.
|
||||||
Frame* rf = new Frame(frame_size, nullptr, nullptr);
|
Frame* rf = new Frame(frame_size, nullptr, nullptr);
|
||||||
rf->offset_map = std::move(offset_map);
|
rf->offset_map = std::move(offset_map);
|
||||||
|
// Frame takes ownership of unref'ing elements in outer_ids
|
||||||
rf->outer_ids = std::move(outer_ids);
|
rf->outer_ids = std::move(outer_ids);
|
||||||
rf->closure = closure;
|
rf->closure = closure;
|
||||||
|
|
||||||
|
@ -361,18 +388,27 @@ std::pair<bool, Frame*> Frame::Unserialize(const broker::vector& data)
|
||||||
|
|
||||||
broker::vector val_tuple = *has_vec;
|
broker::vector val_tuple = *has_vec;
|
||||||
if ( val_tuple.size() != 2 )
|
if ( val_tuple.size() != 2 )
|
||||||
|
{
|
||||||
|
Unref(rf);
|
||||||
return std::make_pair(false, nullptr);
|
return std::make_pair(false, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
auto has_type = broker::get_if<broker::integer>(val_tuple[1]);
|
auto has_type = broker::get_if<broker::integer>(val_tuple[1]);
|
||||||
if ( ! has_type )
|
if ( ! has_type )
|
||||||
|
{
|
||||||
|
Unref(rf);
|
||||||
return std::make_pair(false, nullptr);
|
return std::make_pair(false, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
broker::integer g = *has_type;
|
broker::integer g = *has_type;
|
||||||
BroType t( static_cast<TypeTag>(g) );
|
BroType t( static_cast<TypeTag>(g) );
|
||||||
|
|
||||||
Val* val = bro_broker::data_to_val(std::move(val_tuple[0]), &t);
|
Val* val = bro_broker::data_to_val(std::move(val_tuple[0]), &t);
|
||||||
if ( ! val )
|
if ( ! val )
|
||||||
|
{
|
||||||
|
Unref(rf);
|
||||||
return std::make_pair(false, nullptr);
|
return std::make_pair(false, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
rf->frame[i] = val;
|
rf->frame[i] = val;
|
||||||
}
|
}
|
||||||
|
@ -391,10 +427,14 @@ void Frame::AddKnownOffsets(const id_list& ids)
|
||||||
|
|
||||||
void Frame::CaptureClosure(Frame* c, id_list arg_outer_ids)
|
void Frame::CaptureClosure(Frame* c, id_list arg_outer_ids)
|
||||||
{
|
{
|
||||||
if ( closure )
|
if ( closure || outer_ids.length() )
|
||||||
reporter->InternalError("Attempted to override a closure.");
|
reporter->InternalError("Attempted to override a closure.");
|
||||||
|
|
||||||
outer_ids = std::move(arg_outer_ids);
|
outer_ids = std::move(arg_outer_ids);
|
||||||
|
|
||||||
|
for ( auto& i : outer_ids )
|
||||||
|
::Ref(i);
|
||||||
|
|
||||||
closure = c;
|
closure = c;
|
||||||
if ( closure )
|
if ( closure )
|
||||||
Ref(closure);
|
Ref(closure);
|
||||||
|
@ -467,16 +507,27 @@ Frame::UnserializeIDList(const broker::vector& data)
|
||||||
{
|
{
|
||||||
auto has_name = broker::get_if<std::string>(*where);
|
auto has_name = broker::get_if<std::string>(*where);
|
||||||
if ( ! has_name )
|
if ( ! has_name )
|
||||||
return std::make_pair(false, std::move(rval));
|
{
|
||||||
|
for ( auto& i : rval )
|
||||||
|
Unref(i);
|
||||||
|
|
||||||
ID* id = new ID(has_name->c_str(), SCOPE_FUNCTION, false);
|
rval = id_list{};
|
||||||
|
return std::make_pair(false, std::move(rval));
|
||||||
|
}
|
||||||
|
|
||||||
std::advance(where, 1);
|
std::advance(where, 1);
|
||||||
|
|
||||||
auto has_offset = broker::get_if<broker::integer>(*where);
|
auto has_offset = broker::get_if<broker::integer>(*where);
|
||||||
if ( ! has_offset )
|
if ( ! has_offset )
|
||||||
return std::make_pair(false, std::move(rval));
|
{
|
||||||
|
for ( auto& i : rval )
|
||||||
|
Unref(i);
|
||||||
|
|
||||||
|
rval = id_list{};
|
||||||
|
return std::make_pair(false, std::move(rval));
|
||||||
|
}
|
||||||
|
|
||||||
|
ID* id = new ID(has_name->c_str(), SCOPE_FUNCTION, false);
|
||||||
id->SetOffset(*has_offset);
|
id->SetOffset(*has_offset);
|
||||||
rval.push_back(id);
|
rval.push_back(id);
|
||||||
std::advance(where, 1);
|
std::advance(where, 1);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue