Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: src/JsEngine.cpp

Issue 10173031: Don`t use references to JsEngine to avoid use-after-free errors,switch to shared_ptr instead (Closed)
Patch Set: Created April 18, 2013, 4:15 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/GlobalJsObject.cpp ('k') | src/JsValue.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/JsEngine.cpp
===================================================================
--- a/src/JsEngine.cpp
+++ b/src/JsEngine.cpp
@@ -41,37 +41,44 @@ namespace
}
AdblockPlus::JsError::JsError(const v8::Handle<v8::Value> exception,
const v8::Handle<v8::Message> message)
: std::runtime_error(ExceptionToString(exception, message))
{
}
-AdblockPlus::JsEngine::JsEngine(const AppInfo& appInfo)
+AdblockPlus::JsEngine::JsEngine()
: isolate(v8::Isolate::GetCurrent())
{
- const v8::Locker locker(isolate);
+}
+
+AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::New(const AppInfo& appInfo)
Felix Dahlke 2013/04/18 18:42:16 I don't think we should have this. "JsEnginePtr x(
Wladimir Palant 2013/04/18 20:24:28 We need to have the object in a shared_ptr before
+{
+ JsEnginePtr result(new JsEngine());
+
+ const v8::Locker locker(result->isolate);
Felix Dahlke 2013/04/18 18:42:16 This is initialisation code, can you move it to th
const v8::HandleScope handleScope;
- context = v8::Context::New();
- AdblockPlus::GlobalJsObject::Setup(*this, appInfo,
- JsValuePtr(new JsValue(*this, context->Global())));
+ result->context = v8::Context::New();
+ AdblockPlus::GlobalJsObject::Setup(result, appInfo,
+ JsValuePtr(new JsValue(result, result->context->Global())));
+ return result;
}
AdblockPlus::JsValuePtr AdblockPlus::JsEngine::Evaluate(const std::string& source,
const std::string& filename)
{
- const Context context(*this);
+ const Context context(shared_from_this());
const v8::TryCatch tryCatch;
const v8::Handle<v8::Script> script = CompileScript(source, filename);
CheckTryCatch(tryCatch);
v8::Local<v8::Value> result = script->Run();
CheckTryCatch(tryCatch);
- return JsValuePtr(new JsValue(*this, result));
+ return JsValuePtr(new JsValue(shared_from_this(), result));
}
void AdblockPlus::JsEngine::Load(const std::string& scriptPath)
{
const std::tr1::shared_ptr<std::istream> file = GetFileSystem()->Read(scriptPath);
if (!file || !*file)
throw std::runtime_error("Unable to load script " + scriptPath);
Evaluate(Utils::Slurp(*file));
@@ -79,61 +86,71 @@ void AdblockPlus::JsEngine::Load(const s
void AdblockPlus::JsEngine::Gc()
{
while (!v8::V8::IdleNotification());
}
AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewValue(const std::string& val)
{
- const Context context(*this);
- return JsValuePtr(new JsValue(*this, v8::String::New(val.c_str(), val.length())));
+ const Context context(shared_from_this());
+ return JsValuePtr(new JsValue(shared_from_this(),
+ v8::String::New(val.c_str(), val.length())));
}
AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewValue(int64_t val)
{
- const Context context(*this);
- return JsValuePtr(new JsValue(*this, v8::Integer::New(val)));
+ const Context context(shared_from_this());
+ return JsValuePtr(new JsValue(shared_from_this(), v8::Integer::New(val)));
}
AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewValue(bool val)
{
- const Context context(*this);
- return JsValuePtr(new JsValue(*this, v8::Boolean::New(val)));
+ const Context context(shared_from_this());
+ return JsValuePtr(new JsValue(shared_from_this(), v8::Boolean::New(val)));
}
AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewObject()
{
- const Context context(*this);
- return JsValuePtr(new JsValue(*this, v8::Object::New()));
+ const Context context(shared_from_this());
+ return JsValuePtr(new JsValue(shared_from_this(), v8::Object::New()));
}
AdblockPlus::JsValuePtr AdblockPlus::JsEngine::NewCallback(
v8::InvocationCallback callback)
{
- const Context context(*this);
+ const Context context(shared_from_this());
+ // Note: we are leaking this weak pointer, no obvious way to destroy it when
+ // it's no longer used
+ std::tr1::weak_ptr<JsEngine>* data =
+ new std::tr1::weak_ptr<JsEngine>(shared_from_this());
v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(callback,
- v8::External::New(this));
- return JsValuePtr(new JsValue(*this, templ->GetFunction()));
+ v8::External::New(data));
+ return JsValuePtr(new JsValue(shared_from_this(), templ->GetFunction()));
}
-AdblockPlus::JsEngine& AdblockPlus::JsEngine::FromArguments(const v8::Arguments& arguments)
+AdblockPlus::JsEnginePtr AdblockPlus::JsEngine::FromArguments(const v8::Arguments& arguments)
{
const v8::Local<const v8::External> external =
v8::Local<const v8::External>::Cast(arguments.Data());
- return *static_cast<JsEngine* const>(external->Value());
+ std::tr1::weak_ptr<JsEngine>* data =
+ static_cast<std::tr1::weak_ptr<JsEngine>*>(external->Value());
+ JsEnginePtr result = data->lock();
+ if (!result)
+ throw std::runtime_error("Oops, our JsEngine is gone, how did that happen?");
+ return result;
}
AdblockPlus::JsValueList AdblockPlus::JsEngine::ConvertArguments(const v8::Arguments& arguments)
{
- const Context context(*this);
+ const Context context(shared_from_this());
JsValueList list;
for (int i = 0; i < arguments.Length(); i++)
- list.push_back(JsValuePtr(new JsValue(*this, arguments[i])));
+ list.push_back(JsValuePtr(new JsValue(shared_from_this(), arguments[i])));
return list;
}
AdblockPlus::FileSystemPtr AdblockPlus::JsEngine::GetFileSystem()
{
if (!fileSystem)
fileSystem.reset(new DefaultFileSystem());
return fileSystem;
@@ -172,13 +189,13 @@ AdblockPlus::ErrorCallbackPtr AdblockPlu
void AdblockPlus::JsEngine::SetErrorCallback(AdblockPlus::ErrorCallbackPtr val)
{
if (!val)
throw std::runtime_error("ErrorCallback cannot be null");
errorCallback = val;
}
-AdblockPlus::JsEngine::Context::Context(const JsEngine& jsEngine)
- : locker(jsEngine.isolate), handleScope(),
- contextScope(jsEngine.context)
+AdblockPlus::JsEngine::Context::Context(const JsEnginePtr jsEngine)
+ : locker(jsEngine->isolate), handleScope(),
+ contextScope(jsEngine->context)
{
}
« no previous file with comments | « src/GlobalJsObject.cpp ('k') | src/JsValue.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld