mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 21:58:48 +02:00
lib: brand check event handler property receivers
Event handler properties defined by `defineEventHandler` should check if the receiver is a valid `EventTarget`. PR-URL: https://github.com/nodejs/node/pull/44483 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
ecd5de08b7
commit
f529f73bd7
2 changed files with 47 additions and 27 deletions
|
@ -34,7 +34,7 @@ const {
|
||||||
ERR_INVALID_THIS,
|
ERR_INVALID_THIS,
|
||||||
}
|
}
|
||||||
} = require('internal/errors');
|
} = require('internal/errors');
|
||||||
const { validateObject, validateString } = require('internal/validators');
|
const { validateObject, validateString, validateInternalField } = require('internal/validators');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
customInspectSymbol,
|
customInspectSymbol,
|
||||||
|
@ -492,6 +492,7 @@ function initEventTarget(self) {
|
||||||
self[kEvents] = new SafeMap();
|
self[kEvents] = new SafeMap();
|
||||||
self[kMaxEventTargetListeners] = EventEmitter.defaultMaxListeners;
|
self[kMaxEventTargetListeners] = EventEmitter.defaultMaxListeners;
|
||||||
self[kMaxEventTargetListenersWarned] = false;
|
self[kMaxEventTargetListenersWarned] = false;
|
||||||
|
self[kHandlers] = new SafeMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
class EventTarget {
|
class EventTarget {
|
||||||
|
@ -1021,34 +1022,46 @@ function makeEventHandler(handler) {
|
||||||
|
|
||||||
function defineEventHandler(emitter, name) {
|
function defineEventHandler(emitter, name) {
|
||||||
// 8.1.5.1 Event handlers - basically `on[eventName]` attributes
|
// 8.1.5.1 Event handlers - basically `on[eventName]` attributes
|
||||||
ObjectDefineProperty(emitter, `on${name}`, {
|
const propName = `on${name}`;
|
||||||
|
function get() {
|
||||||
|
validateInternalField(this, kHandlers, 'EventTarget');
|
||||||
|
return this[kHandlers]?.get(name)?.handler ?? null;
|
||||||
|
}
|
||||||
|
ObjectDefineProperty(get, 'name', {
|
||||||
__proto__: null,
|
__proto__: null,
|
||||||
get() {
|
value: `get ${propName}`,
|
||||||
return this[kHandlers]?.get(name)?.handler ?? null;
|
});
|
||||||
},
|
|
||||||
set(value) {
|
function set(value) {
|
||||||
if (!this[kHandlers]) {
|
validateInternalField(this, kHandlers, 'EventTarget');
|
||||||
this[kHandlers] = new SafeMap();
|
let wrappedHandler = this[kHandlers]?.get(name);
|
||||||
|
if (wrappedHandler) {
|
||||||
|
if (typeof wrappedHandler.handler === 'function') {
|
||||||
|
this[kEvents].get(name).size--;
|
||||||
|
const size = this[kEvents].get(name).size;
|
||||||
|
this[kRemoveListener](size, name, wrappedHandler.handler, false);
|
||||||
}
|
}
|
||||||
let wrappedHandler = this[kHandlers]?.get(name);
|
wrappedHandler.handler = value;
|
||||||
if (wrappedHandler) {
|
if (typeof wrappedHandler.handler === 'function') {
|
||||||
if (typeof wrappedHandler.handler === 'function') {
|
this[kEvents].get(name).size++;
|
||||||
this[kEvents].get(name).size--;
|
const size = this[kEvents].get(name).size;
|
||||||
const size = this[kEvents].get(name).size;
|
this[kNewListener](size, name, value, false, false, false, false);
|
||||||
this[kRemoveListener](size, name, wrappedHandler.handler, false);
|
|
||||||
}
|
|
||||||
wrappedHandler.handler = value;
|
|
||||||
if (typeof wrappedHandler.handler === 'function') {
|
|
||||||
this[kEvents].get(name).size++;
|
|
||||||
const size = this[kEvents].get(name).size;
|
|
||||||
this[kNewListener](size, name, value, false, false, false, false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
wrappedHandler = makeEventHandler(value);
|
|
||||||
this.addEventListener(name, wrappedHandler);
|
|
||||||
}
|
}
|
||||||
this[kHandlers].set(name, wrappedHandler);
|
} else {
|
||||||
},
|
wrappedHandler = makeEventHandler(value);
|
||||||
|
this.addEventListener(name, wrappedHandler);
|
||||||
|
}
|
||||||
|
this[kHandlers].set(name, wrappedHandler);
|
||||||
|
}
|
||||||
|
ObjectDefineProperty(set, 'name', {
|
||||||
|
__proto__: null,
|
||||||
|
value: `set ${propName}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
ObjectDefineProperty(emitter, propName, {
|
||||||
|
__proto__: null,
|
||||||
|
get,
|
||||||
|
set,
|
||||||
configurable: true,
|
configurable: true,
|
||||||
enumerable: true
|
enumerable: true
|
||||||
});
|
});
|
||||||
|
|
|
@ -418,6 +418,12 @@ function validateLinkHeaderValue(value, name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const validateInternalField = hideStackFrames((object, fieldKey, className) => {
|
||||||
|
if (typeof object !== 'object' || object === null || !ObjectPrototypeHasOwnProperty(object, fieldKey)) {
|
||||||
|
throw new ERR_INVALID_ARG_TYPE('this', className, object);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
isInt32,
|
isInt32,
|
||||||
isUint32,
|
isUint32,
|
||||||
|
@ -440,5 +446,6 @@ module.exports = {
|
||||||
validateUndefined,
|
validateUndefined,
|
||||||
validateUnion,
|
validateUnion,
|
||||||
validateAbortSignal,
|
validateAbortSignal,
|
||||||
validateLinkHeaderValue
|
validateLinkHeaderValue,
|
||||||
|
validateInternalField,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue