mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 08:08:19 +00:00
Experimental code to better handle interpreter errors.
Currently, a lot of interpreter runtime errors, such as an access to an unset optional record field, cause Bro to abort with an internal error. This is an experimental branch that turns such errors into non-fatal runtime errors by internally raising exceptions. These are caught upstream and processing continues afterwards. For now, not many errors actually raise exceptions (the example above does though). We'll need to go through them eventually and adapt the current Internal() calls (and potentially others). More generally, at some point we should cleanup the interpreter error handling (unifying errors reported at parse- and runtime; and switching to exceptions for all Expr/Stmt/Vals). But that's a larger change and left for later. The main question for now is if this code is already helpful enough to go into 2.0. It will quite likely prevent a number of crashes due to script errors.
This commit is contained in:
parent
0ec1fa6a53
commit
15ab287436
12 changed files with 213 additions and 38 deletions
|
@ -42,7 +42,17 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
|
||||||
{
|
{
|
||||||
val_list* args = new val_list;
|
val_list* args = new val_list;
|
||||||
args->append(BuildHeader(ip4));
|
args->append(BuildHeader(ip4));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
discard_packet = check_ip->Call(args)->AsBool();
|
discard_packet = check_ip->Call(args)->AsBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( InterpreterException& e )
|
||||||
|
{
|
||||||
|
discard_packet = false;
|
||||||
|
}
|
||||||
|
|
||||||
delete args;
|
delete args;
|
||||||
|
|
||||||
if ( discard_packet )
|
if ( discard_packet )
|
||||||
|
@ -90,7 +100,17 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
|
||||||
args->append(BuildHeader(ip4));
|
args->append(BuildHeader(ip4));
|
||||||
args->append(BuildHeader(tp, len));
|
args->append(BuildHeader(tp, len));
|
||||||
args->append(BuildData(data, th_len, len, caplen));
|
args->append(BuildData(data, th_len, len, caplen));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
discard_packet = check_tcp->Call(args)->AsBool();
|
discard_packet = check_tcp->Call(args)->AsBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( InterpreterException& e )
|
||||||
|
{
|
||||||
|
discard_packet = false;
|
||||||
|
}
|
||||||
|
|
||||||
delete args;
|
delete args;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +126,17 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
|
||||||
args->append(BuildHeader(ip4));
|
args->append(BuildHeader(ip4));
|
||||||
args->append(BuildHeader(up));
|
args->append(BuildHeader(up));
|
||||||
args->append(BuildData(data, uh_len, len, caplen));
|
args->append(BuildData(data, uh_len, len, caplen));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
discard_packet = check_udp->Call(args)->AsBool();
|
discard_packet = check_udp->Call(args)->AsBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( InterpreterException& e )
|
||||||
|
{
|
||||||
|
discard_packet = false;
|
||||||
|
}
|
||||||
|
|
||||||
delete args;
|
delete args;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +150,17 @@ int Discarder::NextPacket(const IP_Hdr* ip, int len, int caplen)
|
||||||
val_list* args = new val_list;
|
val_list* args = new val_list;
|
||||||
args->append(BuildHeader(ip4));
|
args->append(BuildHeader(ip4));
|
||||||
args->append(BuildHeader(ih));
|
args->append(BuildHeader(ih));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
discard_packet = check_icmp->Call(args)->AsBool();
|
discard_packet = check_icmp->Call(args)->AsBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( InterpreterException& e )
|
||||||
|
{
|
||||||
|
discard_packet = false;
|
||||||
|
}
|
||||||
|
|
||||||
delete args;
|
delete args;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,16 @@ protected:
|
||||||
if ( handler->ErrorHandler() )
|
if ( handler->ErrorHandler() )
|
||||||
reporter->BeginErrorHandler();
|
reporter->BeginErrorHandler();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
handler->Call(args, no_remote);
|
handler->Call(args, no_remote);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( InterpreterException& e )
|
||||||
|
{
|
||||||
|
// Already reported.
|
||||||
|
}
|
||||||
|
|
||||||
if ( obj )
|
if ( obj )
|
||||||
// obj->EventDone();
|
// obj->EventDone();
|
||||||
Unref(obj);
|
Unref(obj);
|
||||||
|
|
|
@ -68,6 +68,7 @@ void EventHandler::Call(val_list* vl, bool no_remote)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( local )
|
if ( local )
|
||||||
|
// No try/catch here; we pass exceptions upstream.
|
||||||
Unref(local->Call(vl));
|
Unref(local->Call(vl));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
10
src/Expr.cc
10
src/Expr.cc
|
@ -3118,8 +3118,9 @@ Val* FieldExpr::Fold(Val* v) const
|
||||||
return def_attr->AttrExpr()->Eval(0);
|
return def_attr->AttrExpr()->Eval(0);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Internal("field value missing");
|
reporter->ExprRuntimeError(this, "field value missing");
|
||||||
return 0;
|
assert(false);
|
||||||
|
return 0; // Will never get here, but compiler can't tell.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3730,6 +3731,7 @@ Val* RecordMatchExpr::Fold(Val* v1, Val* v2) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No try/catch here; we pass exceptions upstream.
|
||||||
Val* pred_val =
|
Val* pred_val =
|
||||||
match_rec->Lookup(pred_field_index)->AsFunc()->Call(&args);
|
match_rec->Lookup(pred_field_index)->AsFunc()->Call(&args);
|
||||||
bool is_zero = pred_val->IsZero();
|
bool is_zero = pred_val->IsZero();
|
||||||
|
@ -4220,7 +4222,7 @@ Val* FlattenExpr::Fold(Val* v) const
|
||||||
l->Append(fa->AttrExpr()->Eval(0));
|
l->Append(fa->AttrExpr()->Eval(0));
|
||||||
|
|
||||||
else
|
else
|
||||||
Internal("missing field value");
|
reporter->ExprRuntimeError(this, "missing field value");
|
||||||
}
|
}
|
||||||
|
|
||||||
return l;
|
return l;
|
||||||
|
@ -4646,7 +4648,7 @@ Val* CallExpr::Eval(Frame* f) const
|
||||||
|
|
||||||
if ( f )
|
if ( f )
|
||||||
f->SetCall(this);
|
f->SetCall(this);
|
||||||
ret = func->Call(v, f);
|
ret = func->Call(v, f); // No try/catch here; we pass exceptions upstream.
|
||||||
if ( f )
|
if ( f )
|
||||||
f->ClearCall();
|
f->ClearCall();
|
||||||
// Don't Unref() the arguments, as Func::Call already did that.
|
// Don't Unref() the arguments, as Func::Call already did that.
|
||||||
|
|
|
@ -888,9 +888,18 @@ bool LogMgr::Write(EnumVal* id, RecordVal* columns)
|
||||||
// to log this record.
|
// to log this record.
|
||||||
val_list vl(1);
|
val_list vl(1);
|
||||||
vl.append(columns->Ref());
|
vl.append(columns->Ref());
|
||||||
|
|
||||||
|
int result = 1;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
Val* v = filter->pred->Call(&vl);
|
Val* v = filter->pred->Call(&vl);
|
||||||
int result = v->AsBool();
|
int result = v->AsBool();
|
||||||
Unref(v);
|
Unref(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( InterpreterException& e )
|
||||||
|
{ /* Already reported. */ }
|
||||||
|
|
||||||
if ( ! result )
|
if ( ! result )
|
||||||
continue;
|
continue;
|
||||||
|
@ -920,7 +929,17 @@ bool LogMgr::Write(EnumVal* id, RecordVal* columns)
|
||||||
|
|
||||||
vl.append(rec_arg);
|
vl.append(rec_arg);
|
||||||
|
|
||||||
Val* v = filter->path_func->Call(&vl);
|
Val* v = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
v = filter->path_func->Call(&vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( InterpreterException& e )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! v->Type()->Tag() == TYPE_STRING )
|
if ( ! v->Type()->Tag() == TYPE_STRING )
|
||||||
{
|
{
|
||||||
|
@ -1569,9 +1588,19 @@ bool LogMgr::FinishedRotation(LogWriter* writer, string new_name, string old_nam
|
||||||
// Call the postprocessor function.
|
// Call the postprocessor function.
|
||||||
val_list vl(1);
|
val_list vl(1);
|
||||||
vl.append(info);
|
vl.append(info);
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
Val* v = func->Call(&vl);
|
Val* v = func->Call(&vl);
|
||||||
int result = v->AsBool();
|
result = v->AsBool();
|
||||||
Unref(v);
|
Unref(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( InterpreterException& e )
|
||||||
|
{ /* Already reported. */ }
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,9 +200,15 @@ void PersistenceSerializer::GotEvent(const char* name, double time,
|
||||||
void PersistenceSerializer::GotFunctionCall(const char* name, double time,
|
void PersistenceSerializer::GotFunctionCall(const char* name, double time,
|
||||||
Func* func, val_list* args)
|
Func* func, val_list* args)
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
func->Call(args);
|
func->Call(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
catch ( InterpreterException& e )
|
||||||
|
{ /* Already reported. */ }
|
||||||
|
}
|
||||||
|
|
||||||
void PersistenceSerializer::GotStateAccess(StateAccess* s)
|
void PersistenceSerializer::GotStateAccess(StateAccess* s)
|
||||||
{
|
{
|
||||||
s->Replay();
|
s->Replay();
|
||||||
|
|
|
@ -2809,9 +2809,15 @@ void RemoteSerializer::GotFunctionCall(const char* name, double time,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
function->Call(args);
|
function->Call(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
catch ( InterpreterException& e )
|
||||||
|
{ /* Already reported. */ }
|
||||||
|
}
|
||||||
|
|
||||||
void RemoteSerializer::GotID(ID* id, Val* val)
|
void RemoteSerializer::GotID(ID* id, Val* val)
|
||||||
{
|
{
|
||||||
++stats.ids.in;
|
++stats.ids.in;
|
||||||
|
|
|
@ -39,7 +39,7 @@ void Reporter::Info(const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
DoLog("", reporter_info, stderr, 0, 0, true, true, fmt, ap);
|
DoLog("", reporter_info, stderr, 0, 0, true, true, 0, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ void Reporter::Warning(const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
DoLog("warning", reporter_warning, stderr, 0, 0, true, true, fmt, ap);
|
DoLog("warning", reporter_warning, stderr, 0, 0, true, true, 0, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ void Reporter::Error(const char* fmt, ...)
|
||||||
++errors;
|
++errors;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
DoLog("error", reporter_error, stderr, 0, 0, true, true, fmt, ap);
|
DoLog("error", reporter_error, stderr, 0, 0, true, true, 0, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ void Reporter::FatalError(const char* fmt, ...)
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
|
||||||
// Always log to stderr.
|
// Always log to stderr.
|
||||||
DoLog("fatal error", 0, stderr, 0, 0, true, false, fmt, ap);
|
DoLog("fatal error", 0, stderr, 0, 0, true, false, 0, fmt, ap);
|
||||||
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ void Reporter::FatalErrorWithCore(const char* fmt, ...)
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
|
||||||
// Always log to stderr.
|
// Always log to stderr.
|
||||||
DoLog("fatal error", 0, stderr, 0, 0, true, false, fmt, ap);
|
DoLog("fatal error", 0, stderr, 0, 0, true, false, 0, fmt, ap);
|
||||||
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
|
@ -88,13 +88,29 @@ void Reporter::FatalErrorWithCore(const char* fmt, ...)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Reporter::ExprRuntimeError(const Expr* expr, const char* fmt, ...)
|
||||||
|
{
|
||||||
|
++errors;
|
||||||
|
|
||||||
|
ODesc d;
|
||||||
|
expr->Describe(&d);
|
||||||
|
|
||||||
|
PushLocation(expr->GetLocationInfo());
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
DoLog("expression error", reporter_error, stderr, 0, 0, true, true, d.Description(), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
PopLocation();
|
||||||
|
throw InterpreterException();
|
||||||
|
}
|
||||||
|
|
||||||
void Reporter::InternalError(const char* fmt, ...)
|
void Reporter::InternalError(const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
|
||||||
// Always log to stderr.
|
// Always log to stderr.
|
||||||
DoLog("internal error", 0, stderr, 0, 0, true, false, fmt, ap);
|
DoLog("internal error", 0, stderr, 0, 0, true, false, 0, fmt, ap);
|
||||||
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
|
@ -106,7 +122,7 @@ void Reporter::InternalWarning(const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
DoLog("internal warning", reporter_warning, stderr, 0, 0, true, true, fmt, ap);
|
DoLog("internal warning", reporter_warning, stderr, 0, 0, true, true, 0, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +149,7 @@ void Reporter::WeirdHelper(EventHandlerPtr event, Val* conn_val, const char* add
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt_name);
|
va_start(ap, fmt_name);
|
||||||
DoLog("weird", event, stderr, 0, vl, false, false, fmt_name, ap);
|
DoLog("weird", event, stderr, 0, vl, false, false, 0, fmt_name, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
delete vl;
|
delete vl;
|
||||||
|
@ -147,7 +163,7 @@ void Reporter::WeirdFlowHelper(const uint32* orig, const uint32* resp, const cha
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt_name);
|
va_start(ap, fmt_name);
|
||||||
DoLog("weird", flow_weird, stderr, 0, vl, false, false, fmt_name, ap);
|
DoLog("weird", flow_weird, stderr, 0, vl, false, false, 0, fmt_name, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
delete vl;
|
delete vl;
|
||||||
|
@ -173,7 +189,7 @@ void Reporter::Weird(const uint32* orig, const uint32* resp, const char* name)
|
||||||
WeirdFlowHelper(orig, resp, "%s", name);
|
WeirdFlowHelper(orig, resp, "%s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reporter::DoLog(const char* prefix, EventHandlerPtr event, FILE* out, Connection* conn, val_list* addl, bool location, bool time, const char* fmt, va_list ap)
|
void Reporter::DoLog(const char* prefix, EventHandlerPtr event, FILE* out, Connection* conn, val_list* addl, bool location, bool time, const char* postfix, const char* fmt, va_list ap)
|
||||||
{
|
{
|
||||||
static char tmp[512];
|
static char tmp[512];
|
||||||
|
|
||||||
|
@ -235,6 +251,9 @@ void Reporter::DoLog(const char* prefix, EventHandlerPtr event, FILE* out, Conne
|
||||||
int n = vsnprintf(buffer, size, fmt, aq);
|
int n = vsnprintf(buffer, size, fmt, aq);
|
||||||
va_end(aq);
|
va_end(aq);
|
||||||
|
|
||||||
|
if ( postfix )
|
||||||
|
n += strlen(postfix) + 10; // Add a bit of slack.
|
||||||
|
|
||||||
if ( n > -1 && n < size )
|
if ( n > -1 && n < size )
|
||||||
// We had enough space;
|
// We had enough space;
|
||||||
break;
|
break;
|
||||||
|
@ -247,6 +266,11 @@ void Reporter::DoLog(const char* prefix, EventHandlerPtr event, FILE* out, Conne
|
||||||
FatalError("out of memory in Reporter");
|
FatalError("out of memory in Reporter");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( postfix )
|
||||||
|
// Note, if you change this fmt string, adjust the additional
|
||||||
|
// buffer size above.
|
||||||
|
sprintf(buffer + strlen(buffer), " [%s]", postfix);
|
||||||
|
|
||||||
if ( event && via_events && ! in_error_handler )
|
if ( event && via_events && ! in_error_handler )
|
||||||
{
|
{
|
||||||
val_list* vl = new val_list;
|
val_list* vl = new val_list;
|
||||||
|
|
|
@ -14,6 +14,22 @@
|
||||||
|
|
||||||
class Connection;
|
class Connection;
|
||||||
class Location;
|
class Location;
|
||||||
|
class Reporter;
|
||||||
|
|
||||||
|
// One cannot raise this exception directly, go through the
|
||||||
|
// Reporter's methods instead.
|
||||||
|
|
||||||
|
class ReporterException {
|
||||||
|
protected:
|
||||||
|
friend class Reporter;
|
||||||
|
ReporterException() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class InterpreterException : public ReporterException {
|
||||||
|
protected:
|
||||||
|
friend class Reporter;
|
||||||
|
InterpreterException() {}
|
||||||
|
};
|
||||||
|
|
||||||
class Reporter {
|
class Reporter {
|
||||||
public:
|
public:
|
||||||
|
@ -42,6 +58,10 @@ public:
|
||||||
// reported and always generate a core dump.
|
// reported and always generate a core dump.
|
||||||
void FatalErrorWithCore(const char* fmt, ...);
|
void FatalErrorWithCore(const char* fmt, ...);
|
||||||
|
|
||||||
|
// Report a runtime error in evaluating a Bro script expression. This
|
||||||
|
// function will not return but raise an InterpreterException.
|
||||||
|
void ExprRuntimeError(const Expr* expr, const char* fmt, ...);
|
||||||
|
|
||||||
// Report a traffic weirdness, i.e., an unexpected protocol situation
|
// Report a traffic weirdness, i.e., an unexpected protocol situation
|
||||||
// that may lead to incorrectly processing a connnection.
|
// that may lead to incorrectly processing a connnection.
|
||||||
void Weird(const char* name); // Raises net_weird().
|
void Weird(const char* name); // Raises net_weird().
|
||||||
|
@ -87,7 +107,9 @@ public:
|
||||||
void EndErrorHandler() { --in_error_handler; }
|
void EndErrorHandler() { --in_error_handler; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DoLog(const char* prefix, EventHandlerPtr event, FILE* out, Connection* conn, val_list* addl, bool location, bool time, const char* fmt, va_list ap);
|
void DoLog(const char* prefix, EventHandlerPtr event, FILE* out,
|
||||||
|
Connection* conn, val_list* addl, bool location, bool time,
|
||||||
|
const char* postfix, const char* fmt, va_list ap);
|
||||||
|
|
||||||
// The order if addl, name needs to be like that since fmt_name can
|
// The order if addl, name needs to be like that since fmt_name can
|
||||||
// contain format specifiers
|
// contain format specifiers
|
||||||
|
|
|
@ -149,9 +149,19 @@ bool RuleConditionEval::DoMatch(Rule* rule, RuleEndpointState* state,
|
||||||
else
|
else
|
||||||
args.append(new StringVal(""));
|
args.append(new StringVal(""));
|
||||||
|
|
||||||
|
bool result = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
Val* val = id->ID_Val()->AsFunc()->Call(&args);
|
Val* val = id->ID_Val()->AsFunc()->Call(&args);
|
||||||
bool result = val->AsBool();
|
result = val->AsBool();
|
||||||
Unref(val);
|
Unref(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( InterpreterException& e )
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -331,7 +331,14 @@ void NetSessions::NextPacketSecondary(double /* t */, const struct pcap_pkthdr*
|
||||||
args->append(cmd_val);
|
args->append(cmd_val);
|
||||||
args->append(BuildHeader(ip));
|
args->append(BuildHeader(ip));
|
||||||
// ### Need to queue event here.
|
// ### Need to queue event here.
|
||||||
|
try
|
||||||
|
{
|
||||||
sp->Event()->Event()->Call(args);
|
sp->Event()->Event()->Call(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( InterpreterException& e )
|
||||||
|
{ /* Already reported. */ }
|
||||||
|
|
||||||
delete args;
|
delete args;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
23
src/Val.cc
23
src/Val.cc
|
@ -2007,7 +2007,16 @@ Val* TableVal::Default(Val* index)
|
||||||
else
|
else
|
||||||
vl->append(index->Ref());
|
vl->append(index->Ref());
|
||||||
|
|
||||||
Val* result = f->Call(vl);
|
Val* result = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = f->Call(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( InterpreterException& e )
|
||||||
|
{ /* Already reported. */ }
|
||||||
|
|
||||||
delete vl;
|
delete vl;
|
||||||
|
|
||||||
if ( ! result )
|
if ( ! result )
|
||||||
|
@ -2466,10 +2475,20 @@ double TableVal::CallExpireFunc(Val* idx)
|
||||||
|
|
||||||
vl->append(idx);
|
vl->append(idx);
|
||||||
|
|
||||||
|
double secs;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
Val* vs = expire_expr->Eval(0)->AsFunc()->Call(vl);
|
Val* vs = expire_expr->Eval(0)->AsFunc()->Call(vl);
|
||||||
double secs = vs->AsInterval();
|
secs = vs->AsInterval();
|
||||||
Unref(vs);
|
Unref(vs);
|
||||||
delete vl;
|
delete vl;
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( InterpreterException& e )
|
||||||
|
{
|
||||||
|
secs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return secs;
|
return secs;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue