From: Noah Hilverling Date: Tue, 30 Jan 2018 10:26:07 +0000 (+0100) Subject: Add marco RequireNotNull X-Git-Tag: v2.8.2~45 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3ba509086771b75654c76ccb81f38e0d869be25a;p=icinga2 Add marco RequireNotNull This is used to fix a number of possible nullptr dereferences --- diff --git a/lib/base/array-script.cpp b/lib/base/array-script.cpp index 568037d9e..b9535ef98 100644 --- a/lib/base/array-script.cpp +++ b/lib/base/array-script.cpp @@ -30,6 +30,7 @@ static double ArrayLen(void) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); return self->GetLength(); } @@ -37,6 +38,7 @@ static void ArraySet(int index, const Value& value) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); self->Set(index, value); } @@ -44,6 +46,7 @@ static Value ArrayGet(int index) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); return self->Get(index); } @@ -51,6 +54,7 @@ static void ArrayAdd(const Value& value) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); self->Add(value); } @@ -58,6 +62,7 @@ static void ArrayRemove(int index) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); self->Remove(index); } @@ -65,6 +70,7 @@ static bool ArrayContains(const Value& value) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); return self->Contains(value); } @@ -72,6 +78,7 @@ static void ArrayClear(void) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); self->Clear(); } @@ -87,6 +94,7 @@ static Array::Ptr ArraySort(const std::vector& args) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); Array::Ptr arr = self->ShallowClone(); @@ -110,6 +118,7 @@ static Array::Ptr ArrayShallowClone(void) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); return self->ShallowClone(); } @@ -117,6 +126,7 @@ static Value ArrayJoin(const Value& separator) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); Value result; bool first = true; @@ -139,6 +149,7 @@ static Array::Ptr ArrayReverse(void) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); return self->Reverse(); } @@ -146,6 +157,7 @@ static Array::Ptr ArrayMap(const Function::Ptr& function) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); if (vframe->Sandboxed && !function->IsSideEffectFree()) BOOST_THROW_EXCEPTION(ScriptError("Map function must be side-effect free.")); @@ -166,6 +178,7 @@ static Value ArrayReduce(const Function::Ptr& function) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); if (vframe->Sandboxed && !function->IsSideEffectFree()) BOOST_THROW_EXCEPTION(ScriptError("Reduce function must be side-effect free.")); @@ -190,6 +203,7 @@ static Array::Ptr ArrayFilter(const Function::Ptr& function) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); if (vframe->Sandboxed && !function->IsSideEffectFree()) BOOST_THROW_EXCEPTION(ScriptError("Filter function must be side-effect free.")); @@ -211,6 +225,7 @@ static bool ArrayAny(const Function::Ptr& function) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); if (vframe->Sandboxed && !function->IsSideEffectFree()) BOOST_THROW_EXCEPTION(ScriptError("Filter function must be side-effect free.")); @@ -230,6 +245,7 @@ static bool ArrayAll(const Function::Ptr& function) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); if (vframe->Sandboxed && !function->IsSideEffectFree()) BOOST_THROW_EXCEPTION(ScriptError("Filter function must be side-effect free.")); @@ -248,6 +264,7 @@ static Array::Ptr ArrayUnique(void) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); std::set result; diff --git a/lib/base/configobject-script.cpp b/lib/base/configobject-script.cpp index dfe4455b6..30d22ceff 100644 --- a/lib/base/configobject-script.cpp +++ b/lib/base/configobject-script.cpp @@ -29,6 +29,7 @@ static void ConfigObjectModifyAttribute(const String& attr, const Value& value) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); ConfigObject::Ptr self = vframe->Self; + RequireNotNull(self); return self->ModifyAttribute(attr, value); } @@ -36,6 +37,7 @@ static void ConfigObjectRestoreAttribute(const String& attr) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); ConfigObject::Ptr self = vframe->Self; + RequireNotNull(self); return self->RestoreAttribute(attr); } diff --git a/lib/base/datetime-script.cpp b/lib/base/datetime-script.cpp index 7d9a14cc2..2e2f2f10b 100644 --- a/lib/base/datetime-script.cpp +++ b/lib/base/datetime-script.cpp @@ -29,6 +29,7 @@ static String DateTimeFormat(const String& format) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); DateTime::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); return self->Format(format); } diff --git a/lib/base/dictionary-script.cpp b/lib/base/dictionary-script.cpp index 66aa26cbd..9059a0a51 100644 --- a/lib/base/dictionary-script.cpp +++ b/lib/base/dictionary-script.cpp @@ -29,6 +29,7 @@ static double DictionaryLen(void) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Dictionary::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); return self->GetLength(); } @@ -36,6 +37,7 @@ static void DictionarySet(const String& key, const Value& value) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Dictionary::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); self->Set(key, value); } @@ -43,6 +45,7 @@ static Value DictionaryGet(const String& key) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Dictionary::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); return self->Get(key); } @@ -50,6 +53,7 @@ static void DictionaryRemove(const String& key) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Dictionary::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); self->Remove(key); } @@ -57,6 +61,7 @@ static bool DictionaryContains(const String& key) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Dictionary::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); return self->Contains(key); } @@ -64,6 +69,7 @@ static Dictionary::Ptr DictionaryShallowClone(void) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Dictionary::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); return self->ShallowClone(); } @@ -72,6 +78,8 @@ static Array::Ptr DictionaryKeys(void) ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Dictionary::Ptr self = static_cast(vframe->Self); Array::Ptr keys = new Array(); + RequireNotNull(self); + ObjectLock olock(self); for (const Dictionary::Pair& kv : self) { keys->Add(kv.first); @@ -84,6 +92,8 @@ static Array::Ptr DictionaryValues(void) ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Dictionary::Ptr self = static_cast(vframe->Self); Array::Ptr keys = new Array(); + RequireNotNull(self); + ObjectLock olock(self); for (const Dictionary::Pair& kv : self) { keys->Add(kv.second); diff --git a/lib/base/function-script.cpp b/lib/base/function-script.cpp index dab4255de..cd40feacb 100644 --- a/lib/base/function-script.cpp +++ b/lib/base/function-script.cpp @@ -32,6 +32,7 @@ static Value FunctionCall(const std::vector& args) ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Function::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); std::vector uargs(args.begin() + 1, args.end()); return self->Invoke(args[0], uargs); @@ -41,6 +42,7 @@ static Value FunctionCallV(const Value& thisArg, const Array::Ptr& args) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Function::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); std::vector uargs; diff --git a/lib/base/object-script.cpp b/lib/base/object-script.cpp index c8112a402..27bc487da 100644 --- a/lib/base/object-script.cpp +++ b/lib/base/object-script.cpp @@ -29,6 +29,7 @@ static String ObjectToString(void) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Object::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); return self->ToString(); } @@ -36,6 +37,7 @@ static void ObjectNotifyAttribute(const String& attribute) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Object::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); self->NotifyField(self->GetReflectionType()->GetFieldId(attribute)); } @@ -43,6 +45,7 @@ static Object::Ptr ObjectClone(void) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Object::Ptr self = static_cast(vframe->Self); + RequireNotNull(self); return self->Clone(); } diff --git a/lib/base/object.cpp b/lib/base/object.cpp index e9f3cd1bd..b261fefe6 100644 --- a/lib/base/object.cpp +++ b/lib/base/object.cpp @@ -261,3 +261,8 @@ INITIALIZE_ONCE([]() { }); #endif /* I2_LEAK_DEBUG */ +void icinga::RequireNotNullInternal(const intrusive_ptr& object, const char *description) +{ + if (!object) + BOOST_THROW_EXCEPTION(std::invalid_argument("Pointer must not be null: " + String(description))); +} diff --git a/lib/base/object.hpp b/lib/base/object.hpp index d3abc4648..6159c5b5e 100644 --- a/lib/base/object.hpp +++ b/lib/base/object.hpp @@ -62,6 +62,10 @@ extern I2_BASE_API Value Empty; DECLARE_PTR_TYPEDEFS(klass); \ IMPL_TYPE_LOOKUP(); +#define RequireNotNull(ptr) RequireNotNullInternal(ptr, #ptr) + +I2_BASE_API void RequireNotNullInternal(const intrusive_ptr& object, const char *description); + template intrusive_ptr DefaultObjectFactory(const std::vector& args) { diff --git a/lib/base/typetype-script.cpp b/lib/base/typetype-script.cpp index 5189845b3..591de4667 100644 --- a/lib/base/typetype-script.cpp +++ b/lib/base/typetype-script.cpp @@ -37,7 +37,8 @@ static void TypeRegisterAttributeHandler(const String& fieldName, const Function { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Type::Ptr self = static_cast(vframe->Self); - + RequireNotNull(self); + int fid = self->GetFieldId(fieldName); self->RegisterAttributeHandler(fid, boost::bind(&InvokeAttributeHandlerHelper, callback, _1, _2)); } diff --git a/lib/icinga/checkable-script.cpp b/lib/icinga/checkable-script.cpp index 40626fef9..f7ba56e80 100644 --- a/lib/icinga/checkable-script.cpp +++ b/lib/icinga/checkable-script.cpp @@ -30,6 +30,7 @@ static void CheckableProcessCheckResult(const CheckResult::Ptr& cr) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Checkable::Ptr self = vframe->Self; + RequireNotNull(self); self->ProcessCheckResult(cr); } diff --git a/lib/icinga/macroprocessor.cpp b/lib/icinga/macroprocessor.cpp index 2027ef82f..ac45f1c90 100644 --- a/lib/icinga/macroprocessor.cpp +++ b/lib/icinga/macroprocessor.cpp @@ -40,6 +40,9 @@ Value MacroProcessor::ResolveMacros(const Value& str, const ResolverList& resolv const MacroProcessor::EscapeCallback& escapeFn, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros, int recursionLevel) { + if (useResolvedMacros) + RequireNotNull(resolvedMacros); + Value result; if (str.IsEmpty()) @@ -454,6 +457,9 @@ Value MacroProcessor::ResolveArguments(const Value& command, const Dictionary::P const MacroProcessor::ResolverList& resolvers, const CheckResult::Ptr& cr, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros, int recursionLevel) { + if (useResolvedMacros) + RequireNotNull(resolvedMacros); + Value resolvedCommand; if (!arguments || command.IsObjectType() || command.IsObjectType()) resolvedCommand = MacroProcessor::ResolveMacros(command, resolvers, cr, NULL, diff --git a/lib/methods/clusterchecktask.cpp b/lib/methods/clusterchecktask.cpp index 2ad7f6578..513a5a475 100644 --- a/lib/methods/clusterchecktask.cpp +++ b/lib/methods/clusterchecktask.cpp @@ -38,6 +38,9 @@ REGISTER_SCRIPTFUNCTION_NS(Internal, ClusterCheck, &ClusterCheckTask::ScriptFunc void ClusterCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) { + RequireNotNull(checkable); + RequireNotNull(cr); + if (resolvedMacros && !useResolvedMacros) return; diff --git a/lib/methods/clusterzonechecktask.cpp b/lib/methods/clusterzonechecktask.cpp index 919e7fbed..699ef9bf3 100644 --- a/lib/methods/clusterzonechecktask.cpp +++ b/lib/methods/clusterzonechecktask.cpp @@ -34,6 +34,9 @@ REGISTER_SCRIPTFUNCTION_NS(Internal, ClusterZoneCheck, &ClusterZoneCheckTask::Sc void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) { + RequireNotNull(checkable); + RequireNotNull(cr); + ApiListener::Ptr listener = ApiListener::GetInstance(); if (!listener) { diff --git a/lib/methods/exceptionchecktask.cpp b/lib/methods/exceptionchecktask.cpp index 0410621ab..120264327 100644 --- a/lib/methods/exceptionchecktask.cpp +++ b/lib/methods/exceptionchecktask.cpp @@ -34,6 +34,9 @@ REGISTER_SCRIPTFUNCTION_NS(Internal, ExceptionCheck, &ExceptionCheckTask::Script void ExceptionCheckTask::ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) { + RequireNotNull(service); + RequireNotNull(cr); + if (resolvedMacros && !useResolvedMacros) return; diff --git a/lib/methods/icingachecktask.cpp b/lib/methods/icingachecktask.cpp index 3a4b668a9..d96dfedd1 100644 --- a/lib/methods/icingachecktask.cpp +++ b/lib/methods/icingachecktask.cpp @@ -35,6 +35,9 @@ REGISTER_SCRIPTFUNCTION_NS(Internal, IcingaCheck, &IcingaCheckTask::ScriptFunc, void IcingaCheckTask::ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) { + RequireNotNull(service); + RequireNotNull(cr); + if (resolvedMacros && !useResolvedMacros) return; diff --git a/lib/methods/nullchecktask.cpp b/lib/methods/nullchecktask.cpp index 09b060c2b..50d2409a1 100644 --- a/lib/methods/nullchecktask.cpp +++ b/lib/methods/nullchecktask.cpp @@ -32,9 +32,12 @@ using namespace icinga; REGISTER_SCRIPTFUNCTION_NS(Internal, NullCheck, &NullCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros"); -void NullCheckTask::ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr, +void NullCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) { + RequireNotNull(checkable); + RequireNotNull(cr); + if (resolvedMacros && !useResolvedMacros) return; @@ -48,5 +51,5 @@ void NullCheckTask::ScriptFunc(const Checkable::Ptr& service, const CheckResult: cr->SetPerformanceData(perfdata); cr->SetState(ServiceOK); - service->ProcessCheckResult(cr); + checkable->ProcessCheckResult(cr); } diff --git a/lib/methods/nulleventtask.cpp b/lib/methods/nulleventtask.cpp index 2d56e8a34..f80edd4e0 100644 --- a/lib/methods/nulleventtask.cpp +++ b/lib/methods/nulleventtask.cpp @@ -25,5 +25,7 @@ using namespace icinga; REGISTER_SCRIPTFUNCTION_NS(Internal, NullEvent, &NullEventTask::ScriptFunc, "checkable:resolvedMacros:useResolvedMacros"); -void NullEventTask::ScriptFunc(const Checkable::Ptr&, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) -{ } +void NullEventTask::ScriptFunc(const Checkable::Ptr& checkable, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) +{ + RequireNotNull(checkable); +} diff --git a/lib/methods/pluginchecktask.cpp b/lib/methods/pluginchecktask.cpp index abf2b0cd5..ddd8dba38 100644 --- a/lib/methods/pluginchecktask.cpp +++ b/lib/methods/pluginchecktask.cpp @@ -38,6 +38,9 @@ REGISTER_SCRIPTFUNCTION_NS(Internal, PluginCheck, &PluginCheckTask::ScriptFunc, void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) { + RequireNotNull(checkable); + RequireNotNull(cr); + CheckCommand::Ptr commandObj = checkable->GetCheckCommand(); Host::Ptr host; diff --git a/lib/methods/plugineventtask.cpp b/lib/methods/plugineventtask.cpp index 48a0b9ce0..a1a49f066 100644 --- a/lib/methods/plugineventtask.cpp +++ b/lib/methods/plugineventtask.cpp @@ -36,6 +36,8 @@ REGISTER_SCRIPTFUNCTION_NS(Internal, PluginEvent, &PluginEventTask::ScriptFunc, void PluginEventTask::ScriptFunc(const Checkable::Ptr& checkable, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) { + RequireNotNull(checkable); + EventCommand::Ptr commandObj = checkable->GetEventCommand(); Host::Ptr host; diff --git a/lib/methods/pluginnotificationtask.cpp b/lib/methods/pluginnotificationtask.cpp index 42403e7bb..730ae6770 100644 --- a/lib/methods/pluginnotificationtask.cpp +++ b/lib/methods/pluginnotificationtask.cpp @@ -39,6 +39,9 @@ void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification, const String& author, const String& comment, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) { + RequireNotNull(notification); + RequireNotNull(user); + NotificationCommand::Ptr commandObj = notification->GetCommand(); NotificationType type = static_cast(itype); diff --git a/lib/methods/randomchecktask.cpp b/lib/methods/randomchecktask.cpp index 0d31e795a..7afa0c7af 100644 --- a/lib/methods/randomchecktask.cpp +++ b/lib/methods/randomchecktask.cpp @@ -32,9 +32,12 @@ using namespace icinga; REGISTER_SCRIPTFUNCTION_NS(Internal, RandomCheck, &RandomCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros"); -void RandomCheckTask::ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr, +void RandomCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) { + RequireNotNull(checkable); + RequireNotNull(cr); + if (resolvedMacros && !useResolvedMacros) return; @@ -48,5 +51,5 @@ void RandomCheckTask::ScriptFunc(const Checkable::Ptr& service, const CheckResul cr->SetPerformanceData(perfdata); cr->SetState(static_cast(Utility::Random() % 4)); - service->ProcessCheckResult(cr); + checkable->ProcessCheckResult(cr); } diff --git a/lib/methods/timeperiodtask.cpp b/lib/methods/timeperiodtask.cpp index c26b4cedd..92c57b3cf 100644 --- a/lib/methods/timeperiodtask.cpp +++ b/lib/methods/timeperiodtask.cpp @@ -25,15 +25,18 @@ using namespace icinga; REGISTER_SCRIPTFUNCTION_NS(Internal, EmptyTimePeriod, &TimePeriodTask::EmptyTimePeriodUpdate, "tp:begin:end"); REGISTER_SCRIPTFUNCTION_NS(Internal, EvenMinutesTimePeriod, &TimePeriodTask::EvenMinutesTimePeriodUpdate, "tp:begin:end"); -Array::Ptr TimePeriodTask::EmptyTimePeriodUpdate(const TimePeriod::Ptr&, double, double) +Array::Ptr TimePeriodTask::EmptyTimePeriodUpdate(const TimePeriod::Ptr& tp, double, double) { + RequireNotNull(tp); + Array::Ptr segments = new Array(); return segments; } -Array::Ptr TimePeriodTask::EvenMinutesTimePeriodUpdate(const TimePeriod::Ptr&, double begin, double end) +Array::Ptr TimePeriodTask::EvenMinutesTimePeriodUpdate(const TimePeriod::Ptr& tp, double begin, double end) { Array::Ptr segments = new Array(); + RequireNotNull(tp); for (long t = begin / 60 - 1; t * 60 < end; t++) { if ((t % 2) == 0) {