summaryrefslogtreecommitdiffstats
path: root/gin
diff options
context:
space:
mode:
authorhajimehoshi@chromium.org <hajimehoshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-28 14:48:25 +0000
committerhajimehoshi@chromium.org <hajimehoshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-28 14:48:25 +0000
commite0719edc493cdb9edce7ee29665da825be863404 (patch)
treef28e747e3c1b6e5969bdd4c8d40dd8325d73efb4 /gin
parentf2a40edbd44cbaeee3f7345abb2ccd5ddbeab159 (diff)
downloadchromium_src-e0719edc493cdb9edce7ee29665da825be863404.zip
chromium_src-e0719edc493cdb9edce7ee29665da825be863404.tar.gz
chromium_src-e0719edc493cdb9edce7ee29665da825be863404.tar.bz2
gin: Bug fix: Fix CreateHandle to return an emtpy handle in some extreme cases
In some extreme cases, ObjectTemplate::NewInstance might return an empty handler. For example, the getter and setter Object.prototype.constructor can be rewritten with a evil function which can throw exceptions. BUG=331301 TEST=gin_unittests --gtest_filter=WrappableTest.ErrorInObjectConstructorProperty Review URL: https://codereview.chromium.org/184253004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@254109 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gin')
-rw-r--r--gin/handle.h5
-rw-r--r--gin/wrappable.cc8
-rw-r--r--gin/wrappable_unittest.cc22
3 files changed, 34 insertions, 1 deletions
diff --git a/gin/handle.h b/gin/handle.h
index da1de34..01db660 100644
--- a/gin/handle.h
+++ b/gin/handle.h
@@ -60,7 +60,10 @@ struct Converter<gin::Handle<T> > {
// without having to write out the type of the object explicitly.
template<typename T>
gin::Handle<T> CreateHandle(v8::Isolate* isolate, T* object) {
- return gin::Handle<T>(object->GetWrapper(isolate), object);
+ v8::Handle<v8::Object> wrapper = object->GetWrapper(isolate);
+ if (wrapper.IsEmpty())
+ return gin::Handle<T>();
+ return gin::Handle<T>(wrapper, object);
}
} // namespace gin
diff --git a/gin/wrappable.cc b/gin/wrappable.cc
index 8d41ce0..a330fef 100644
--- a/gin/wrappable.cc
+++ b/gin/wrappable.cc
@@ -44,6 +44,14 @@ v8::Handle<v8::Object> WrappableBase::GetWrapperImpl(v8::Isolate* isolate,
}
CHECK_EQ(kNumberOfInternalFields, templ->InternalFieldCount());
v8::Handle<v8::Object> wrapper = templ->NewInstance();
+ // |wrapper| may be empty in some extreme cases, e.g., when
+ // Object.prototype.constructor is overwritten.
+ if (wrapper.IsEmpty()) {
+ // The current wrappable object will be no longer managed by V8. Delete this
+ // now.
+ delete this;
+ return wrapper;
+ }
wrapper->SetAlignedPointerInInternalField(kWrapperInfoIndex, info);
wrapper->SetAlignedPointerInInternalField(kEncodedValueIndex, this);
wrapper_.Reset(isolate, wrapper);
diff --git a/gin/wrappable_unittest.cc b/gin/wrappable_unittest.cc
index 984ba573..bf143ce 100644
--- a/gin/wrappable_unittest.cc
+++ b/gin/wrappable_unittest.cc
@@ -191,4 +191,26 @@ TEST_F(WrappableTest, WrappableSubclass) {
EXPECT_EQ("Hello, Lily", object->result);
}
+TEST_F(WrappableTest, ErrorInObjectConstructorProperty) {
+ v8::Isolate* isolate = instance_->isolate();
+ v8::HandleScope handle_scope(isolate);
+
+ v8::Handle<v8::String> source = StringToV8(
+ isolate,
+ "(function() {"
+ " Object.defineProperty(Object.prototype, 'constructor', {"
+ " get: function() { throw 'Error'; },"
+ " set: function() { throw 'Error'; }"
+ " });"
+ "})();");
+ EXPECT_FALSE(source.IsEmpty());
+ v8::Handle<v8::Script> script = v8::Script::New(source);
+ script->Run();
+
+ gin::TryCatch try_catch;
+ gin::Handle<MyObject> obj = MyObject::Create(isolate);
+ EXPECT_TRUE(obj.IsEmpty());
+ EXPECT_TRUE(try_catch.HasCaught());
+}
+
} // namespace gin