mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 15:24:46 -05:00
refactor(core): validate promise id in refOp (#13905)
This commit is contained in:
parent
f9b4d262b3
commit
b198bfd795
5 changed files with 59 additions and 20 deletions
10
cli/tests/unit/ref_unref_test.ts
Normal file
10
cli/tests/unit/ref_unref_test.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { assertNotEquals, execCode } from "./test_util.ts";
|
||||
|
||||
Deno.test("[unrefOp] unref'ing invalid ops does not have effects", async () => {
|
||||
const [statusCode, _] = await execCode(`
|
||||
Deno.core.unrefOp(-1);
|
||||
setTimeout(() => { throw new Error() }, 10)
|
||||
`);
|
||||
// Invalid unrefOp call doesn't affect exit condition of event loop
|
||||
assertNotEquals(statusCode, 0);
|
||||
});
|
|
@ -27,3 +27,21 @@ export function pathToAbsoluteFileUrl(path: string): URL {
|
|||
|
||||
return new URL(`file://${Deno.build.os === "windows" ? "/" : ""}${path}`);
|
||||
}
|
||||
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
export async function execCode(code: string) {
|
||||
const p = Deno.run({
|
||||
cmd: [
|
||||
Deno.execPath(),
|
||||
"eval",
|
||||
"--unstable",
|
||||
"--no-check",
|
||||
code,
|
||||
],
|
||||
stdout: "piped",
|
||||
});
|
||||
const [status, output] = await Promise.all([p.status(), p.output()]);
|
||||
p.close();
|
||||
return [status.code, decoder.decode(output)];
|
||||
}
|
||||
|
|
|
@ -6,11 +6,10 @@ import {
|
|||
Deferred,
|
||||
deferred,
|
||||
delay,
|
||||
execCode,
|
||||
unreachable,
|
||||
} from "./test_util.ts";
|
||||
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
Deno.test(async function functionParameterBindingSuccess() {
|
||||
const promise = deferred();
|
||||
let count = 0;
|
||||
|
@ -578,21 +577,6 @@ Deno.test(
|
|||
},
|
||||
);
|
||||
|
||||
async function execCode(code: string) {
|
||||
const p = Deno.run({
|
||||
cmd: [
|
||||
Deno.execPath(),
|
||||
"eval",
|
||||
"--unstable",
|
||||
code,
|
||||
],
|
||||
stdout: "piped",
|
||||
});
|
||||
const [status, output] = await Promise.all([p.status(), p.output()]);
|
||||
p.close();
|
||||
return [status.code, decoder.decode(output)];
|
||||
}
|
||||
|
||||
Deno.test({
|
||||
name: "unrefTimer",
|
||||
permissions: { run: true },
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
} = window.__bootstrap.primordials;
|
||||
|
||||
// Available on start due to bindings.
|
||||
const { opcallSync, opcallAsync } = window.Deno.core;
|
||||
const { opcallSync, opcallAsync, refOp_, unrefOp_ } = window.Deno.core;
|
||||
|
||||
let opsCache = {};
|
||||
const errorMap = {};
|
||||
|
@ -99,6 +99,17 @@
|
|||
return promise;
|
||||
}
|
||||
|
||||
function hasPromise(promiseId) {
|
||||
// Check if out of ring bounds, fallback to map
|
||||
const outOfBounds = promiseId < nextPromiseId - RING_SIZE;
|
||||
if (outOfBounds) {
|
||||
return MapPrototypeHas(promiseMap, promiseId);
|
||||
}
|
||||
// Otherwise check it in ring
|
||||
const idx = promiseId % RING_SIZE;
|
||||
return promiseRing[idx] != NO_PROMISE;
|
||||
}
|
||||
|
||||
function ops() {
|
||||
return opsCache;
|
||||
}
|
||||
|
@ -172,6 +183,20 @@
|
|||
return unwrapOpResult(opcallSync(opsCache[opName], arg1, arg2));
|
||||
}
|
||||
|
||||
function refOp(promiseId) {
|
||||
if (!hasPromise(promiseId)) {
|
||||
return;
|
||||
}
|
||||
refOp_(promiseId);
|
||||
}
|
||||
|
||||
function unrefOp(promiseId) {
|
||||
if (!hasPromise(promiseId)) {
|
||||
return;
|
||||
}
|
||||
unrefOp_(promiseId);
|
||||
}
|
||||
|
||||
function resources() {
|
||||
return ObjectFromEntries(opSync("op_resources"));
|
||||
}
|
||||
|
@ -252,6 +277,8 @@
|
|||
enableOpCallTracing,
|
||||
isOpCallTracingEnabled,
|
||||
opCallTraces,
|
||||
refOp,
|
||||
unrefOp,
|
||||
});
|
||||
|
||||
ObjectAssign(globalThis.__bootstrap, { core });
|
||||
|
|
|
@ -173,8 +173,8 @@ pub fn initialize_context<'s>(
|
|||
// Bind functions to Deno.core.*
|
||||
set_func(scope, core_val, "opcallSync", opcall_sync);
|
||||
set_func(scope, core_val, "opcallAsync", opcall_async);
|
||||
set_func(scope, core_val, "refOp", ref_op);
|
||||
set_func(scope, core_val, "unrefOp", unref_op);
|
||||
set_func(scope, core_val, "refOp_", ref_op);
|
||||
set_func(scope, core_val, "unrefOp_", unref_op);
|
||||
set_func(
|
||||
scope,
|
||||
core_val,
|
||||
|
|
Loading…
Reference in a new issue