Skip to content

Commit fa447b5

Browse files
KhafraDevMoLow
authored andcommitted
lib: use webidl DOMString converter in EventTarget
PR-URL: #47514 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
1 parent 114b847 commit fa447b5

4 files changed

Lines changed: 196 additions & 2 deletions

File tree

‎lib/internal/event_target.js‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const {
4242
kEnumerableProperty,
4343
}=require('internal/util');
4444
const{ inspect }=require('util');
45+
constwebidl=require('internal/webidl');
4546

4647
constkIsEventTarget=SymbolFor('nodejs.event_target');
4748
constkIsNodeEventTarget=Symbol('kIsNodeEventTarget');
@@ -577,7 +578,7 @@ class EventTarget {
577578
process.emitWarning(w);
578579
return;
579580
}
580-
type=String(type);
581+
type=webidl.converters.DOMString(type);
581582

582583
if(signal){
583584
if(signal.aborted){
@@ -643,7 +644,7 @@ class EventTarget {
643644
if(!validateEventListener(listener))
644645
return;
645646

646-
type=String(type);
647+
type=webidl.converters.DOMString(type);
647648
constcapture=options?.capture===true;
648649

649650
constroot=this[kEvents].get(type);

‎lib/internal/webidl.js‎

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
'use strict';
2+
3+
const{
4+
MathAbs,
5+
MathMax,
6+
MathMin,
7+
MathPow,
8+
MathSign,
9+
MathTrunc,
10+
NumberIsNaN,
11+
NumberMAX_SAFE_INTEGER,
12+
NumberMIN_SAFE_INTEGER,
13+
String,
14+
}=primordials;
15+
16+
const{
17+
codes: {
18+
ERR_INVALID_ARG_VALUE,
19+
},
20+
}=require('internal/errors');
21+
const{ kEmptyObject }=require('internal/util');
22+
23+
constconverters={__proto__: null};
24+
25+
// https://webidl.spec.whatwg.org/#abstract-opdef-integerpart
26+
constintegerPart=MathTrunc;
27+
28+
/* eslint-disable node-core/non-ascii-character */
29+
// Round x to the nearest integer, choosing the even integer if it lies halfway
30+
// between two, and choosing +0 rather than -0.
31+
// This is different from Math.round, which rounds to the next integer in the
32+
// direction of +∞ when the fraction portion is exactly 0.5.
33+
/* eslint-enable node-core/non-ascii-character */
34+
functionevenRound(x){
35+
// Convert -0 to +0.
36+
consti=integerPart(x)+0;
37+
constreminder=MathAbs(x%1);
38+
constsign=MathSign(i);
39+
if(reminder===0.5){
40+
returni%2===0 ? i : i+sign;
41+
}
42+
constr=reminder<0.5 ? i : i+sign;
43+
// Convert -0 to +0.
44+
if(r===0){
45+
return0;
46+
}
47+
returnr;
48+
}
49+
50+
functionpow2(exponent){
51+
// << operates on 32 bit signed integers.
52+
if(exponent<31){
53+
return1<<exponent;
54+
}
55+
if(exponent===31){
56+
return0x8000_0000;
57+
}
58+
if(exponent===32){
59+
return0x1_0000_0000;
60+
}
61+
returnMathPow(2,exponent);
62+
}
63+
64+
// https://tc39.es/ecma262/#eqn-modulo
65+
// The notation “x modulo y” computes a value k of the same sign as y.
66+
functionmodulo(x,y){
67+
constr=x%y;
68+
// Convert -0 to +0.
69+
if(r===0){
70+
return0;
71+
}
72+
returnr;
73+
}
74+
75+
// https://webidl.spec.whatwg.org/#abstract-opdef-converttoint
76+
functionconvertToInt(name,value,bitLength,options=kEmptyObject){
77+
const{ signed =false, enforceRange =false, clamp =false}=options;
78+
79+
letupperBound;
80+
letlowerBound;
81+
// 1. If bitLength is 64, then:
82+
if(bitLength===64){
83+
// 1.1. Let upperBound be 2^53 − 1.
84+
upperBound=NumberMAX_SAFE_INTEGER;
85+
// 1.2. If signedness is "unsigned", then let lowerBound be 0.
86+
// 1.3. Otherwise let lowerBound be −2^53 + 1.
87+
lowerBound=!signed ? 0 : NumberMIN_SAFE_INTEGER;
88+
}elseif(!signed){
89+
// 2. Otherwise, if signedness is "unsigned", then:
90+
// 2.1. Let lowerBound be 0.
91+
// 2.2. Let upperBound be 2^bitLength − 1.
92+
lowerBound=0;
93+
upperBound=pow2(bitLength)-1;
94+
}else{
95+
// 3. Otherwise:
96+
// 3.1. Let lowerBound be -2^(bitLength − 1).
97+
// 3.2. Let upperBound be 2^(bitLength − 1) − 1.
98+
lowerBound=-pow2(bitLength-1);
99+
upperBound=pow2(bitLength-1)-1;
100+
}
101+
102+
// 4. Let x be ? ToNumber(V).
103+
letx=+value;
104+
// 5. If x is −0, then set x to +0.
105+
if(x===0){
106+
x=0;
107+
}
108+
109+
// 6. If the conversion is to an IDL type associated with the [EnforceRange]
110+
// extended attribute, then:
111+
if(enforceRange){
112+
// 6.1. If x is NaN, +∞, or −∞, then throw a TypeError.
113+
if(NumberIsNaN(x)||x===Infinity||x===-Infinity){
114+
thrownewERR_INVALID_ARG_VALUE(name,x);
115+
}
116+
// 6.2. Set x to IntegerPart(x).
117+
x=integerPart(x);
118+
119+
// 6.3. If x < lowerBound or x > upperBound, then throw a TypeError.
120+
if(x<lowerBound||x>upperBound){
121+
thrownewERR_INVALID_ARG_VALUE(name,x);
122+
}
123+
124+
// 6.4. Return x.
125+
returnx;
126+
}
127+
128+
// 7. If x is not NaN and the conversion is to an IDL type associated with
129+
// the [Clamp] extended attribute, then:
130+
if(clamp&&!NumberIsNaN(x)){
131+
// 7.1. Set x to min(max(x, lowerBound), upperBound).
132+
x=MathMin(MathMax(x,lowerBound),upperBound);
133+
134+
// 7.2. Round x to the nearest integer, choosing the even integer if it
135+
// lies halfway between two, and choosing +0 rather than −0.
136+
x=evenRound(x);
137+
138+
// 7.3. Return x.
139+
returnx;
140+
}
141+
142+
// 8. If x is NaN, +0, +∞, or −∞, then return +0.
143+
if(NumberIsNaN(x)||x===0||x===Infinity||x===-Infinity){
144+
return0;
145+
}
146+
147+
// 9. Set x to IntegerPart(x).
148+
x=integerPart(x);
149+
150+
// 10. Set x to x modulo 2^bitLength.
151+
x=modulo(x,pow2(bitLength));
152+
153+
// 11. If signedness is "signed" and x ≥ 2^(bitLength − 1), then return x −
154+
// 2^bitLength.
155+
if(signed&&x>=pow2(bitLength-1)){
156+
returnx-pow2(bitLength);
157+
}
158+
159+
// 12. Otherwise, return x.
160+
returnx;
161+
}
162+
163+
/**
164+
* @see https://webidl.spec.whatwg.org/#es-DOMString
165+
* @param {any} V
166+
* @returns {string}
167+
*/
168+
converters.DOMString=functionDOMString(V){
169+
if(typeofV==='symbol'){
170+
thrownewERR_INVALID_ARG_VALUE('value',V);
171+
}
172+
173+
returnString(V);
174+
};
175+
176+
module.exports={
177+
convertToInt,
178+
evenRound,
179+
converters,
180+
};

‎test/parallel/test-bootstrap-modules.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ const expectedModules = new Set([
151151
'NativeModule internal/vm',
152152
'NativeModule internal/vm/module',
153153
'NativeModule internal/wasm_web_api',
154+
'NativeModule internal/webidl',
154155
'NativeModule internal/webstreams/adapters',
155156
'NativeModule internal/webstreams/compression',
156157
'NativeModule internal/webstreams/encoding',

‎test/parallel/test-eventtarget.js‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,3 +705,15 @@ let asyncTest = Promise.resolve();
705705
name: 'TypeError',
706706
});
707707
}
708+
709+
{
710+
constet=newEventTarget();
711+
712+
throws(()=>{
713+
et.addEventListener(Symbol('symbol'),()=>{});
714+
},TypeError);
715+
716+
throws(()=>{
717+
et.removeEventListener(Symbol('symbol'),()=>{});
718+
},TypeError);
719+
}

0 commit comments

Comments
 (0)