Skip to content

Commit f40b1db

Browse files
dyatlovjasnell
authored andcommitted
src: revert removal of SecureContext _external getter
This `_external` getter is essential for some libs to work: uWebSockets as an example. PR-URL: #21711 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 318f1cd commit f40b1db

File tree

4 files changed

+60
-1
lines changed

4 files changed

+60
-1
lines changed

src/node_crypto.cc

+21
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,19 @@ void SecureContext::Initialize(Environment* env, Local<Object> target) {
359359
t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kTicketKeyIVIndex"),
360360
Integer::NewFromUnsigned(env->isolate(), kTicketKeyIVIndex));
361361

362+
Local<FunctionTemplate> ctx_getter_templ =
363+
FunctionTemplate::New(env->isolate(),
364+
CtxGetter,
365+
env->as_external(),
366+
Signature::New(env->isolate(), t));
367+
368+
369+
t->PrototypeTemplate()->SetAccessorProperty(
370+
FIXED_ONE_BYTE_STRING(env->isolate(), "_external"),
371+
ctx_getter_templ,
372+
Local<FunctionTemplate>(),
373+
static_cast<PropertyAttribute>(ReadOnly | DontDelete));
374+
362375
target->Set(secureContextString,
363376
t->GetFunction(env->context()).ToLocalChecked());
364377
env->set_secure_context_constructor_template(t);
@@ -1331,6 +1344,14 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl,
13311344
}
13321345

13331346

1347+
void SecureContext::CtxGetter(const FunctionCallbackInfo<Value>& info) {
1348+
SecureContext* sc;
1349+
ASSIGN_OR_RETURN_UNWRAP(&sc, info.This());
1350+
Local<External> ext = External::New(info.GetIsolate(), sc->ctx_.get());
1351+
info.GetReturnValue().Set(ext);
1352+
}
1353+
1354+
13341355
template <bool primary>
13351356
void SecureContext::GetCertificate(const FunctionCallbackInfo<Value>& args) {
13361357
SecureContext* wrap;

src/node_crypto.h

+1
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ class SecureContext : public BaseObject {
165165
const v8::FunctionCallbackInfo<v8::Value>& args);
166166
static void EnableTicketKeyCallback(
167167
const v8::FunctionCallbackInfo<v8::Value>& args);
168+
static void CtxGetter(const v8::FunctionCallbackInfo<v8::Value>& info);
168169

169170
template <bool primary>
170171
static void GetCertificate(const v8::FunctionCallbackInfo<v8::Value>& args);

test/parallel/test-accessor-properties.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Flags: --expose-internals
22
'use strict';
33

4-
require('../common');
4+
const common = require('../common');
55

66
// This tests that the accessor properties do not raise assertions
77
// when called with incompatible receivers.
@@ -54,4 +54,19 @@ const UDP = internalBinding('udp_wrap').UDP;
5454
typeof Object.getOwnPropertyDescriptor(StreamWrapProto, 'fd'),
5555
'object'
5656
);
57+
58+
if (common.hasCrypto) { // eslint-disable-line node-core/crypto-check
59+
// There are accessor properties in crypto too
60+
const crypto = process.binding('crypto');
61+
62+
assert.throws(() => {
63+
crypto.SecureContext.prototype._external;
64+
}, TypeError);
65+
66+
assert.strictEqual(
67+
typeof Object.getOwnPropertyDescriptor(
68+
crypto.SecureContext.prototype, '_external'),
69+
'object'
70+
);
71+
}
5772
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
if (!common.hasCrypto)
5+
common.skip('missing crypto');
6+
7+
const assert = require('assert');
8+
const tls = require('tls');
9+
10+
// Ensure accessing ._external doesn't hit an assert in the accessor method.
11+
{
12+
const pctx = tls.createSecureContext().context;
13+
const cctx = Object.create(pctx);
14+
assert.throws(() => cctx._external, TypeError);
15+
pctx._external;
16+
}
17+
{
18+
const pctx = tls.createSecurePair().credentials.context;
19+
const cctx = Object.create(pctx);
20+
assert.throws(() => cctx._external, TypeError);
21+
pctx._external;
22+
}

0 commit comments

Comments
 (0)