tls: fix assert in context._external accessor

* Restrict the receiver to instances of the FunctionTemplate.
* Use `args.This()` instead of `args.Holder()`.

Fixes: https://github.com/nodejs/node/issues/3682
PR-URL: https://github.com/nodejs/node/pull/5521
Reviewed-By: Fedor Indutny <fedor@indutny.com>
pull/5521/head
Ben Noordhuis 2016-03-02 14:04:42 +01:00
parent c133d07b83
commit 0bea78682a
2 changed files with 48 additions and 21 deletions

View File

@ -63,6 +63,7 @@ static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
namespace node {
namespace crypto {
using v8::AccessorSignature;
using v8::Array;
using v8::Boolean;
using v8::Context;
@ -324,7 +325,8 @@ void SecureContext::Initialize(Environment* env, Local<Object> target) {
nullptr,
env->as_external(),
DEFAULT,
static_cast<PropertyAttribute>(ReadOnly | DontDelete));
static_cast<PropertyAttribute>(ReadOnly | DontDelete),
AccessorSignature::New(env->isolate(), t));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"),
t->GetFunction());
@ -1138,9 +1140,7 @@ int SecureContext::TicketKeyCallback(SSL* ssl,
void SecureContext::CtxGetter(Local<String> property,
const PropertyCallbackInfo<Value>& info) {
HandleScope scope(info.GetIsolate());
SSL_CTX* ctx = Unwrap<SecureContext>(info.Holder())->ctx_;
SSL_CTX* ctx = Unwrap<SecureContext>(info.This())->ctx_;
Local<External> ext = External::New(info.GetIsolate(), ctx);
info.GetReturnValue().Set(ext);
}
@ -1213,7 +1213,8 @@ void SSLWrap<Base>::AddMethods(Environment* env, Local<FunctionTemplate> t) {
nullptr,
env->as_external(),
DEFAULT,
static_cast<PropertyAttribute>(ReadOnly | DontDelete));
static_cast<PropertyAttribute>(ReadOnly | DontDelete),
AccessorSignature::New(env->isolate(), t));
}
@ -2371,9 +2372,7 @@ void SSLWrap<Base>::CertCbDone(const FunctionCallbackInfo<Value>& args) {
template <class Base>
void SSLWrap<Base>::SSLGetter(Local<String> property,
const PropertyCallbackInfo<Value>& info) {
HandleScope scope(info.GetIsolate());
SSL* ssl = Unwrap<Base>(info.Holder())->ssl_;
SSL* ssl = Unwrap<Base>(info.This())->ssl_;
Local<External> ext = External::New(info.GetIsolate(), ssl);
info.GetReturnValue().Set(ext);
}
@ -4313,12 +4312,14 @@ void DiffieHellman::Initialize(Environment* env, Local<Object> target) {
env->SetProtoMethod(t, "setPublicKey", SetPublicKey);
env->SetProtoMethod(t, "setPrivateKey", SetPrivateKey);
t->InstanceTemplate()->SetAccessor(env->verify_error_string(),
t->InstanceTemplate()->SetAccessor(
env->verify_error_string(),
DiffieHellman::VerifyErrorGetter,
nullptr,
env->as_external(),
DEFAULT,
attributes);
attributes,
AccessorSignature::New(env->isolate(), t));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellman"),
t->GetFunction());
@ -4333,12 +4334,14 @@ void DiffieHellman::Initialize(Environment* env, Local<Object> target) {
env->SetProtoMethod(t2, "getPublicKey", GetPublicKey);
env->SetProtoMethod(t2, "getPrivateKey", GetPrivateKey);
t2->InstanceTemplate()->SetAccessor(env->verify_error_string(),
t2->InstanceTemplate()->SetAccessor(
env->verify_error_string(),
DiffieHellman::VerifyErrorGetter,
nullptr,
env->as_external(),
DEFAULT,
attributes);
attributes,
AccessorSignature::New(env->isolate(), t2));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "DiffieHellmanGroup"),
t2->GetFunction());

View File

@ -0,0 +1,24 @@
'use strict';
const common = require('../common');
const assert = require('assert');
if (!common.hasCrypto) {
console.log('1..0 # Skipped: missing crypto');
return;
}
// Ensure accessing ._external doesn't hit an assert in the accessor method.
const tls = require('tls');
{
const pctx = tls.createSecureContext().context;
const cctx = Object.create(pctx);
assert.throws(() => cctx._external, /incompatible receiver/);
pctx._external;
}
{
const pctx = tls.createSecurePair().credentials.context;
const cctx = Object.create(pctx);
assert.throws(() => cctx._external, /incompatible receiver/);
pctx._external;
}