Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit fa447b5

Browse filesBrowse 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
Copy full SHA for fa447b5

File tree

Expand file treeCollapse file tree

4 files changed

+196
-2
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

4 files changed

+196
-2
lines changed
Open diff view settings
Collapse file

‎lib/internal/event_target.js‎

Copy file name to clipboardExpand all lines: lib/internal/event_target.js
+3-2Lines 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+
const webidl = require('internal/webidl');
4546

4647
const kIsEventTarget = SymbolFor('nodejs.event_target');
4748
const kIsNodeEventTarget = 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
const capture = options?.capture === true;
648649

649650
const root = this[kEvents].get(type);
Collapse file

‎lib/internal/webidl.js‎

Copy file name to clipboard
+180Lines 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+
const converters = { __proto__: null };
24+
25+
// https://webidl.spec.whatwg.org/#abstract-opdef-integerpart
26+
const integerPart = 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+
function evenRound(x) {
35+
// Convert -0 to +0.
36+
const i = integerPart(x) + 0;
37+
const reminder = MathAbs(x % 1);
38+
const sign = MathSign(i);
39+
if (reminder === 0.5) {
40+
return i % 2 === 0 ? i : i + sign;
41+
}
42+
const r = reminder < 0.5 ? i : i + sign;
43+
// Convert -0 to +0.
44+
if (r === 0) {
45+
return 0;
46+
}
47+
return r;
48+
}
49+
50+
function pow2(exponent) {
51+
// << operates on 32 bit signed integers.
52+
if (exponent < 31) {
53+
return 1 << exponent;
54+
}
55+
if (exponent === 31) {
56+
return 0x8000_0000;
57+
}
58+
if (exponent === 32) {
59+
return 0x1_0000_0000;
60+
}
61+
return MathPow(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+
function modulo(x, y) {
67+
const r = x % y;
68+
// Convert -0 to +0.
69+
if (r === 0) {
70+
return 0;
71+
}
72+
return r;
73+
}
74+
75+
// https://webidl.spec.whatwg.org/#abstract-opdef-converttoint
76+
function convertToInt(name, value, bitLength, options = kEmptyObject) {
77+
const { signed = false, enforceRange = false, clamp = false } = options;
78+
79+
let upperBound;
80+
let lowerBound;
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+
} else if (!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+
let x = +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+
throw new ERR_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+
throw new ERR_INVALID_ARG_VALUE(name, x);
122+
}
123+
124+
// 6.4. Return x.
125+
return x;
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+
return x;
140+
}
141+
142+
// 8. If x is NaN, +0, +∞, or −∞, then return +0.
143+
if (NumberIsNaN(x) || x === 0 || x === Infinity || x === -Infinity) {
144+
return 0;
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+
return x - pow2(bitLength);
157+
}
158+
159+
// 12. Otherwise, return x.
160+
return x;
161+
}
162+
163+
/**
164+
* @see https://webidl.spec.whatwg.org/#es-DOMString
165+
* @param {any} V
166+
* @returns {string}
167+
*/
168+
converters.DOMString = function DOMString(V) {
169+
if (typeof V === 'symbol') {
170+
throw new ERR_INVALID_ARG_VALUE('value', V);
171+
}
172+
173+
return String(V);
174+
};
175+
176+
module.exports = {
177+
convertToInt,
178+
evenRound,
179+
converters,
180+
};
Collapse file

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

Copy file name to clipboardExpand all lines: test/parallel/test-bootstrap-modules.js
+1Lines 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',
Collapse file

‎test/parallel/test-eventtarget.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-eventtarget.js
+12Lines 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+
const et = new EventTarget();
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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.