Skip to content

Commit f529f73

Browse files
committed
lib: brand check event handler property receivers
Event handler properties defined by `defineEventHandler` should check if the receiver is a valid `EventTarget`. PR-URL: #44483 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent ecd5de0 commit f529f73

2 files changed

Lines changed: 47 additions & 27 deletions

File tree

‎lib/internal/event_target.js‎

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const {
3434
ERR_INVALID_THIS,
3535
}
3636
}=require('internal/errors');
37-
const{ validateObject, validateString }=require('internal/validators');
37+
const{ validateObject, validateString, validateInternalField}=require('internal/validators');
3838

3939
const{
4040
customInspectSymbol,
@@ -492,6 +492,7 @@ function initEventTarget(self) {
492492
self[kEvents]=newSafeMap();
493493
self[kMaxEventTargetListeners]=EventEmitter.defaultMaxListeners;
494494
self[kMaxEventTargetListenersWarned]=false;
495+
self[kHandlers]=newSafeMap();
495496
}
496497

497498
classEventTarget{
@@ -1021,34 +1022,46 @@ function makeEventHandler(handler) {
10211022

10221023
functiondefineEventHandler(emitter,name){
10231024
// 8.1.5.1 Event handlers - basically `on[eventName]` attributes
1024-
ObjectDefineProperty(emitter,`on${name}`,{
1025+
constpropName=`on${name}`;
1026+
functionget(){
1027+
validateInternalField(this,kHandlers,'EventTarget');
1028+
returnthis[kHandlers]?.get(name)?.handler??null;
1029+
}
1030+
ObjectDefineProperty(get,'name',{
10251031
__proto__: null,
1026-
get(){
1027-
returnthis[kHandlers]?.get(name)?.handler??null;
1028-
},
1029-
set(value){
1030-
if(!this[kHandlers]){
1031-
this[kHandlers]=newSafeMap();
1032+
value: `get ${propName}`,
1033+
});
1034+
1035+
functionset(value){
1036+
validateInternalField(this,kHandlers,'EventTarget');
1037+
letwrappedHandler=this[kHandlers]?.get(name);
1038+
if(wrappedHandler){
1039+
if(typeofwrappedHandler.handler==='function'){
1040+
this[kEvents].get(name).size--;
1041+
constsize=this[kEvents].get(name).size;
1042+
this[kRemoveListener](size,name,wrappedHandler.handler,false);
10321043
}
1033-
letwrappedHandler=this[kHandlers]?.get(name);
1034-
if(wrappedHandler){
1035-
if(typeofwrappedHandler.handler==='function'){
1036-
this[kEvents].get(name).size--;
1037-
constsize=this[kEvents].get(name).size;
1038-
this[kRemoveListener](size,name,wrappedHandler.handler,false);
1039-
}
1040-
wrappedHandler.handler=value;
1041-
if(typeofwrappedHandler.handler==='function'){
1042-
this[kEvents].get(name).size++;
1043-
constsize=this[kEvents].get(name).size;
1044-
this[kNewListener](size,name,value,false,false,false,false);
1045-
}
1046-
}else{
1047-
wrappedHandler=makeEventHandler(value);
1048-
this.addEventListener(name,wrappedHandler);
1044+
wrappedHandler.handler=value;
1045+
if(typeofwrappedHandler.handler==='function'){
1046+
this[kEvents].get(name).size++;
1047+
constsize=this[kEvents].get(name).size;
1048+
this[kNewListener](size,name,value,false,false,false,false);
10491049
}
1050-
this[kHandlers].set(name,wrappedHandler);
1051-
},
1050+
}else{
1051+
wrappedHandler=makeEventHandler(value);
1052+
this.addEventListener(name,wrappedHandler);
1053+
}
1054+
this[kHandlers].set(name,wrappedHandler);
1055+
}
1056+
ObjectDefineProperty(set,'name',{
1057+
__proto__: null,
1058+
value: `set ${propName}`,
1059+
});
1060+
1061+
ObjectDefineProperty(emitter,propName,{
1062+
__proto__: null,
1063+
get,
1064+
set,
10521065
configurable: true,
10531066
enumerable: true
10541067
});

‎lib/internal/validators.js‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,12 @@ function validateLinkHeaderValue(value, name) {
418418
}
419419
}
420420

421+
constvalidateInternalField=hideStackFrames((object,fieldKey,className)=>{
422+
if(typeofobject!=='object'||object===null||!ObjectPrototypeHasOwnProperty(object,fieldKey)){
423+
thrownewERR_INVALID_ARG_TYPE('this',className,object);
424+
}
425+
});
426+
421427
module.exports={
422428
isInt32,
423429
isUint32,
@@ -440,5 +446,6 @@ module.exports = {
440446
validateUndefined,
441447
validateUnion,
442448
validateAbortSignal,
443-
validateLinkHeaderValue
449+
validateLinkHeaderValue,
450+
validateInternalField,
444451
};

0 commit comments

Comments
 (0)