Skip to content

Commit

Permalink
Added a guard against calling a weak callback on already deleted inst…
Browse files Browse the repository at this point in the history
…ance. Refs #210.
  • Loading branch information
uhop committed Jun 5, 2024
1 parent 078e266 commit 5e779ce
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 12 deletions.
36 changes: 31 additions & 5 deletions lib/addon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,29 @@ NODE_MODULE_INIT()
Nan::Set(module->ToObject(context).ToLocalChecked(), Nan::New("exports").ToLocalChecked(), WrappedRE2::Init());
}

WrappedRE2::~WrappedRE2()
{
for (auto ptr : callbackRegistry)
{
*ptr = nullptr;
}
dropLastString();
}

// private methods

WrappedRE2::PtrWrappedRE2 *WrappedRE2::registerCallback()
{
PtrWrappedRE2 *ptr = new PtrWrappedRE2(this);
callbackRegistry.insert(ptr);
return ptr;
}

void WrappedRE2::unregisterCallback(PtrWrappedRE2 *ptr)
{
callbackRegistry.erase(ptr);
}

void WrappedRE2::dropLastString()
{
lastString.Reset();
Expand All @@ -106,10 +127,15 @@ void WrappedRE2::dropLastString()
}
}

void WrappedRE2::weakLastStringCallback(const Nan::WeakCallbackInfo<WrappedRE2> &data)
void WrappedRE2::weakLastStringCallback(const Nan::WeakCallbackInfo<PtrWrappedRE2> &data)
{
WrappedRE2* re2 = data.GetParameter();
re2->dropLastString();
PtrWrappedRE2 *re2 = data.GetParameter();
if (*re2)
{
(*re2)->unregisterCallback(re2);
(*re2)->dropLastString();
}
delete re2;
}

void WrappedRE2::prepareLastString(const v8::Local<v8::Value> &arg, bool ignoreLastIndex)
Expand Down Expand Up @@ -137,10 +163,10 @@ void WrappedRE2::prepareLastString(const v8::Local<v8::Value> &arg, bool ignoreL
dropLastString();

lastString.Reset(arg);
static_cast<v8::PersistentBase<v8::Value>&>(lastString).SetWeak();
static_cast<v8::PersistentBase<v8::Value> &>(lastString).SetWeak();

Nan::Persistent<v8::Value> dummy(arg);
dummy.SetWeak(this, weakLastStringCallback, Nan::WeakCallbackType::kParameter);
dummy.SetWeak(registerCallback(), weakLastStringCallback, Nan::WeakCallbackType::kParameter);

lastStringValue = new StrValString(arg, startFrom);
};
20 changes: 13 additions & 7 deletions lib/wrapped_re2.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <re2/re2.h>

#include <string>
#include <unordered_set>

struct StrValBase;

Expand Down Expand Up @@ -67,10 +68,7 @@ class WrappedRE2 : public Nan::ObjectWrap
static NAN_SETTER(SetUnicodeWarningLevel);

public:
~WrappedRE2()
{
dropLastString();
}
~WrappedRE2();

static v8::Local<v8::Function> Init();

Expand Down Expand Up @@ -108,19 +106,27 @@ class WrappedRE2 : public Nan::ObjectWrap
Nan::Persistent<v8::Value> lastString; // weak pointer
StrValBase *lastStringValue;

static void weakLastStringCallback(const Nan::WeakCallbackInfo<WrappedRE2> &data);
typedef WrappedRE2 *PtrWrappedRE2;

std::unordered_set<PtrWrappedRE2 *> callbackRegistry;
PtrWrappedRE2 *registerCallback();
void unregisterCallback(PtrWrappedRE2 *re2);

static void weakLastStringCallback(const Nan::WeakCallbackInfo<PtrWrappedRE2> &data);

void dropLastString();
void prepareLastString(const v8::Local<v8::Value> &arg, bool ignoreLastIndex = false);
};

struct PrepareLastString
{
PrepareLastString(WrappedRE2 *re2, const v8::Local<v8::Value> &arg, bool ignoreLastIndex = false) : re2(re2) {
PrepareLastString(WrappedRE2 *re2, const v8::Local<v8::Value> &arg, bool ignoreLastIndex = false) : re2(re2)
{
re2->prepareLastString(arg, ignoreLastIndex);
}

~PrepareLastString() {
~PrepareLastString()
{
if (!re2->enabledCache || !(re2->global || re2->sticky))
re2->dropLastString();
}
Expand Down

0 comments on commit 5e779ce

Please sign in to comment.