Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix nullptr dereferences #6104

Merged
merged 4 commits into from Feb 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions lib/base/array-script.cpp
Expand Up @@ -30,48 +30,55 @@ static double ArrayLen()
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
return self->GetLength();
}

static void ArraySet(int index, const Value& value)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
self->Set(index, value);
}

static Value ArrayGet(int index)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
return self->Get(index);
}

static void ArrayAdd(const Value& value)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
self->Add(value);
}

static void ArrayRemove(int index)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
self->Remove(index);
}

static bool ArrayContains(const Value& value)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
return self->Contains(value);
}

static void ArrayClear()
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
self->Clear();
}

Expand All @@ -84,6 +91,7 @@ static Array::Ptr ArraySort(const std::vector<Value>& args)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);

Array::Ptr arr = self->ShallowClone();

Expand All @@ -107,13 +115,15 @@ static Array::Ptr ArrayShallowClone()
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
return self->ShallowClone();
}

static Value ArrayJoin(const Value& separator)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);

Value result;
bool first = true;
Expand All @@ -136,13 +146,15 @@ static Array::Ptr ArrayReverse()
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
return self->Reverse();
}

static Array::Ptr ArrayMap(const Function::Ptr& function)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);

if (vframe->Sandboxed && !function->IsSideEffectFree())
BOOST_THROW_EXCEPTION(ScriptError("Map function must be side-effect free."));
Expand All @@ -161,6 +173,7 @@ static Value ArrayReduce(const Function::Ptr& function)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);

if (vframe->Sandboxed && !function->IsSideEffectFree())
BOOST_THROW_EXCEPTION(ScriptError("Reduce function must be side-effect free."));
Expand All @@ -182,6 +195,7 @@ static Array::Ptr ArrayFilter(const Function::Ptr& function)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);

if (vframe->Sandboxed && !function->IsSideEffectFree())
BOOST_THROW_EXCEPTION(ScriptError("Filter function must be side-effect free."));
Expand All @@ -201,6 +215,7 @@ static bool ArrayAny(const Function::Ptr& function)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);

if (vframe->Sandboxed && !function->IsSideEffectFree())
BOOST_THROW_EXCEPTION(ScriptError("Filter function must be side-effect free."));
Expand All @@ -218,6 +233,7 @@ static bool ArrayAll(const Function::Ptr& function)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);

if (vframe->Sandboxed && !function->IsSideEffectFree())
BOOST_THROW_EXCEPTION(ScriptError("Filter function must be side-effect free."));
Expand All @@ -234,6 +250,7 @@ static Array::Ptr ArrayUnique()
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);

std::set<Value> result;

Expand Down
2 changes: 2 additions & 0 deletions lib/base/configobject-script.cpp
Expand Up @@ -29,13 +29,15 @@ static void ConfigObjectModifyAttribute(const String& attr, const Value& value)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
ConfigObject::Ptr self = vframe->Self;
REQUIRE_NOT_NULL(self);
return self->ModifyAttribute(attr, value);
}

static void ConfigObjectRestoreAttribute(const String& attr)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
ConfigObject::Ptr self = vframe->Self;
REQUIRE_NOT_NULL(self);
return self->RestoreAttribute(attr);
}

Expand Down
1 change: 1 addition & 0 deletions lib/base/datetime-script.cpp
Expand Up @@ -29,6 +29,7 @@ static String DateTimeFormat(const String& format)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
DateTime::Ptr self = static_cast<DateTime::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);

return self->Format(format);
}
Expand Down
10 changes: 10 additions & 0 deletions lib/base/dictionary-script.cpp
Expand Up @@ -29,48 +29,56 @@ static double DictionaryLen()
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Dictionary::Ptr self = static_cast<Dictionary::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
return self->GetLength();
}

static void DictionarySet(const String& key, const Value& value)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Dictionary::Ptr self = static_cast<Dictionary::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
self->Set(key, value);
}

static Value DictionaryGet(const String& key)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Dictionary::Ptr self = static_cast<Dictionary::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
return self->Get(key);
}

