Disallow calling strings as functions

fixes #8040
This commit is contained in:
Gunnar Beutner 2014-12-12 20:40:24 +01:00
parent ae95918da0
commit 05485ea2d6
16 changed files with 35 additions and 75 deletions

View File

@ -896,7 +896,7 @@ Attributes:
Name |Description
----------------|----------------
methods |**Required.** The "execute" script method takes care of executing the check. In virtually all cases you should import the "plugin-check-command" template to take care of this setting.
execute |**Required.** The "execute" script method takes care of executing the check. In virtually all cases you should import the "plugin-check-command" template to take care of this setting.
command |**Required.** The command. This can either be an array of individual command arguments. Alternatively a string can be specified in which case the shell interpreter (usually /bin/sh) takes care of parsing the command. When using the "arguments" attribute this must be an array.
env |**Optional.** A dictionary of macros which should be exported as environment variables prior to executing the command.
vars |**Optional.** A dictionary containing custom attributes that are specific to this command.
@ -998,7 +998,7 @@ Attributes:
Name |Description
----------------|----------------
methods |**Required.** The "execute" script method takes care of executing the notification. In virtually all cases you should import the "plugin-notification-command" template to take care of this setting.
execute |**Required.** The "execute" script method takes care of executing the notification. In virtually all cases you should import the "plugin-notification-command" template to take care of this setting.
command |**Required.** The command. This can either be an array of individual command arguments. Alternatively a string can be specified in which case the shell interpreter (usually /bin/sh) takes care of parsing the command.
env |**Optional.** A dictionary of macros which should be exported as environment variables prior to executing the command.
vars |**Optional.** A dictionary containing custom attributes that are specific to this command.
@ -1026,7 +1026,7 @@ Attributes:
Name |Description
----------------|----------------
methods |**Required.** The "execute" script method takes care of executing the event handler. In virtually all cases you should import the "plugin-event-command" template to take care of this setting.
execute |**Required.** The "execute" script method takes care of executing the event handler. In virtually all cases you should import the "plugin-event-command" template to take care of this setting.
command |**Required.** The command. This can either be an array of individual command arguments. Alternatively a string can be specified in which case the shell interpreter (usually /bin/sh) takes care of parsing the command.
env |**Optional.** A dictionary of macros which should be exported as environment variables prior to executing the command.
vars |**Optional.** A dictionary containing custom attributes that are specific to this command.
@ -1130,7 +1130,7 @@ Attributes:
Name |Description
----------------|----------------
display_name |**Optional.** A short description of the time period.
methods |**Required.** The "update" script method takes care of updating the internal representation of the time period. In virtually all cases you should import the "legacy-timeperiod" template to take care of this setting.
update |**Required.** The "update" script method takes care of updating the internal representation of the time period. In virtually all cases you should import the "legacy-timeperiod" template to take care of this setting.
zone |**Optional.** The zone this object is a member of.
ranges |**Required.** A dictionary containing information which days and durations apply to this timeperiod.

View File

@ -20,29 +20,29 @@
library "methods"
template CheckCommand "icinga-check-command" {
methods.execute = "IcingaCheck"
execute = IcingaCheck
}
template CheckCommand "cluster-check-command" {
methods.execute = "ClusterCheck"
execute = ClusterCheck
}
template CheckCommand "cluster-zone-check-command" {
methods.execute = "ClusterZoneCheck"
execute = ClusterZoneCheck
}
template CheckCommand "plugin-check-command" {
methods.execute = "PluginCheck"
execute = PluginCheck
}
template CheckCommand "clr-check-command" {
methods.execute = "ClrCheck"
execute = ClrCheck
}
template NotificationCommand "plugin-notification-command" {
methods.execute = "PluginNotification"
execute = PluginNotification
}
template EventCommand "plugin-event-command" {
methods.execute = "PluginEvent"
execute = PluginEvent
}

View File

@ -18,5 +18,5 @@
******************************************************************************/
template TimePeriod "legacy-timeperiod" {
methods.update = "LegacyTimePeriod"
update = LegacyTimePeriod
}

View File

@ -219,35 +219,6 @@ void DynamicObject::SetAuthority(bool authority)
}
}
Value DynamicObject::InvokeMethod(const String& method,
const std::vector<Value>& arguments)
{
Dictionary::Ptr methods;
methods = GetMethods();
if (!methods)
BOOST_THROW_EXCEPTION(std::invalid_argument("Method '" + method + "' does not exist."));
Value funcName = methods->Get(method);
if (funcName.IsEmpty())
BOOST_THROW_EXCEPTION(std::invalid_argument("Method '" + method + "' does not exist."));
ScriptFunction::Ptr func;
if (funcName.IsObjectType<ScriptFunction>()) {
func = funcName;
} else {
func = ScriptFunction::GetByName(funcName);
if (!func)
BOOST_THROW_EXCEPTION(std::invalid_argument("Function '" + String(funcName) + "' does not exist."));
}
return func->Invoke(arguments);
}
void DynamicObject::DumpObjects(const String& filename, int attributeTypes)
{
Log(LogInformation, "DynamicObject")

View File

@ -50,8 +50,6 @@ public:
static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnResumed;
static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnStateChanged;
Value InvokeMethod(const String& method, const std::vector<Value>& arguments);
intrusive_ptr<DynamicType> GetType(void) const;
DebugInfo GetDebugInfo(void) const;

View File

@ -47,7 +47,6 @@ abstract class DynamicObject
[config, internal, get_protected] String type (TypeName);
[config] String zone;
[config, internal, get_protected] Array::Ptr templates;
[config] Dictionary::Ptr methods;
[get_protected] bool active;
[get_protected] bool paused {
default {{{ return true; }}}

View File

@ -32,8 +32,6 @@
%attribute %string "*"
},
%attribute %dictionary "methods",
%attribute %dictionary "vars"
}

