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

fix(runtime): use more null proto objects (#23921)

This is a primordialization effort to improve resistance against users
tampering with the global `Object` prototype.

---------

Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This commit is contained in:
Luca Casonato 2024-05-23 00:03:35 +02:00 committed by GitHub
parent 6c167c64d6
commit 971f09abe4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 141 additions and 92 deletions

View file

@ -342,7 +342,7 @@ function enableJupyter() {
async function broadcast( async function broadcast(
msgType, msgType,
content, content,
{ metadata = {}, buffers = [] } = {}, { metadata = { __proto__: null }, buffers = [] } = { __proto__: null },
) { ) {
await op_jupyter_broadcast(msgType, content, metadata, buffers); await op_jupyter_broadcast(msgType, content, metadata, buffers);
} }
@ -400,7 +400,7 @@ function enableJupyter() {
if (options.update) { if (options.update) {
messageType = "update_display_data"; messageType = "update_display_data";
} }
let transient = {}; let transient = { __proto__: null };
if (options.display_id) { if (options.display_id) {
transient = { display_id: options.display_id }; transient = { display_id: options.display_id };
} }

View file

@ -196,7 +196,7 @@ function testInner(
nameOrFnOrOptions, nameOrFnOrOptions,
optionsOrFn, optionsOrFn,
maybeFn, maybeFn,
overrides = {}, overrides = { __proto__: null },
) { ) {
// No-op if we're not running in `deno test` subcommand. // No-op if we're not running in `deno test` subcommand.
if (typeof op_register_test !== "function") { if (typeof op_register_test !== "function") {

View file

@ -2930,7 +2930,7 @@ function cssToAnsi(css, prevCss = null) {
return ansi; return ansi;
} }
function inspectArgs(args, inspectOptions = {}) { function inspectArgs(args, inspectOptions = { __proto__: null }) {
const ctx = { const ctx = {
...getDefaultInspectOptions(), ...getDefaultInspectOptions(),
colors: inspectOptions.colors ?? !noColorStdout(), colors: inspectOptions.colors ?? !noColorStdout(),
@ -3124,7 +3124,7 @@ class Console {
); );
}; };
dir = (obj = undefined, options = {}) => { dir = (obj = undefined, options = { __proto__: null }) => {
this.#printFunc( this.#printFunc(
inspectArgs([obj], { inspectArgs([obj], {
...getConsoleInspectOptions(noColorStdout()), ...getConsoleInspectOptions(noColorStdout()),
@ -3232,7 +3232,7 @@ class Console {
resultData = [...new SafeSetIterator(data)]; resultData = [...new SafeSetIterator(data)];
} else if (isMapObject) { } else if (isMapObject) {
let idx = 0; let idx = 0;
resultData = {}; resultData = { __proto__: null };
MapPrototypeForEach(data, (v, k) => { MapPrototypeForEach(data, (v, k) => {
resultData[idx] = { Key: k, Values: v }; resultData[idx] = { Key: k, Values: v };
@ -3390,7 +3390,7 @@ const customInspect = SymbolFor("Deno.customInspect");
function inspect( function inspect(
value, value,
inspectOptions = {}, inspectOptions = { __proto__: null },
) { ) {
// Default options // Default options
const ctx = { const ctx = {

View file

@ -100,7 +100,7 @@ function checkForInvalidValueChars(value) {
return true; return true;
} }
let HEADER_NAME_CACHE = {}; let HEADER_NAME_CACHE = { __proto__: null };
let HEADER_CACHE_SIZE = 0; let HEADER_CACHE_SIZE = 0;
const HEADER_NAME_CACHE_SIZE_BOUNDARY = 4096; const HEADER_NAME_CACHE_SIZE_BOUNDARY = 4096;
function checkHeaderNameForHttpTokenCodePoint(name) { function checkHeaderNameForHttpTokenCodePoint(name) {
@ -112,7 +112,7 @@ function checkHeaderNameForHttpTokenCodePoint(name) {
const valid = RegExpPrototypeTest(HTTP_TOKEN_CODE_POINT_RE, name); const valid = RegExpPrototypeTest(HTTP_TOKEN_CODE_POINT_RE, name);
if (HEADER_CACHE_SIZE > HEADER_NAME_CACHE_SIZE_BOUNDARY) { if (HEADER_CACHE_SIZE > HEADER_NAME_CACHE_SIZE_BOUNDARY) {
HEADER_NAME_CACHE = {}; HEADER_NAME_CACHE = { __proto__: null };
HEADER_CACHE_SIZE = 0; HEADER_CACHE_SIZE = 0;
} }
HEADER_CACHE_SIZE++; HEADER_CACHE_SIZE++;
@ -241,7 +241,7 @@ class Headers {
// The order of steps are not similar to the ones suggested by the // The order of steps are not similar to the ones suggested by the
// spec but produce the same result. // spec but produce the same result.
const seenHeaders = {}; const seenHeaders = { __proto__: null };
const entries = []; const entries = [];
for (let i = 0; i < list.length; ++i) { for (let i = 0; i < list.length; ++i) {
const entry = list[i]; const entry = list[i];

View file

@ -300,7 +300,7 @@ class Request {
* @param {RequestInfo} input * @param {RequestInfo} input
* @param {RequestInit} init * @param {RequestInit} init
*/ */
constructor(input, init = {}) { constructor(input, init = { __proto__: null }) {
if (input === _brand) { if (input === _brand) {
this[_brand] = _brand; this[_brand] = _brand;
return; return;

View file

@ -282,7 +282,7 @@ class Response {
* @param {ResponseInit} init * @param {ResponseInit} init
* @returns {Response} * @returns {Response}
*/ */
static json(data = undefined, init = {}) { static json(data = undefined, init = { __proto__: null }) {
const prefix = "Failed to execute 'Response.json'"; const prefix = "Failed to execute 'Response.json'";
data = webidl.converters.any(data); data = webidl.converters.any(data);
init = webidl.converters["ResponseInit_fast"](init, prefix, "Argument 2"); init = webidl.converters["ResponseInit_fast"](init, prefix, "Argument 2");

View file

@ -305,7 +305,7 @@ function httpRedirectFetch(request, response, terminator) {
* @param {RequestInfo} input * @param {RequestInfo} input
* @param {RequestInit} init * @param {RequestInit} init
*/ */
function fetch(input, init = {}) { function fetch(input, init = { __proto__: null }) {
// There is an async dispatch later that causes a stack trace disconnect. // There is an async dispatch later that causes a stack trace disconnect.
// We reconnect it by assigning the result of that dispatch to `opPromise`, // We reconnect it by assigning the result of that dispatch to `opPromise`,
// awaiting `opPromise` in an inner function also named `fetch()` and // awaiting `opPromise` in an inner function also named `fetch()` and

View file

@ -144,7 +144,7 @@ class EventSource extends EventTarget {
return this.#withCredentials; return this.#withCredentials;
} }
constructor(url, eventSourceInitDict = {}) { constructor(url, eventSourceInitDict = { __proto__: null }) {
super(); super();
this[webidl.brand] = webidl.brand; this[webidl.brand] = webidl.brand;
const prefix = "Failed to construct 'EventSource'"; const prefix = "Failed to construct 'EventSource'";

View file

@ -475,7 +475,7 @@ const UnsafeCallbackPrototype = UnsafeCallback.prototype;
class DynamicLibrary { class DynamicLibrary {
#rid; #rid;
symbols = {}; symbols = { __proto__: null };
constructor(path, symbols) { constructor(path, symbols) {
({ 0: this.#rid, 1: this.symbols } = op_ffi_load({ path, symbols })); ({ 0: this.#rid, 1: this.symbols } = op_ffi_load({ path, symbols }));

View file

@ -155,7 +155,7 @@ function chdir(directory) {
op_fs_chdir(pathFromURL(directory)); op_fs_chdir(pathFromURL(directory));
} }
function makeTempDirSync(options = {}) { function makeTempDirSync(options = { __proto__: null }) {
return op_fs_make_temp_dir_sync( return op_fs_make_temp_dir_sync(
options.dir, options.dir,
options.prefix, options.prefix,
@ -163,7 +163,7 @@ function makeTempDirSync(options = {}) {
); );
} }
function makeTempDir(options = {}) { function makeTempDir(options = { __proto__: null }) {
return op_fs_make_temp_dir_async( return op_fs_make_temp_dir_async(
options.dir, options.dir,
options.prefix, options.prefix,
@ -171,7 +171,7 @@ function makeTempDir(options = {}) {
); );
} }
function makeTempFileSync(options = {}) { function makeTempFileSync(options = { __proto__: null }) {
return op_fs_make_temp_file_sync( return op_fs_make_temp_file_sync(
options.dir, options.dir,
options.prefix, options.prefix,
@ -179,7 +179,7 @@ function makeTempFileSync(options = {}) {
); );
} }
function makeTempFile(options = {}) { function makeTempFile(options = { __proto__: null }) {
return op_fs_make_temp_file_async( return op_fs_make_temp_file_async(
options.dir, options.dir,
options.prefix, options.prefix,
@ -241,7 +241,7 @@ function realPath(path) {
function removeSync( function removeSync(
path, path,
options = {}, options = { __proto__: null },
) { ) {
op_fs_remove_sync( op_fs_remove_sync(
pathFromURL(path), pathFromURL(path),
@ -251,7 +251,7 @@ function removeSync(
async function remove( async function remove(
path, path,
options = {}, options = { __proto__: null },
) { ) {
await op_fs_remove_async( await op_fs_remove_async(
pathFromURL(path), pathFromURL(path),
@ -773,7 +773,7 @@ class FsFile {
return core.isTerminal(this.#rid); return core.isTerminal(this.#rid);
} }
setRaw(mode, options = {}) { setRaw(mode, options = { __proto__: null }) {
const cbreak = !!(options.cbreak ?? false); const cbreak = !!(options.cbreak ?? false);
op_set_raw(this.#rid, mode, cbreak); op_set_raw(this.#rid, mode, cbreak);
} }
@ -889,7 +889,7 @@ async function readTextFile(path, options) {
function writeFileSync( function writeFileSync(
path, path,
data, data,
options = {}, options = { __proto__: null },
) { ) {
options.signal?.throwIfAborted(); options.signal?.throwIfAborted();
op_fs_write_file_sync( op_fs_write_file_sync(
@ -905,7 +905,7 @@ function writeFileSync(
async function writeFile( async function writeFile(
path, path,
data, data,
options = {}, options = { __proto__: null },
) { ) {
let cancelRid; let cancelRid;
let abortHandler; let abortHandler;
@ -951,7 +951,7 @@ async function writeFile(
function writeTextFileSync( function writeTextFileSync(
path, path,
data, data,
options = {}, options = { __proto__: null },
) { ) {
const encoder = new TextEncoder(); const encoder = new TextEncoder();
return writeFileSync(path, encoder.encode(data), options); return writeFileSync(path, encoder.encode(data), options);
@ -960,7 +960,7 @@ function writeTextFileSync(
function writeTextFile( function writeTextFile(
path, path,
data, data,
options = {}, options = { __proto__: null },
) { ) {
if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, data)) { if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, data)) {
return writeFile( return writeFile(

View file

@ -591,7 +591,7 @@ function serve(arg1, arg2) {
throw new TypeError("A handler function must be provided."); throw new TypeError("A handler function must be provided.");
} }
if (options === undefined) { if (options === undefined) {
options = {}; options = { __proto__: null };
} }
const wantsHttps = hasTlsKeyPairOptions(options); const wantsHttps = hasTlsKeyPairOptions(options);

View file

@ -37,7 +37,7 @@ const _ws = Symbol("[[associated_ws]]");
const websocketCvf = buildCaseInsensitiveCommaValueFinder("websocket"); const websocketCvf = buildCaseInsensitiveCommaValueFinder("websocket");
const upgradeCvf = buildCaseInsensitiveCommaValueFinder("upgrade"); const upgradeCvf = buildCaseInsensitiveCommaValueFinder("upgrade");
function upgradeWebSocket(request, options = {}) { function upgradeWebSocket(request, options = { __proto__: null }) {
const inner = toInnerRequest(request); const inner = toInnerRequest(request);
const upgrade = request.headers.get("upgrade"); const upgrade = request.headers.get("upgrade");
const upgradeHasWebSocketOption = upgrade !== null && const upgradeHasWebSocketOption = upgrade !== null &&

View file

@ -228,7 +228,7 @@ class Stdin {
return this.#readable; return this.#readable;
} }
setRaw(mode, options = {}) { setRaw(mode, options = { __proto__: null }) {
const cbreak = !!(options.cbreak ?? false); const cbreak = !!(options.cbreak ?? false);
op_set_raw(this.#rid, mode, cbreak); op_set_raw(this.#rid, mode, cbreak);
} }

View file

@ -210,7 +210,7 @@ class Kv {
cursor?: string; cursor?: string;
reverse?: boolean; reverse?: boolean;
consistency?: Deno.KvConsistencyLevel; consistency?: Deno.KvConsistencyLevel;
} = {}, } = { __proto__: null },
): KvListIterator { ): KvListIterator {
if (options.limit !== undefined && options.limit <= 0) { if (options.limit !== undefined && options.limit <= 0) {
throw new Error("limit must be positive"); throw new Error("limit must be positive");
@ -340,7 +340,7 @@ class Kv {
finishMessageOps.clear(); finishMessageOps.clear();
} }
watch(keys: Deno.KvKey[], options = {}) { watch(keys: Deno.KvKey[], options = { __proto__: null }) {
const raw = options.raw ?? false; const raw = options.raw ?? false;
const rid = op_kv_watch(this.#rid, keys); const rid = op_kv_watch(this.#rid, keys);
const lastEntries: (Deno.KvEntryMaybe<unknown> | undefined)[] = ArrayFrom( const lastEntries: (Deno.KvEntryMaybe<unknown> | undefined)[] = ArrayFrom(

View file

@ -281,7 +281,7 @@ async function startTls(
hostname = "127.0.0.1", hostname = "127.0.0.1",
caCerts = [], caCerts = [],
alpnProtocols = undefined, alpnProtocols = undefined,
} = {}, } = { __proto__: null },
) { ) {
const { 0: rid, 1: localAddr, 2: remoteAddr } = op_tls_start({ const { 0: rid, 1: localAddr, 2: remoteAddr } = op_tls_start({
rid: conn[internalRidSymbol], rid: conn[internalRidSymbol],

View file

@ -123,7 +123,7 @@ const _isTrusted = Symbol("[[isTrusted]]");
const _path = Symbol("[[path]]"); const _path = Symbol("[[path]]");
class Event { class Event {
constructor(type, eventInitDict = {}) { constructor(type, eventInitDict = { __proto__: null }) {
// TODO(lucacasonato): remove when this interface is spec aligned // TODO(lucacasonato): remove when this interface is spec aligned
this[SymbolToStringTag] = "Event"; this[SymbolToStringTag] = "Event";
this[_canceledFlag] = false; this[_canceledFlag] = false;
@ -1095,7 +1095,7 @@ class ErrorEvent extends Event {
lineno = 0, lineno = 0,
colno = 0, colno = 0,
error, error,
} = {}, } = { __proto__: null },
) { ) {
super(type, { super(type, {
bubbles: bubbles, bubbles: bubbles,
@ -1164,7 +1164,7 @@ class CloseEvent extends Event {
wasClean = false, wasClean = false,
code = 0, code = 0,
reason = "", reason = "",
} = {}) { } = { __proto__: null }) {
super(type, { super(type, {
bubbles: bubbles, bubbles: bubbles,
cancelable: cancelable, cancelable: cancelable,
@ -1238,7 +1238,7 @@ const MessageEventPrototype = MessageEvent.prototype;
class CustomEvent extends Event { class CustomEvent extends Event {
#detail = null; #detail = null;
constructor(type, eventInitDict = {}) { constructor(type, eventInitDict = { __proto__: null }) {
super(type, eventInitDict); super(type, eventInitDict);
webidl.requiredArguments( webidl.requiredArguments(
arguments.length, arguments.length,
@ -1280,7 +1280,7 @@ ReflectDefineProperty(CustomEvent.prototype, "detail", {
// ProgressEvent could also be used in other DOM progress event emits. // ProgressEvent could also be used in other DOM progress event emits.
// Current use is for FileReader. // Current use is for FileReader.
class ProgressEvent extends Event { class ProgressEvent extends Event {
constructor(type, eventInitDict = {}) { constructor(type, eventInitDict = { __proto__: null }) {
super(type, eventInitDict); super(type, eventInitDict);
this.lengthComputable = eventInitDict?.lengthComputable ?? false; this.lengthComputable = eventInitDict?.lengthComputable ?? false;
@ -1329,7 +1329,7 @@ class PromiseRejectionEvent extends Event {
composed, composed,
promise, promise,
reason, reason,
} = {}, } = { __proto__: null },
) { ) {
super(type, { super(type, {
bubbles: bubbles, bubbles: bubbles,

View file

@ -5274,7 +5274,7 @@ class ReadableStream {
"Argument 1", "Argument 1",
); );
} else { } else {
options = {}; options = { __proto__: null };
} }
if (options.mode === undefined) { if (options.mode === undefined) {
return acquireReadableStreamDefaultReader(this); return acquireReadableStreamDefaultReader(this);
@ -5290,7 +5290,7 @@ class ReadableStream {
* @param {PipeOptions=} options * @param {PipeOptions=} options
* @returns {ReadableStream<T>} * @returns {ReadableStream<T>}
*/ */
pipeThrough(transform, options = {}) { pipeThrough(transform, options = { __proto__: null }) {
webidl.assertBranded(this, ReadableStreamPrototype); webidl.assertBranded(this, ReadableStreamPrototype);
const prefix = "Failed to execute 'pipeThrough' on 'ReadableStream'"; const prefix = "Failed to execute 'pipeThrough' on 'ReadableStream'";
webidl.requiredArguments(arguments.length, 1, prefix); webidl.requiredArguments(arguments.length, 1, prefix);
@ -5329,7 +5329,7 @@ class ReadableStream {
* @param {PipeOptions=} options * @param {PipeOptions=} options
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
pipeTo(destination, options = {}) { pipeTo(destination, options = { __proto__: null }) {
try { try {
webidl.assertBranded(this, ReadableStreamPrototype); webidl.assertBranded(this, ReadableStreamPrototype);
const prefix = "Failed to execute 'pipeTo' on 'ReadableStream'"; const prefix = "Failed to execute 'pipeTo' on 'ReadableStream'";
@ -5567,7 +5567,7 @@ class ReadableStreamBYOBReader {
* @param {ReadableStreamBYOBReaderReadOptions} options * @param {ReadableStreamBYOBReaderReadOptions} options
* @returns {Promise<ReadableStreamBYOBReadResult>} * @returns {Promise<ReadableStreamBYOBReadResult>}
*/ */
read(view, options = {}) { read(view, options = { __proto__: null }) {
try { try {
webidl.assertBranded(this, ReadableStreamBYOBReaderPrototype); webidl.assertBranded(this, ReadableStreamBYOBReaderPrototype);
const prefix = "Failed to execute 'read' on 'ReadableStreamBYOBReader'"; const prefix = "Failed to execute 'read' on 'ReadableStreamBYOBReader'";
@ -6151,8 +6151,8 @@ class TransformStream {
*/ */
constructor( constructor(
transformer = undefined, transformer = undefined,
writableStrategy = {}, writableStrategy = { __proto__: null },
readableStrategy = {}, readableStrategy = { __proto__: null },
) { ) {
const prefix = "Failed to construct 'TransformStream'"; const prefix = "Failed to construct 'TransformStream'";
if (transformer !== undefined) { if (transformer !== undefined) {

View file

@ -63,7 +63,7 @@ class TextDecoder {
* @param {string} label * @param {string} label
* @param {TextDecoderOptions} options * @param {TextDecoderOptions} options
*/ */
constructor(label = "utf-8", options = {}) { constructor(label = "utf-8", options = { __proto__: null }) {
const prefix = "Failed to construct 'TextDecoder'"; const prefix = "Failed to construct 'TextDecoder'";
label = webidl.converters.DOMString(label, prefix, "Argument 1"); label = webidl.converters.DOMString(label, prefix, "Argument 1");
options = webidl.converters.TextDecoderOptions( options = webidl.converters.TextDecoderOptions(
@ -288,7 +288,7 @@ class TextDecoderStream {
* @param {string} label * @param {string} label
* @param {TextDecoderOptions} options * @param {TextDecoderOptions} options
*/ */
constructor(label = "utf-8", options = {}) { constructor(label = "utf-8", options = { __proto__: null }) {
const prefix = "Failed to construct 'TextDecoderStream'"; const prefix = "Failed to construct 'TextDecoderStream'";
label = webidl.converters.DOMString(label, prefix, "Argument 1"); label = webidl.converters.DOMString(label, prefix, "Argument 1");
options = webidl.converters.TextDecoderOptions( options = webidl.converters.TextDecoderOptions(

View file

@ -223,7 +223,7 @@ class Blob {
* @param {BlobPart[]} blobParts * @param {BlobPart[]} blobParts
* @param {BlobPropertyBag} options * @param {BlobPropertyBag} options
*/ */
constructor(blobParts = [], options = {}) { constructor(blobParts = [], options = { __proto__: null }) {
const prefix = "Failed to construct 'Blob'"; const prefix = "Failed to construct 'Blob'";
blobParts = webidl.converters["sequence<BlobPart>"]( blobParts = webidl.converters["sequence<BlobPart>"](
blobParts, blobParts,
@ -500,7 +500,7 @@ class File extends Blob {
* @param {string} fileName * @param {string} fileName
* @param {FilePropertyBag} options * @param {FilePropertyBag} options
*/ */
constructor(fileBits, fileName, options = {}) { constructor(fileBits, fileName, options = { __proto__: null }) {
const prefix = "Failed to construct 'File'"; const prefix = "Failed to construct 'File'";
webidl.requiredArguments(arguments.length, 2, prefix); webidl.requiredArguments(arguments.length, 2, prefix);

View file

@ -150,7 +150,7 @@ class MessagePort extends EventTarget {
* @param {any} message * @param {any} message
* @param {object[] | StructuredSerializeOptions} transferOrOptions * @param {object[] | StructuredSerializeOptions} transferOrOptions
*/ */
postMessage(message, transferOrOptions = {}) { postMessage(message, transferOrOptions = { __proto__: null }) {
webidl.assertBranded(this, MessagePortPrototype); webidl.assertBranded(this, MessagePortPrototype);
const prefix = "Failed to execute 'postMessage' on 'MessagePort'"; const prefix = "Failed to execute 'postMessage' on 'MessagePort'";
webidl.requiredArguments(arguments.length, 1, prefix); webidl.requiredArguments(arguments.length, 1, prefix);

View file

@ -234,7 +234,7 @@ class PerformanceMark extends PerformanceEntry {
constructor( constructor(
name, name,
options = {}, options = { __proto__: null },
) { ) {
const prefix = "Failed to construct 'PerformanceMark'"; const prefix = "Failed to construct 'PerformanceMark'";
webidl.requiredArguments(arguments.length, 1, prefix); webidl.requiredArguments(arguments.length, 1, prefix);
@ -441,7 +441,7 @@ class Performance extends EventTarget {
mark( mark(
markName, markName,
markOptions = {}, markOptions = { __proto__: null },
) { ) {
webidl.assertBranded(this, PerformancePrototype); webidl.assertBranded(this, PerformancePrototype);
const prefix = "Failed to execute 'mark' on 'Performance'"; const prefix = "Failed to execute 'mark' on 'Performance'";
@ -466,7 +466,7 @@ class Performance extends EventTarget {
measure( measure(
measureName, measureName,
startOrMeasureOptions = {}, startOrMeasureOptions = { __proto__: null },
endMark = undefined, endMark = undefined,
) { ) {
webidl.assertBranded(this, PerformancePrototype); webidl.assertBranded(this, PerformancePrototype);

View file

@ -358,7 +358,7 @@ class GPU {
* @param {GPURequestAdapterOptions} options * @param {GPURequestAdapterOptions} options
*/ */
// deno-lint-ignore require-await // deno-lint-ignore require-await
async requestAdapter(options = {}) { async requestAdapter(options = { __proto__: null }) {
webidl.assertBranded(this, GPUPrototype); webidl.assertBranded(this, GPUPrototype);
options = webidl.converters.GPURequestAdapterOptions( options = webidl.converters.GPURequestAdapterOptions(
options, options,
@ -449,7 +449,7 @@ class GPUAdapter {
* @returns {Promise<GPUDevice>} * @returns {Promise<GPUDevice>}
*/ */
// deno-lint-ignore require-await // deno-lint-ignore require-await
async requestDevice(descriptor = {}) { async requestDevice(descriptor = { __proto__: null }) {
webidl.assertBranded(this, GPUAdapterPrototype); webidl.assertBranded(this, GPUAdapterPrototype);
const prefix = "Failed to execute 'requestDevice' on 'GPUAdapter'"; const prefix = "Failed to execute 'requestDevice' on 'GPUAdapter'";
descriptor = webidl.converters.GPUDeviceDescriptor( descriptor = webidl.converters.GPUDeviceDescriptor(
@ -1174,7 +1174,7 @@ class GPUDevice extends EventTarget {
* @param {GPUSamplerDescriptor} descriptor * @param {GPUSamplerDescriptor} descriptor
* @returns {GPUSampler} * @returns {GPUSampler}
*/ */
createSampler(descriptor = {}) { createSampler(descriptor = { __proto__: null }) {
webidl.assertBranded(this, GPUDevicePrototype); webidl.assertBranded(this, GPUDevicePrototype);
const prefix = "Failed to execute 'createSampler' on 'GPUDevice'"; const prefix = "Failed to execute 'createSampler' on 'GPUDevice'";
descriptor = webidl.converters.GPUSamplerDescriptor( descriptor = webidl.converters.GPUSamplerDescriptor(
@ -1687,7 +1687,7 @@ class GPUDevice extends EventTarget {
* @param {GPUCommandEncoderDescriptor} descriptor * @param {GPUCommandEncoderDescriptor} descriptor
* @returns {GPUCommandEncoder} * @returns {GPUCommandEncoder}
*/ */
createCommandEncoder(descriptor = {}) { createCommandEncoder(descriptor = { __proto__: null }) {
webidl.assertBranded(this, GPUDevicePrototype); webidl.assertBranded(this, GPUDevicePrototype);
const prefix = "Failed to execute 'createCommandEncoder' on 'GPUDevice'"; const prefix = "Failed to execute 'createCommandEncoder' on 'GPUDevice'";
descriptor = webidl.converters.GPUCommandEncoderDescriptor( descriptor = webidl.converters.GPUCommandEncoderDescriptor(
@ -1842,7 +1842,7 @@ defineEventHandler(GPUDevice.prototype, "uncapturederror");
class GPUPipelineError extends DOMException { class GPUPipelineError extends DOMException {
#reason; #reason;
constructor(message = "", options = {}) { constructor(message = "", options = { __proto__: null }) {
const prefix = "Failed to construct 'GPUPipelineError'"; const prefix = "Failed to construct 'GPUPipelineError'";
message = webidl.converters.DOMString(message, prefix, "Argument 1"); message = webidl.converters.DOMString(message, prefix, "Argument 1");
options = webidl.converters.GPUPipelineErrorInit( options = webidl.converters.GPUPipelineErrorInit(
@ -2499,7 +2499,7 @@ class GPUTexture {
/** /**
* @param {GPUTextureViewDescriptor} descriptor * @param {GPUTextureViewDescriptor} descriptor
*/ */
createView(descriptor = {}) { createView(descriptor = { __proto__: null }) {
webidl.assertBranded(this, GPUTexturePrototype); webidl.assertBranded(this, GPUTexturePrototype);
const prefix = "Failed to execute 'createView' on 'GPUTexture'"; const prefix = "Failed to execute 'createView' on 'GPUTexture'";
webidl.requiredArguments(arguments.length, 0, prefix); webidl.requiredArguments(arguments.length, 0, prefix);
@ -3306,7 +3306,7 @@ class GPUCommandEncoder {
/** /**
* @param {GPUComputePassDescriptor} descriptor * @param {GPUComputePassDescriptor} descriptor
*/ */
beginComputePass(descriptor = {}) { beginComputePass(descriptor = { __proto__: null }) {
webidl.assertBranded(this, GPUCommandEncoderPrototype); webidl.assertBranded(this, GPUCommandEncoderPrototype);
const prefix = const prefix =
"Failed to execute 'beginComputePass' on 'GPUCommandEncoder'"; "Failed to execute 'beginComputePass' on 'GPUCommandEncoder'";
@ -3757,7 +3757,7 @@ class GPUCommandEncoder {
* @param {GPUCommandBufferDescriptor} descriptor * @param {GPUCommandBufferDescriptor} descriptor
* @returns {GPUCommandBuffer} * @returns {GPUCommandBuffer}
*/ */
finish(descriptor = {}) { finish(descriptor = { __proto__: null }) {
webidl.assertBranded(this, GPUCommandEncoderPrototype); webidl.assertBranded(this, GPUCommandEncoderPrototype);
const prefix = "Failed to execute 'finish' on 'GPUCommandEncoder'"; const prefix = "Failed to execute 'finish' on 'GPUCommandEncoder'";
descriptor = webidl.converters.GPUCommandBufferDescriptor( descriptor = webidl.converters.GPUCommandBufferDescriptor(
@ -4774,7 +4774,7 @@ class GPURenderBundleEncoder {
/** /**
* @param {GPURenderBundleDescriptor} descriptor * @param {GPURenderBundleDescriptor} descriptor
*/ */
finish(descriptor = {}) { finish(descriptor = { __proto__: null }) {
webidl.assertBranded(this, GPURenderBundleEncoderPrototype); webidl.assertBranded(this, GPURenderBundleEncoderPrototype);
const prefix = "Failed to execute 'finish' on 'GPURenderBundleEncoder'"; const prefix = "Failed to execute 'finish' on 'GPURenderBundleEncoder'";
descriptor = webidl.converters.GPURenderBundleDescriptor( descriptor = webidl.converters.GPURenderBundleDescriptor(

View file

@ -192,7 +192,12 @@ function createIntegerConversion(bitLength, typeOpts) {
const twoToTheBitLength = MathPow(2, bitLength); const twoToTheBitLength = MathPow(2, bitLength);
const twoToOneLessThanTheBitLength = MathPow(2, bitLength - 1); const twoToOneLessThanTheBitLength = MathPow(2, bitLength - 1);
return (V, prefix = undefined, context = undefined, opts = {}) => { return (
V,
prefix = undefined,
context = undefined,
opts = { __proto__: null },
) => {
let x = toNumber(V); let x = toNumber(V);
x = censorNegativeZero(x); x = censorNegativeZero(x);
@ -251,7 +256,12 @@ function createLongLongConversion(bitLength, { unsigned }) {
const lowerBound = unsigned ? 0 : NumberMIN_SAFE_INTEGER; const lowerBound = unsigned ? 0 : NumberMIN_SAFE_INTEGER;
const asBigIntN = unsigned ? BigIntAsUintN : BigIntAsIntN; const asBigIntN = unsigned ? BigIntAsUintN : BigIntAsIntN;
return (V, prefix = undefined, context = undefined, opts = {}) => { return (
V,
prefix = undefined,
context = undefined,
opts = { __proto__: null },
) => {
let x = toNumber(V); let x = toNumber(V);
x = censorNegativeZero(x); x = censorNegativeZero(x);
@ -386,7 +396,12 @@ converters["unrestricted double"] = (V, _prefix, _context, _opts) => {
return x; return x;
}; };
converters.DOMString = function (V, prefix, context, opts = {}) { converters.DOMString = function (
V,
prefix,
context,
opts = { __proto__: null },
) {
if (typeof V === "string") { if (typeof V === "string") {
return V; return V;
} else if (V === null && opts.treatNullAsEmptyString) { } else if (V === null && opts.treatNullAsEmptyString) {
@ -464,7 +479,7 @@ converters.ArrayBuffer = (
V, V,
prefix = undefined, prefix = undefined,
context = undefined, context = undefined,
opts = {}, opts = { __proto__: null },
) => { ) => {
if (!isArrayBuffer(V)) { if (!isArrayBuffer(V)) {
if (opts.allowShared && !isSharedArrayBuffer(V)) { if (opts.allowShared && !isSharedArrayBuffer(V)) {
@ -490,7 +505,7 @@ converters.DataView = (
V, V,
prefix = undefined, prefix = undefined,
context = undefined, context = undefined,
opts = {}, opts = { __proto__: null },
) => { ) => {
if (!isDataView(V)) { if (!isDataView(V)) {
throw makeException( throw makeException(
@ -539,7 +554,7 @@ ArrayPrototypeForEach(
V, V,
prefix = undefined, prefix = undefined,
context = undefined, context = undefined,
opts = {}, opts = { __proto__: null },
) => { ) => {
if (TypedArrayPrototypeGetSymbolToStringTag(V) !== name) { if (TypedArrayPrototypeGetSymbolToStringTag(V) !== name) {
throw makeException( throw makeException(
@ -572,7 +587,7 @@ converters.ArrayBufferView = (
V, V,
prefix = undefined, prefix = undefined,
context = undefined, context = undefined,
opts = {}, opts = { __proto__: null },
) => { ) => {
if (!ArrayBufferIsView(V)) { if (!ArrayBufferIsView(V)) {
throw makeException( throw makeException(
@ -604,7 +619,7 @@ converters.BufferSource = (
V, V,
prefix = undefined, prefix = undefined,
context = undefined, context = undefined,
opts = {}, opts = { __proto__: null },
) => { ) => {
if (ArrayBufferIsView(V)) { if (ArrayBufferIsView(V)) {
let buffer; let buffer;
@ -722,7 +737,7 @@ function createDictionaryConverter(name, ...dictionaries) {
return a.key < b.key ? -1 : 1; return a.key < b.key ? -1 : 1;
}); });
const defaultValues = {}; const defaultValues = { __proto__: null };
for (let i = 0; i < allMembers.length; ++i) { for (let i = 0; i < allMembers.length; ++i) {
const member = allMembers[i]; const member = allMembers[i];
if (ReflectHas(member, "defaultValue")) { if (ReflectHas(member, "defaultValue")) {
@ -747,7 +762,12 @@ function createDictionaryConverter(name, ...dictionaries) {
} }
} }
return function (V, prefix = undefined, context = undefined, opts = {}) { return function (
V,
prefix = undefined,
context = undefined,
opts = { __proto__: null },
) {
const typeV = type(V); const typeV = type(V);
switch (typeV) { switch (typeV) {
case "Undefined": case "Undefined":
@ -812,7 +832,12 @@ function createDictionaryConverter(name, ...dictionaries) {
function createEnumConverter(name, values) { function createEnumConverter(name, values) {
const E = new SafeSet(values); const E = new SafeSet(values);
return function (V, prefix = undefined, _context = undefined, _opts = {}) { return function (
V,
prefix = undefined,
_context = undefined,
_opts = { __proto__: null },
) {
const S = String(V); const S = String(V);
if (!E.has(S)) { if (!E.has(S)) {
@ -828,7 +853,12 @@ function createEnumConverter(name, values) {
} }
function createNullableConverter(converter) { function createNullableConverter(converter) {
return (V, prefix = undefined, context = undefined, opts = {}) => { return (
V,
prefix = undefined,
context = undefined,
opts = { __proto__: null },
) => {
// FIXME: If Type(V) is not Object, and the conversion to an IDL value is // FIXME: If Type(V) is not Object, and the conversion to an IDL value is
// being performed due to V being assigned to an attribute whose type is a // being performed due to V being assigned to an attribute whose type is a
// nullable callback function that is annotated with // nullable callback function that is annotated with
@ -842,7 +872,12 @@ function createNullableConverter(converter) {
// https://heycam.github.io/webidl/#es-sequence // https://heycam.github.io/webidl/#es-sequence
function createSequenceConverter(converter) { function createSequenceConverter(converter) {
return function (V, prefix = undefined, context = undefined, opts = {}) { return function (
V,
prefix = undefined,
context = undefined,
opts = { __proto__: null },
) {
if (type(V) !== "Object") { if (type(V) !== "Object") {
throw makeException( throw makeException(
TypeError, TypeError,
@ -894,7 +929,7 @@ function createRecordConverter(keyConverter, valueConverter) {
context, context,
); );
} }
const result = {}; const result = { __proto__: null };
// Fast path for common case (not a Proxy) // Fast path for common case (not a Proxy)
if (!core.isProxy(V)) { if (!core.isProxy(V)) {
for (const key in V) { for (const key in V) {

View file

@ -474,7 +474,7 @@ class WebSocketError extends DOMException {
#closeCode; #closeCode;
#reason; #reason;
constructor(message = "", init = {}) { constructor(message = "", init = { __proto__: null }) {
super(message, "WebSocketError"); super(message, "WebSocketError");
this[webidl.brand] = webidl.brand; this[webidl.brand] = webidl.brand;

View file

@ -268,7 +268,7 @@ const permissions = new Permissions(illegalConstructorKey);
/** Converts all file URLs in FS allowlists to paths. */ /** Converts all file URLs in FS allowlists to paths. */
function serializePermissions(permissions) { function serializePermissions(permissions) {
if (typeof permissions == "object" && permissions != null) { if (typeof permissions == "object" && permissions != null) {
const serializedPermissions = {}; const serializedPermissions = { __proto__: null };
for ( for (
const key of new SafeArrayIterator(["read", "write", "run", "ffi"]) const key of new SafeArrayIterator(["read", "write", "run", "ffi"])
) { ) {

View file

@ -91,7 +91,7 @@ class Worker extends EventTarget {
// still be messages left to receive. // still be messages left to receive.
#status = "RUNNING"; #status = "RUNNING";
constructor(specifier, options = {}) { constructor(specifier, options = { __proto__: null }) {
super(); super();
specifier = String(specifier); specifier = String(specifier);
const { const {
@ -254,7 +254,7 @@ class Worker extends EventTarget {
} }
}; };
postMessage(message, transferOrOptions = {}) { postMessage(message, transferOrOptions = { __proto__: null }) {
const prefix = "Failed to execute 'postMessage' on 'MessagePort'"; const prefix = "Failed to execute 'postMessage' on 'MessagePort'";
webidl.requiredArguments(arguments.length, 1, prefix); webidl.requiredArguments(arguments.length, 1, prefix);
message = webidl.converters.any(message); message = webidl.converters.any(message);

View file

@ -134,7 +134,7 @@ function run({
cmd, cmd,
cwd = undefined, cwd = undefined,
clearEnv = false, clearEnv = false,
env = {}, env = { __proto__: null },
gid = undefined, gid = undefined,
uid = undefined, uid = undefined,
stdout = "inherit", stdout = "inherit",
@ -172,7 +172,7 @@ function spawnChildInner(opFn, command, apiName, {
args = [], args = [],
cwd = undefined, cwd = undefined,
clearEnv = false, clearEnv = false,
env = {}, env = { __proto__: null },
uid = undefined, uid = undefined,
gid = undefined, gid = undefined,
stdin = "null", stdin = "null",
@ -181,7 +181,7 @@ function spawnChildInner(opFn, command, apiName, {
signal = undefined, signal = undefined,
windowsRawArguments = false, windowsRawArguments = false,
ipc = -1, ipc = -1,
} = {}) { } = { __proto__: null }) {
const child = opFn({ const child = opFn({
cmd: pathFromURL(command), cmd: pathFromURL(command),
args: ArrayPrototypeMap(args, String), args: ArrayPrototypeMap(args, String),
@ -202,7 +202,7 @@ function spawnChildInner(opFn, command, apiName, {
}); });
} }
function spawnChild(command, options = {}) { function spawnChild(command, options = { __proto__: null }) {
return spawnChildInner( return spawnChildInner(
op_spawn_child, op_spawn_child,
command, command,
@ -392,14 +392,14 @@ function spawnSync(command, {
args = [], args = [],
cwd = undefined, cwd = undefined,
clearEnv = false, clearEnv = false,
env = {}, env = { __proto__: null },
uid = undefined, uid = undefined,
gid = undefined, gid = undefined,
stdin = "null", stdin = "null",
stdout = "piped", stdout = "piped",
stderr = "piped", stderr = "piped",
windowsRawArguments = false, windowsRawArguments = false,
} = {}) { } = { __proto__: null }) {
if (stdin === "piped") { if (stdin === "piped") {
throw new TypeError( throw new TypeError(
"Piped stdin is not supported for this function, use 'Deno.Command().spawn()' instead", "Piped stdin is not supported for this function, use 'Deno.Command().spawn()' instead",

View file

@ -26,7 +26,7 @@ function unbindSignal(rid) {
// Stores signal listeners and resource data. This has type of // Stores signal listeners and resource data. This has type of
// `Record<string, { rid: number | undefined, listeners: Set<() => void> }` // `Record<string, { rid: number | undefined, listeners: Set<() => void> }`
const signalData = {}; const signalData = { __proto__: null };
/** Gets the signal handlers and resource data of the given signal */ /** Gets the signal handlers and resource data of the given signal */
function getSignalData(signo) { function getSignalData(signo) {

View file

@ -264,9 +264,9 @@ const unstableIds = {
workerOptions: 11, workerOptions: 11,
}; };
const denoNsUnstableById = {}; const denoNsUnstableById = { __proto__: null };
// denoNsUnstableById[unstableIds.broadcastChannel] = {} // denoNsUnstableById[unstableIds.broadcastChannel] = { __proto__: null }
denoNsUnstableById[unstableIds.cron] = { denoNsUnstableById[unstableIds.cron] = {
cron: cron.cron, cron: cron.cron,
@ -308,13 +308,13 @@ denoNsUnstableById[unstableIds.net] = {
), ),
}; };
// denoNsUnstableById[unstableIds.unsafeProto] = {} // denoNsUnstableById[unstableIds.unsafeProto] = { __proto__: null }
denoNsUnstableById[unstableIds.webgpu] = { denoNsUnstableById[unstableIds.webgpu] = {
UnsafeWindowSurface: webgpuSurface.UnsafeWindowSurface, UnsafeWindowSurface: webgpuSurface.UnsafeWindowSurface,
}; };
// denoNsUnstableById[unstableIds.workerOptions] = {} // denoNsUnstableById[unstableIds.workerOptions] = { __proto__: null }
// when editing this list, also update unstableDenoProps in cli/tsc/99_main_compiler.js // when editing this list, also update unstableDenoProps in cli/tsc/99_main_compiler.js
const denoNsUnstable = { const denoNsUnstable = {

View file

@ -145,7 +145,7 @@ const windowOrWorkerGlobalScope = {
[webidl.brand]: core.propNonEnumerable(webidl.brand), [webidl.brand]: core.propNonEnumerable(webidl.brand),
}; };
const unstableForWindowOrWorkerGlobalScope = {}; const unstableForWindowOrWorkerGlobalScope = { __proto__: null };
unstableForWindowOrWorkerGlobalScope[unstableIds.broadcastChannel] = { unstableForWindowOrWorkerGlobalScope[unstableIds.broadcastChannel] = {
BroadcastChannel: core.propNonEnumerable(broadcastChannel.BroadcastChannel), BroadcastChannel: core.propNonEnumerable(broadcastChannel.BroadcastChannel),
}; };

View file

@ -252,7 +252,7 @@ function workerClose() {
op_worker_close(); op_worker_close();
} }
function postMessage(message, transferOrOptions = {}) { function postMessage(message, transferOrOptions = { __proto__: null }) {
const prefix = const prefix =
"Failed to execute 'postMessage' on 'DedicatedWorkerGlobalScope'"; "Failed to execute 'postMessage' on 'DedicatedWorkerGlobalScope'";
webidl.requiredArguments(arguments.length, 1, prefix); webidl.requiredArguments(arguments.length, 1, prefix);

View file

@ -141,3 +141,17 @@ Deno.test(function inspectEvent() {
`Event {\n bubbles: false,\n cancelable: false,`, `Event {\n bubbles: false,\n cancelable: false,`,
); );
}); });
Deno.test("default argument is null prototype", () => {
const event = new Event("test");
assertEquals(event.bubbles, false);
// @ts-ignore this is on purpose to check if overriding prototype
// has effect on `Event.
Object.prototype.bubbles = true;
const event2 = new Event("test");
assertEquals(event2.bubbles, false);
// @ts-ignore this is done on purpose
delete Object.prototype.bubbles;
});