0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-09 13:49:37 -04:00

fix(inspect): eliminate panic inspecting event classes (#10979)

This commit is contained in:
David Sherret 2021-06-24 09:43:41 -04:00 committed by Ryan Dahl
parent 8f699d6133
commit 1909da47fe
2 changed files with 79 additions and 15 deletions

View file

@ -1,5 +1,10 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
import { assert, assertEquals, unitTest } from "./test_util.ts"; import {
assert,
assertEquals,
assertStringIncludes,
unitTest,
} from "./test_util.ts";
unitTest(function eventInitializedWithType(): void { unitTest(function eventInitializedWithType(): void {
const type = "click"; const type = "click";
@ -127,3 +132,30 @@ unitTest(function eventInspectOutput(): void {
assertEquals(Deno.inspect(event), outputProvider(event)); assertEquals(Deno.inspect(event), outputProvider(event));
} }
}); });
unitTest(function inspectEvent(): void {
// has a customInspect implementation that previously would throw on a getter
assertEquals(
Deno.inspect(Event.prototype),
`Event {
bubbles: [Getter/Setter],
cancelable: [Getter/Setter],
composed: [Getter/Setter],
currentTarget: [Getter/Setter],
defaultPrevented: [Getter/Setter],
eventPhase: [Getter/Setter],
srcElement: [Getter/Setter],
target: [Getter/Setter],
returnValue: [Getter/Setter],
timeStamp: [Getter/Setter],
type: [Getter/Setter]
}`,
);
// ensure this still works
assertStringIncludes(
Deno.inspect(new Event("test")),
// check a substring because one property is a timestamp
`Event {\n bubbles: false,\n cancelable: false,`,
);
});

View file

@ -144,7 +144,7 @@
} }
[Symbol.for("Deno.customInspect")](inspect) { [Symbol.for("Deno.customInspect")](inspect) {
return buildCustomInspectOutput(this, EVENT_PROPS, inspect); return inspect(buildFilteredPropertyInspectObject(this, EVENT_PROPS));
} }
get type() { get type() {
@ -395,9 +395,41 @@
} }
} }
function buildCustomInspectOutput(object, keys, inspect) { function buildFilteredPropertyInspectObject(object, keys) {
const inspectObject = Object.fromEntries(keys.map((k) => [k, object[k]])); // forward the subset of properties from `object` without evaluating
return `${object.constructor.name} ${inspect(inspectObject)}`; // as evaluation could lead to an error, which is better handled
// in the inspect code
return new Proxy({}, {
get(_target, key) {
if (key === Symbol.toStringTag) {
return object.constructor?.name;
} else if (keys.includes(key)) {
return Reflect.get(object, key);
} else {
return undefined;
}
},
getOwnPropertyDescriptor(_target, key) {
if (!keys.includes(key)) {
return undefined;
}
return Reflect.getOwnPropertyDescriptor(object, key) ??
(object.prototype &&
Reflect.getOwnPropertyDescriptor(object.prototype, key)) ??
{
configurable: true,
enumerable: true,
value: object[key],
};
},
has(_target, key) {
return keys.includes(key);
},
ownKeys() {
return keys;
},
});
} }
function defineEnumerableProps( function defineEnumerableProps(
@ -1053,14 +1085,14 @@
} }
[Symbol.for("Deno.customInspect")](inspect) { [Symbol.for("Deno.customInspect")](inspect) {
return buildCustomInspectOutput(this, [ return inspect(buildFilteredPropertyInspectObject(this, [
...EVENT_PROPS, ...EVENT_PROPS,
"message", "message",
"filename", "filename",
"lineno", "lineno",
"colno", "colno",
"error", "error",
], inspect); ]));
} }
} }
@ -1107,12 +1139,12 @@
} }
[Symbol.for("Deno.customInspect")](inspect) { [Symbol.for("Deno.customInspect")](inspect) {
return buildCustomInspectOutput(this, [ return inspect(buildFilteredPropertyInspectObject(this, [
...EVENT_PROPS, ...EVENT_PROPS,
"wasClean", "wasClean",
"code", "code",
"reason", "reason",
], inspect); ]));
} }
} }
@ -1134,12 +1166,12 @@
} }
[Symbol.for("Deno.customInspect")](inspect) { [Symbol.for("Deno.customInspect")](inspect) {
return buildCustomInspectOutput(this, [ return inspect(buildFilteredPropertyInspectObject(this, [
...EVENT_PROPS, ...EVENT_PROPS,
"data", "data",
"origin", "origin",
"lastEventId", "lastEventId",
], inspect); ]));
} }
} }
@ -1164,10 +1196,10 @@
} }
[Symbol.for("Deno.customInspect")](inspect) { [Symbol.for("Deno.customInspect")](inspect) {
return buildCustomInspectOutput(this, [ return inspect(buildFilteredPropertyInspectObject(this, [
...EVENT_PROPS, ...EVENT_PROPS,
"detail", "detail",
], inspect); ]));
} }
} }
@ -1187,12 +1219,12 @@
} }
[Symbol.for("Deno.customInspect")](inspect) { [Symbol.for("Deno.customInspect")](inspect) {
return buildCustomInspectOutput(this, [ return inspect(buildFilteredPropertyInspectObject(this, [
...EVENT_PROPS, ...EVENT_PROPS,
"lengthComputable", "lengthComputable",
"loaded", "loaded",
"total", "total",
], inspect); ]));
} }
} }