Skip to content

Commit ddb12ac

Browse files
committed
src: make StreamBase prototype accessors more robust
1 parent 0a84e95 commit ddb12ac

3 files changed

+57
-4
lines changed

src/stream_base-inl.h

+11-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace node {
1313

14+
using v8::AccessorSignature;
1415
using v8::External;
1516
using v8::FunctionCallbackInfo;
1617
using v8::FunctionTemplate;
@@ -31,27 +32,33 @@ void StreamBase::AddMethods(Environment* env,
3132
HandleScope scope(env->isolate());
3233

3334
enum PropertyAttribute attributes =
34-
static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
35+
static_cast<PropertyAttribute>(
36+
v8::ReadOnly | v8::DontDelete | v8::DontEnum);
37+
Local<AccessorSignature> signature =
38+
AccessorSignature::New(env->isolate(), t);
3539
t->PrototypeTemplate()->SetAccessor(env->fd_string(),
3640
GetFD<Base>,
3741
nullptr,
3842
env->as_external(),
3943
v8::DEFAULT,
40-
attributes);
44+
attributes,
45+
signature);
4146

4247
t->PrototypeTemplate()->SetAccessor(env->external_stream_string(),
4348
GetExternal<Base>,
4449
nullptr,
4550
env->as_external(),
4651
v8::DEFAULT,
47-
attributes);
52+
attributes,
53+
signature);
4854

4955
t->PrototypeTemplate()->SetAccessor(env->bytes_read_string(),
5056
GetBytesRead<Base>,
5157
nullptr,
5258
env->as_external(),
5359
v8::DEFAULT,
54-
attributes);
60+
attributes,
61+
signature);
5562

5663
env->SetProtoMethod(t, "readStart", JSMethod<Base, &StreamBase::ReadStart>);
5764
env->SetProtoMethod(t, "readStop", JSMethod<Base, &StreamBase::ReadStop>);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
'use strict';
2+
3+
require('../common');
4+
5+
// This tests that the prototype accessors added by StreamBase::AddMethods
6+
// are not enumerable. They could be enumerated when inspecting the prototype
7+
// with util.inspect or the inspector protocol.
8+
9+
const assert = require('assert');
10+
11+
// Or anything that calls StreamBase::AddMethods when setting up its prototype
12+
const TTY = process.binding('tty_wrap').TTY;
13+
14+
{
15+
assert.strictEqual(TTY.prototype.propertyIsEnumerable('bytesRead'), false);
16+
assert.strictEqual(TTY.prototype.propertyIsEnumerable('fd'), false);
17+
assert.strictEqual(
18+
TTY.prototype.propertyIsEnumerable('_externalStream'), false);
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
3+
require('../common');
4+
5+
// This tests that the prototype accessors added by StreamBase::AddMethods
6+
// do not raise assersions when called with incompatible receivers.
7+
8+
const assert = require('assert');
9+
10+
// Or anything that calls StreamBase::AddMethods when setting up its prototype
11+
const TTY = process.binding('tty_wrap').TTY;
12+
13+
// Should throw instead of raise assertions
14+
{
15+
const msg = /TypeError: Method \w+ called on incompatible receiver/;
16+
assert.throws(() => {
17+
TTY.prototype.bytesRead;
18+
}, msg);
19+
20+
assert.throws(() => {
21+
TTY.prototype.fd;
22+
}, msg);
23+
24+
assert.throws(() => {
25+
TTY.prototype._externalStream;
26+
}, msg);
27+
}

0 commit comments

Comments
 (0)