Fix memory leak in Zeek when-statement bodies with runtime errors

This commit is contained in:
Jon Siwek 2020-03-23 21:50:00 -07:00
parent b045ce4bb3
commit 94656c2308
2 changed files with 19 additions and 6 deletions

View file

@ -321,9 +321,14 @@ bool Trigger::Eval()
delete [] pname; delete [] pname;
#endif #endif
trigger->Cache(frame->GetCall(), v.get()); auto queued = trigger->Cache(frame->GetCall(), v.get());
trigger->Release(); trigger->Release();
frame->ClearTrigger(); frame->ClearTrigger();
if ( ! queued && trigger->TimeoutValue() < 0 )
// Usually the parent-trigger would get unref'd either by
// its Eval() or its eventual Timeout(), but has neither
Unref(trigger);
} }
Unref(f); Unref(f);
@ -368,9 +373,14 @@ void Trigger::Timeout()
DBG_LOG(DBG_NOTIFIERS, "%s: trigger has parent %s, caching timeout result", Name(), pname); DBG_LOG(DBG_NOTIFIERS, "%s: trigger has parent %s, caching timeout result", Name(), pname);
delete [] pname; delete [] pname;
#endif #endif
trigger->Cache(frame->GetCall(), v.get()); auto queued = trigger->Cache(frame->GetCall(), v.get());
trigger->Release(); trigger->Release();
frame->ClearTrigger(); frame->ClearTrigger();
if ( ! queued && trigger->TimeoutValue() < 0 )
// Usually the parent-trigger would get unref'd either by
// its Eval() or its eventual Timeout(), but has neither
Unref(trigger);
} }
} }
@ -429,10 +439,10 @@ void Trigger::Attach(Trigger *trigger)
Hold(); Hold();
} }
void Trigger::Cache(const CallExpr* expr, Val* v) bool Trigger::Cache(const CallExpr* expr, Val* v)
{ {
if ( disabled || ! v ) if ( disabled || ! v )
return; return false;
ValCache::iterator i = cache.find(expr); ValCache::iterator i = cache.find(expr);
@ -448,6 +458,7 @@ void Trigger::Cache(const CallExpr* expr, Val* v)
Ref(v); Ref(v);
trigger_mgr->Queue(this); trigger_mgr->Queue(this);
return true;
} }

View file

@ -59,8 +59,10 @@ public:
// to the given trigger. Note, automatically calls Hold(). // to the given trigger. Note, automatically calls Hold().
void Attach(Trigger* trigger); void Attach(Trigger* trigger);
// Cache for return values of delayed function calls. // Cache for return values of delayed function calls. Returns whether
void Cache(const CallExpr* expr, Val* val); // the trigger is queued for later evaluation -- it may not be queued
// if the Val is null or it's disabled.
bool Cache(const CallExpr* expr, Val* val);
Val* Lookup(const CallExpr*); Val* Lookup(const CallExpr*);
// Disable this trigger completely. Needed because Unref'ing the trigger // Disable this trigger completely. Needed because Unref'ing the trigger