Skip to content

Commit b1507c4

Browse files
MattiasBuelenstargos
authored andcommitted
lib: add brand checks to AbortController and AbortSignal
PR-URL: #37720 Backport-PR-URL: #38386 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 397d937 commit b1507c4

2 files changed

Lines changed: 89 additions & 3 deletions

File tree

‎lib/internal/abort_controller.js‎

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ const {
2323
emitExperimentalWarning
2424
}=require('internal/util');
2525
const{ inspect }=require('internal/util/inspect');
26+
const{
27+
codes: {
28+
ERR_INVALID_THIS,
29+
}
30+
}=require('internal/errors');
2631

2732
constkAborted=Symbol('kAborted');
2833

@@ -37,13 +42,21 @@ function customInspect(self, obj, depth, options) {
3742
return`${self.constructor.name}${inspect(obj,opts)}`;
3843
}
3944

45+
functionvalidateAbortSignal(obj){
46+
if(obj?.[kAborted]===undefined)
47+
thrownewERR_INVALID_THIS('AbortSignal');
48+
}
49+
4050
classAbortSignalextendsEventTarget{
4151
constructor(){
4252
// eslint-disable-next-line no-restricted-syntax
4353
thrownewTypeError('Illegal constructor');
4454
}
4555

46-
getaborted(){return!!this[kAborted];}
56+
getaborted(){
57+
validateAbortSignal(this);
58+
return!!this[kAborted];
59+
}
4760

4861
[customInspectSymbol](depth,options){
4962
returncustomInspect(this,{
@@ -89,14 +102,27 @@ function abortSignal(signal) {
89102
// initializers for now:
90103
// https://bugs.chromium.org/p/v8/issues/detail?id=10704
91104
constkSignal=Symbol('signal');
105+
106+
functionvalidateAbortController(obj){
107+
if(obj?.[kSignal]===undefined)
108+
thrownewERR_INVALID_THIS('AbortController');
109+
}
110+
92111
classAbortController{
93112
constructor(){
94113
this[kSignal]=createAbortSignal();
95114
emitExperimentalWarning('AbortController');
96115
}
97116

98-
getsignal(){returnthis[kSignal];}
99-
abort(){abortSignal(this[kSignal]);}
117+
getsignal(){
118+
validateAbortController(this);
119+
returnthis[kSignal];
120+
}
121+
122+
abort(){
123+
validateAbortController(this);
124+
abortSignal(this[kSignal]);
125+
}
100126

101127
[customInspectSymbol](depth,options){
102128
returncustomInspect(this,{

‎test/parallel/test-abortcontroller.js‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,63 @@ const { Event } = require('internal/event_target');
7373
constsignal=AbortSignal.abort();
7474
ok(signal.aborted);
7575
}
76+
77+
{
78+
// Test that AbortController properties and methods validate the receiver
79+
constacSignalGet=Object.getOwnPropertyDescriptor(
80+
AbortController.prototype,
81+
'signal'
82+
).get;
83+
constacAbort=AbortController.prototype.abort;
84+
85+
constgoodController=newAbortController();
86+
ok(acSignalGet.call(goodController));
87+
acAbort.call(goodController);
88+
89+
constbadAbortControllers=[
90+
null,
91+
undefined,
92+
0,
93+
NaN,
94+
true,
95+
'AbortController',
96+
Object.create(AbortController.prototype)
97+
];
98+
for(constbadControllerofbadAbortControllers){
99+
throws(
100+
()=>acSignalGet.call(badController),
101+
{code: 'ERR_INVALID_THIS',name: 'TypeError'}
102+
);
103+
throws(
104+
()=>acAbort.call(badController),
105+
{code: 'ERR_INVALID_THIS',name: 'TypeError'}
106+
);
107+
}
108+
}
109+
110+
{
111+
// Test that AbortSignal properties validate the receiver
112+
constsignalAbortedGet=Object.getOwnPropertyDescriptor(
113+
AbortSignal.prototype,
114+
'aborted'
115+
).get;
116+
117+
constgoodSignal=newAbortController().signal;
118+
strictEqual(signalAbortedGet.call(goodSignal),false);
119+
120+
constbadAbortSignals=[
121+
null,
122+
undefined,
123+
0,
124+
NaN,
125+
true,
126+
'AbortSignal',
127+
Object.create(AbortSignal.prototype)
128+
];
129+
for(constbadSignalofbadAbortSignals){
130+
throws(
131+
()=>signalAbortedGet.call(badSignal),
132+
{code: 'ERR_INVALID_THIS',name: 'TypeError'}
133+
);
134+
}
135+
}

0 commit comments

Comments
 (0)