diff options
author | hajimehoshi@chromium.org <hajimehoshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-28 14:48:25 +0000 |
---|---|---|
committer | hajimehoshi@chromium.org <hajimehoshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-28 14:48:25 +0000 |
commit | e0719edc493cdb9edce7ee29665da825be863404 (patch) | |
tree | f28e747e3c1b6e5969bdd4c8d40dd8325d73efb4 /gin | |
parent | f2a40edbd44cbaeee3f7345abb2ccd5ddbeab159 (diff) | |
download | chromium_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.h | 5 | ||||
-rw-r--r-- | gin/wrappable.cc | 8 | ||||
-rw-r--r-- | gin/wrappable_unittest.cc | 22 |
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 |