View File

@ -224,7 +224,7 @@ Value LogicalOrExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) cons
Value FunctionCallExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
{
Value self, funcName;
Value self, vfunc;
if (!m_IName.empty()) {
Value result = m_IName[0]->Evaluate(frame);
@ -243,18 +243,23 @@ Value FunctionCallExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) c
self = result;
}
funcName = result;
vfunc= result;
}
if (m_FName)
funcName = m_FName->Evaluate(frame);
vfunc = m_FName->Evaluate(frame);
if (!vfunc.IsObjectType<ScriptFunction>())
BOOST_THROW_EXCEPTION(ScriptError("Argument is not a callable object.", GetDebugInfo()));
ScriptFunction::Ptr func = vfunc;
std::vector<Value> arguments;
BOOST_FOREACH(Expression *arg, m_Args) {
arguments.push_back(arg->Evaluate(frame));
}
return VMOps::FunctionCall(frame, self, funcName, arguments);
return VMOps::FunctionCall(frame, self, func, arguments);
}
Value ArrayExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const

View File

@ -58,18 +58,8 @@ public:
return ScriptVariable::Get(name);
}
static inline Value FunctionCall(ScriptFrame& frame, const Value& self, const Value& funcName, const std::vector<Value>& arguments)
static inline Value FunctionCall(ScriptFrame& frame, const Value& self, const ScriptFunction::Ptr& func, const std::vector<Value>& arguments)
{
ScriptFunction::Ptr func;
if (funcName.IsObjectType<ScriptFunction>())
func = funcName;
else
func = ScriptFunction::GetByName(funcName);
if (!func)
BOOST_THROW_EXCEPTION(ScriptError("Function '" + funcName + "' does not exist."));
boost::shared_ptr<ScriptFrame> vframe;
if (!self.IsEmpty())

View File

@ -32,5 +32,5 @@ void CheckCommand::Execute(const Checkable::Ptr& checkable, const CheckResult::P
arguments.push_back(cr);
arguments.push_back(resolvedMacros);
arguments.push_back(useResolvedMacros);
InvokeMethod("execute", arguments);
GetExecute()->Invoke(arguments);
}

View File

@ -18,6 +18,7 @@
******************************************************************************/
#include "icinga/customvarobject.hpp"
#include "base/scriptfunction.hpp"
namespace icinga
{
@ -30,6 +31,7 @@ abstract class Command : CustomVarObject
default {{{ return 60; }}}
};
[config] Dictionary::Ptr env;
[config] ScriptFunction::Ptr execute;
};
}

View File

@ -30,5 +30,5 @@ void EventCommand::Execute(const Checkable::Ptr& checkable,
arguments.push_back(checkable);
arguments.push_back(resolvedMacros);
arguments.push_back(useResolvedMacros);
InvokeMethod("execute", arguments);
GetExecute()->Invoke(arguments);
}

View File

@ -173,11 +173,8 @@
%type TimePeriod {
%attribute %string "display_name",
%require "methods",
%attribute %dictionary "methods" {
%require "update",
%attribute %string "update"
},
%require "update",
%attribute %any "update",
/* %if (methods.update == "LegacyTimePeriod") { */
// %require "ranges",
@ -189,11 +186,9 @@
%type Command {
%validator "ValidateCommandAttributes",
%require "methods",
%attribute %dictionary "methods" {
%require "execute",
%attribute %string "execute"
},
%require "execute",
%attribute %any "execute",
/* %if (methods.execute == "PluginNotification" || methods.execute == "PluginCheck" || methods.execute == "PluginEvent") { */
// %require "command",

View File

@ -37,5 +37,5 @@ Dictionary::Ptr NotificationCommand::Execute(const Notification::Ptr& notificati
arguments.push_back(comment);
arguments.push_back(resolvedMacros);
arguments.push_back(useResolvedMacros);
return InvokeMethod("execute", arguments);
return GetExecute()->Invoke(arguments);
}

View File

@ -199,7 +199,7 @@ void TimePeriod::UpdateRegion(double begin, double end, bool clearExisting)
arguments.push_back(begin);
arguments.push_back(end);
Array::Ptr segments = InvokeMethod("update", arguments);
Array::Ptr segments = GetUpdate()->Invoke(arguments);
{
ObjectLock olock(this);

View File

@ -18,6 +18,7 @@
******************************************************************************/
#include "icinga/customvarobject.hpp"
#include "base/scriptfunction.hpp"
namespace icinga
{
@ -33,6 +34,7 @@ class TimePeriod : CustomVarObject
}}}
};
[config] Dictionary::Ptr ranges;
[config] ScriptFunction::Ptr update;
[state] Value valid_begin;
[state] Value valid_end;
[state] Array::Ptr segments;