Skip to content

Commit

Permalink
node: add signature to SET_PROTOTYPE_METHOD
Browse files Browse the repository at this point in the history
This prevents segfaults when a native method is reassigned to a
different object (which corrupts args.This()).  When unwrapping,
clients should use args.Holder() instead of args.This().

Closes nodejs#6690.

Signed-off-by: Trevor Norris <trev.norris@gmail.com>
  • Loading branch information
cscott authored and trevnorris committed Apr 2, 2014
1 parent d4fcb23 commit 08a5b44
Show file tree
Hide file tree
Showing 23 changed files with 211 additions and 145 deletions.
4 changes: 2 additions & 2 deletions doc/api/addons.markdown
Expand Up @@ -401,7 +401,7 @@ prototype:
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);

MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.This());
MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());
obj->value_ += 1;

args.GetReturnValue().Set(Number::New(isolate, obj->value_));
Expand Down Expand Up @@ -539,7 +539,7 @@ The implementation is similar to the above in `myobject.cc`:
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);

MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.This());
MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());
obj->value_ += 1;

args.GetReturnValue().Set(Number::New(isolate, obj->value_));
Expand Down
4 changes: 2 additions & 2 deletions src/fs_event_wrap.cc
Expand Up @@ -106,7 +106,7 @@ void FSEventWrap::Start(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

FSEventWrap* wrap = Unwrap<FSEventWrap>(args.This());
FSEventWrap* wrap = Unwrap<FSEventWrap>(args.Holder());

if (args.Length() < 1 || !args[0]->IsString()) {
return env->ThrowTypeError("Bad arguments");
Expand Down Expand Up @@ -189,7 +189,7 @@ void FSEventWrap::Close(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

FSEventWrap* wrap = Unwrap<FSEventWrap>(args.This());
FSEventWrap* wrap = Unwrap<FSEventWrap>(args.Holder());

if (wrap == NULL || wrap->initialized_ == false)
return;
Expand Down
6 changes: 3 additions & 3 deletions src/handle_wrap.cc
Expand Up @@ -47,7 +47,7 @@ void HandleWrap::Ref(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

HandleWrap* wrap = Unwrap<HandleWrap>(args.This());
HandleWrap* wrap = Unwrap<HandleWrap>(args.Holder());

if (wrap != NULL && wrap->handle__ != NULL) {
uv_ref(wrap->handle__);
Expand All @@ -60,7 +60,7 @@ void HandleWrap::Unref(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

HandleWrap* wrap = Unwrap<HandleWrap>(args.This());
HandleWrap* wrap = Unwrap<HandleWrap>(args.Holder());

if (wrap != NULL && wrap->handle__ != NULL) {
uv_unref(wrap->handle__);
Expand All @@ -73,7 +73,7 @@ void HandleWrap::Close(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

HandleWrap* wrap = Unwrap<HandleWrap>(args.This());
HandleWrap* wrap = Unwrap<HandleWrap>(args.Holder());

// guard against uninitialized handle or double close
if (wrap == NULL || wrap->handle__ == NULL)
Expand Down
5 changes: 3 additions & 2 deletions src/node.h
Expand Up @@ -212,8 +212,9 @@ inline void NODE_SET_PROTOTYPE_METHOD(v8::Handle<v8::FunctionTemplate> recv,
v8::FunctionCallback callback) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handle_scope(isolate);
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate,
callback);
v8::Handle<v8::Signature> s = v8::Signature::New(isolate, recv);
v8::Local<v8::FunctionTemplate> t =
v8::FunctionTemplate::New(isolate, callback, v8::Handle<v8::Value>(), s);
recv->PrototypeTemplate()->Set(v8::String::NewFromUtf8(isolate, name),
t->GetFunction());
}
Expand Down
5 changes: 2 additions & 3 deletions src/node_contextify.cc
Expand Up @@ -634,14 +634,13 @@ class ContextifyScript : public BaseObject {
const bool display_errors,
const FunctionCallbackInfo<Value>& args,
TryCatch& try_catch) {
if (!ContextifyScript::InstanceOf(env, args.This())) {
if (!ContextifyScript::InstanceOf(env, args.Holder())) {
env->ThrowTypeError(
"Script methods can only be called on script instances.");
return false;
}

ContextifyScript* wrapped_script =
Unwrap<ContextifyScript>(args.This());
ContextifyScript* wrapped_script = Unwrap<ContextifyScript>(args.Holder());
Local<UnboundScript> unbound_script =
PersistentToLocal(env->isolate(), wrapped_script->script_);
Local<Script> script = unbound_script->BindToCurrentContext();
Expand Down

0 comments on commit 08a5b44

Please sign in to comment.