static void DictionaryRemove(const String& key)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Dictionary::Ptr self = static_cast<Dictionary::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
self->Remove(key);
}

static bool DictionaryContains(const String& key)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Dictionary::Ptr self = static_cast<Dictionary::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
return self->Contains(key);
}

static Dictionary::Ptr DictionaryShallowClone()
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Dictionary::Ptr self = static_cast<Dictionary::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
return self->ShallowClone();
}

static Array::Ptr DictionaryKeys()
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Dictionary::Ptr self = static_cast<Dictionary::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);

ArrayData keys;
ObjectLock olock(self);
for (const Dictionary::Pair& kv : self) {
Expand All @@ -83,6 +91,8 @@ static Array::Ptr DictionaryValues()
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Dictionary::Ptr self = static_cast<Dictionary::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);

ArrayData values;
ObjectLock olock(self);
for (const Dictionary::Pair& kv : self) {
Expand Down
2 changes: 2 additions & 0 deletions lib/base/function-script.cpp
Expand Up @@ -32,6 +32,7 @@ static Value FunctionCall(const std::vector<Value>& args)

ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Function::Ptr self = static_cast<Function::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);

std::vector<Value> uargs(args.begin() + 1, args.end());
return self->InvokeThis(args[0], uargs);
Expand All @@ -41,6 +42,7 @@ static Value FunctionCallV(const Value& thisArg, const Array::Ptr& args)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Function::Ptr self = static_cast<Function::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);

std::vector<Value> uargs;

Expand Down
3 changes: 3 additions & 0 deletions lib/base/object-script.cpp
Expand Up @@ -29,20 +29,23 @@ static String ObjectToString()
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Object::Ptr self = static_cast<Object::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
return self->ToString();
}

static void ObjectNotifyAttribute(const String& attribute)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Object::Ptr self = static_cast<Object::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
self->NotifyField(self->GetReflectionType()->GetFieldId(attribute));
}

static Object::Ptr ObjectClone()
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Object::Ptr self = static_cast<Object::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);
return self->Clone();
}

Expand Down
6 changes: 6 additions & 0 deletions lib/base/object.cpp
Expand Up @@ -290,3 +290,9 @@ void icinga::DefaultObjectFactoryCheckArgs(const std::vector<Value>& args)
if (!args.empty())
BOOST_THROW_EXCEPTION(std::invalid_argument("Constructor does not take any arguments."));
}

void icinga::RequireNotNullInternal(const intrusive_ptr<Object>& object, const char *description)
{
if (!object)
BOOST_THROW_EXCEPTION(std::invalid_argument("Pointer must not be null: " + String(description)));
}
4 changes: 4 additions & 0 deletions lib/base/object.hpp
Expand Up @@ -57,6 +57,10 @@ extern Value Empty;
DECLARE_PTR_TYPEDEFS(klass); \
IMPL_TYPE_LOOKUP();

#define REQUIRE_NOT_NULL(ptr) RequireNotNullInternal(ptr, #ptr)

void RequireNotNullInternal(const intrusive_ptr<Object>& object, const char *description);

void DefaultObjectFactoryCheckArgs(const std::vector<Value>& args);

template<typename T>
Expand Down
1 change: 1 addition & 0 deletions lib/base/typetype-script.cpp
Expand Up @@ -35,6 +35,7 @@ static void TypeRegisterAttributeHandler(const String& fieldName, const Function
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Type::Ptr self = static_cast<Type::Ptr>(vframe->Self);
REQUIRE_NOT_NULL(self);

int fid = self->GetFieldId(fieldName);
self->RegisterAttributeHandler(fid, std::bind(&InvokeAttributeHandlerHelper, callback, _1, _2));
Expand Down
1 change: 1 addition & 0 deletions lib/icinga/checkable-script.cpp
Expand Up @@ -30,6 +30,7 @@ static void CheckableProcessCheckResult(const CheckResult::Ptr& cr)
{
ScriptFrame *vframe = ScriptFrame::GetCurrentFrame();
Checkable::Ptr self = vframe->Self;
REQUIRE_NOT_NULL(self);
self->ProcessCheckResult(cr);
}

Expand Down