1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

fix(ext/web): align DOMException better with spec (#15097)

This commit is contained in:
Phosra 2022-07-20 01:12:18 -07:00 committed by GitHub
parent 2b1f145c3e
commit b8e1250500
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 39 deletions

View file

@ -1,4 +1,8 @@
import { assertEquals, assertStringIncludes } from "./test_util.ts"; import {
assertEquals,
assertNotEquals,
assertStringIncludes,
} from "./test_util.ts";
Deno.test(function customInspectFunction() { Deno.test(function customInspectFunction() {
const blob = new DOMException("test"); const blob = new DOMException("test");
@ -8,3 +12,13 @@ Deno.test(function customInspectFunction() {
); );
assertStringIncludes(Deno.inspect(DOMException.prototype), "DOMException"); assertStringIncludes(Deno.inspect(DOMException.prototype), "DOMException");
}); });
Deno.test(function nameToCodeMappingPrototypeAccess() {
const newCode = 100;
const objectPrototype = Object.prototype as unknown as {
pollution: number;
};
objectPrototype.pollution = newCode;
assertNotEquals(newCode, new DOMException("test", "pollution").code);
Reflect.deleteProperty(objectPrototype, "pollution");
});

View file

@ -15,16 +15,22 @@
Error, Error,
ErrorPrototype, ErrorPrototype,
ObjectDefineProperty, ObjectDefineProperty,
ObjectCreate,
ObjectEntries, ObjectEntries,
ObjectPrototypeIsPrototypeOf, ObjectPrototypeIsPrototypeOf,
ObjectSetPrototypeOf, ObjectSetPrototypeOf,
Symbol,
SymbolFor, SymbolFor,
} = window.__bootstrap.primordials; } = window.__bootstrap.primordials;
const webidl = window.__bootstrap.webidl; const webidl = window.__bootstrap.webidl;
const consoleInternal = window.__bootstrap.console; const consoleInternal = window.__bootstrap.console;
const _name = Symbol("name");
const _message = Symbol("message");
const _code = Symbol("code");
// Defined in WebIDL 4.3. // Defined in WebIDL 4.3.
// https://heycam.github.io/webidl/#idl-DOMException // https://webidl.spec.whatwg.org/#idl-DOMException
const INDEX_SIZE_ERR = 1; const INDEX_SIZE_ERR = 1;
const DOMSTRING_SIZE_ERR = 2; const DOMSTRING_SIZE_ERR = 2;
const HIERARCHY_REQUEST_ERR = 3; const HIERARCHY_REQUEST_ERR = 3;
@ -52,52 +58,60 @@
const DATA_CLONE_ERR = 25; const DATA_CLONE_ERR = 25;
// Defined in WebIDL 2.8.1. // Defined in WebIDL 2.8.1.
// https://heycam.github.io/webidl/#dfn-error-names-table // https://webidl.spec.whatwg.org/#dfn-error-names-table
/** @type {Record<string, number>} */ /** @type {Record<string, number>} */
const nameToCodeMapping = { // the prototype should be null, to prevent user code from looking
IndexSizeError: INDEX_SIZE_ERR, // up Object.prototype properties, such as "toString"
HierarchyRequestError: HIERARCHY_REQUEST_ERR, const nameToCodeMapping = ObjectCreate(null, {
WrongDocumentError: WRONG_DOCUMENT_ERR, IndexSizeError: { value: INDEX_SIZE_ERR },
InvalidCharacterError: INVALID_CHARACTER_ERR, HierarchyRequestError: { value: HIERARCHY_REQUEST_ERR },
NoModificationAllowedError: NO_MODIFICATION_ALLOWED_ERR, WrongDocumentError: { value: WRONG_DOCUMENT_ERR },
NotFoundError: NOT_FOUND_ERR, InvalidCharacterError: { value: INVALID_CHARACTER_ERR },
NotSupportedError: NOT_SUPPORTED_ERR, NoModificationAllowedError: { value: NO_MODIFICATION_ALLOWED_ERR },
InUseAttributeError: INUSE_ATTRIBUTE_ERR, NotFoundError: { value: NOT_FOUND_ERR },
InvalidStateError: INVALID_STATE_ERR, NotSupportedError: { value: NOT_SUPPORTED_ERR },
SyntaxError: SYNTAX_ERR, InUseAttributeError: { value: INUSE_ATTRIBUTE_ERR },
InvalidModificationError: INVALID_MODIFICATION_ERR, InvalidStateError: { value: INVALID_STATE_ERR },
NamespaceError: NAMESPACE_ERR, SyntaxError: { value: SYNTAX_ERR },
InvalidAccessError: INVALID_ACCESS_ERR, InvalidModificationError: { value: INVALID_MODIFICATION_ERR },
TypeMismatchError: TYPE_MISMATCH_ERR, NamespaceError: { value: NAMESPACE_ERR },
SecurityError: SECURITY_ERR, InvalidAccessError: { value: INVALID_ACCESS_ERR },
NetworkError: NETWORK_ERR, TypeMismatchError: { value: TYPE_MISMATCH_ERR },
AbortError: ABORT_ERR, SecurityError: { value: SECURITY_ERR },
URLMismatchError: URL_MISMATCH_ERR, NetworkError: { value: NETWORK_ERR },
QuotaExceededError: QUOTA_EXCEEDED_ERR, AbortError: { value: ABORT_ERR },
TimeoutError: TIMEOUT_ERR, URLMismatchError: { value: URL_MISMATCH_ERR },
InvalidNodeTypeError: INVALID_NODE_TYPE_ERR, QuotaExceededError: { value: QUOTA_EXCEEDED_ERR },
DataCloneError: DATA_CLONE_ERR, TimeoutError: { value: TIMEOUT_ERR },
}; InvalidNodeTypeError: { value: INVALID_NODE_TYPE_ERR },
DataCloneError: { value: DATA_CLONE_ERR },
});
// Defined in WebIDL 4.3. // Defined in WebIDL 4.3.
// https://heycam.github.io/webidl/#idl-DOMException // https://webidl.spec.whatwg.org/#idl-DOMException
class DOMException { class DOMException {
#message = ""; [_message];
#name = ""; [_name];
#code = 0; [_code];
// https://webidl.spec.whatwg.org/#dom-domexception-domexception
constructor(message = "", name = "Error") { constructor(message = "", name = "Error") {
this.#message = webidl.converters.DOMString(message, { message = webidl.converters.DOMString(message, {
prefix: "Failed to construct 'DOMException'", prefix: "Failed to construct 'DOMException'",
context: "Argument 1", context: "Argument 1",
}); });
this.#name = webidl.converters.DOMString(name, { name = webidl.converters.DOMString(name, {
prefix: "Failed to construct 'DOMException'", prefix: "Failed to construct 'DOMException'",
context: "Argument 2", context: "Argument 2",
}); });
this.#code = nameToCodeMapping[this.#name] ?? 0; const code = nameToCodeMapping[name] ?? 0;
const error = new Error(this.#message); this[_message] = message;
this[_name] = name;
this[_code] = code;
this[webidl.brand] = webidl.brand;
const error = new Error(message);
error.name = "DOMException"; error.name = "DOMException";
ObjectDefineProperty(this, "stack", { ObjectDefineProperty(this, "stack", {
value: error.stack, value: error.stack,
@ -115,20 +129,23 @@
} }
get message() { get message() {
return this.#message; webidl.assertBranded(this, DOMExceptionPrototype);
return this[_message];
} }
get name() { get name() {
return this.#name; webidl.assertBranded(this, DOMExceptionPrototype);
return this[_name];
} }
get code() { get code() {
return this.#code; webidl.assertBranded(this, DOMExceptionPrototype);
return this[_code];
} }
[SymbolFor("Deno.customInspect")](inspect) { [SymbolFor("Deno.customInspect")](inspect) {
if (ObjectPrototypeIsPrototypeOf(DOMExceptionPrototype, this)) { if (ObjectPrototypeIsPrototypeOf(DOMExceptionPrototype, this)) {
return `DOMException: ${this.#message}`; return `DOMException: ${this[_message]}`;
} else { } else {
return inspect(consoleInternal.createFilteredInspectProxy({ return inspect(consoleInternal.createFilteredInspectProxy({
object: this, object: this,