summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/js/dispatch_json_test.ts20
-rw-r--r--cli/js/dispatch_minimal_test.ts42
-rw-r--r--cli/ops/dispatch_json.rs8
-rw-r--r--cli/ops/dispatch_minimal.rs17
4 files changed, 84 insertions, 3 deletions
diff --git a/cli/js/dispatch_json_test.ts b/cli/js/dispatch_json_test.ts
index 11dadc620..07549d295 100644
--- a/cli/js/dispatch_json_test.ts
+++ b/cli/js/dispatch_json_test.ts
@@ -1,4 +1,11 @@
-import { testPerm, assertMatch, unreachable } from "./test_util.ts";
+import {
+ test,
+ testPerm,
+ assert,
+ assertEquals,
+ assertMatch,
+ unreachable
+} from "./test_util.ts";
const openErrorStackPattern = new RegExp(
`^.*
@@ -17,3 +24,14 @@ testPerm({ read: true }, async function sendAsyncStackTrace(): Promise<void> {
}
);
});
+
+test(async function malformedJsonControlBuffer(): Promise<void> {
+ // @ts-ignore
+ const res = Deno.core.send(10, new Uint8Array([1, 2, 3, 4, 5]));
+ const resText = new TextDecoder().decode(res);
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const resJson = JSON.parse(resText) as any;
+ assert(!resJson.ok);
+ assert(resJson.err);
+ assertEquals(resJson.err!.kind, Deno.ErrorKind.InvalidInput);
+});
diff --git a/cli/js/dispatch_minimal_test.ts b/cli/js/dispatch_minimal_test.ts
new file mode 100644
index 000000000..a08252171
--- /dev/null
+++ b/cli/js/dispatch_minimal_test.ts
@@ -0,0 +1,42 @@
+import {
+ test,
+ assert,
+ assertEquals,
+ assertMatch,
+ unreachable
+} from "./test_util.ts";
+
+const readErrorStackPattern = new RegExp(
+ `^.*
+ at unwrapResponse \\(.*dispatch_minimal\\.ts:.*\\)
+ at Object.sendAsync \\(.*dispatch_minimal\\.ts:.*\\)
+ at async Object\\.open \\(.*files\\.ts:.*\\).*$`,
+ "ms"
+);
+
+test(async function sendAsyncStackTrace(): Promise<void> {
+ const buf = new Uint8Array(10);
+ await Deno.read(10, "nonexistent.txt", buf)
+ .then(unreachable)
+ .catch(
+ (error): void => {
+ assertMatch(error.stack, readErrorStackPattern);
+ }
+ );
+});
+test(async function malformedMinimalControlBuffer(): Promise<void> {
+ // @ts-ignore
+ const res = Deno.core.send(1, new Uint8Array([1, 2, 3, 4, 5]));
+ const header = res.slice(0, 12);
+ const buf32 = new Int32Array(
+ header.buffer,
+ header.byteOffset,
+ header.byteLength / 4
+ );
+ const arg = buf32[1];
+ const result = buf32[2];
+ const message = new TextDecoder().decode(res.slice(12));
+ assert(arg < 0);
+ assertEquals(result, Deno.ErrorKind.InvalidInput);
+ assertEquals(message, "Unparsable control buffer");
+});
diff --git a/cli/ops/dispatch_json.rs b/cli/ops/dispatch_json.rs
index 3a8faf2a8..5f1caac6f 100644
--- a/cli/ops/dispatch_json.rs
+++ b/cli/ops/dispatch_json.rs
@@ -48,7 +48,13 @@ where
D: Fn(Value, Option<PinnedBuf>) -> Result<JsonOp, ErrBox>,
{
move |control: &[u8], zero_copy: Option<PinnedBuf>| {
- let async_args: AsyncArgs = serde_json::from_slice(control).unwrap();
+ let async_args: AsyncArgs = match serde_json::from_slice(control) {
+ Ok(args) => args,
+ Err(e) => {
+ let buf = serialize_result(None, Err(ErrBox::from(e)));
+ return CoreOp::Sync(buf);
+ }
+ };
let promise_id = async_args.promise_id;
let is_sync = promise_id.is_none();
diff --git a/cli/ops/dispatch_minimal.rs b/cli/ops/dispatch_minimal.rs
index 6170890a3..c19521bf1 100644
--- a/cli/ops/dispatch_minimal.rs
+++ b/cli/ops/dispatch_minimal.rs
@@ -5,6 +5,7 @@
//! messages. The first i32 is used to determine if a message a flatbuffer
//! message or a "minimal" message.
use crate::deno_error::GetErrorKind;
+use crate::msg::ErrorKind;
use byteorder::{LittleEndian, WriteBytesExt};
use deno::Buf;
use deno::CoreOp;
@@ -115,7 +116,21 @@ pub fn minimal_op(
d: Dispatcher,
) -> impl Fn(&[u8], Option<PinnedBuf>) -> CoreOp {
move |control: &[u8], zero_copy: Option<PinnedBuf>| {
- let mut record = parse_min_record(control).unwrap();
+ let mut record = match parse_min_record(control) {
+ Some(r) => r,
+ None => {
+ let error_record = ErrorRecord {
+ promise_id: 0,
+ arg: -1,
+ error_code: ErrorKind::InvalidInput as i32,
+ error_message: "Unparsable control buffer"
+ .to_string()
+ .as_bytes()
+ .to_owned(),
+ };
+ return Op::Sync(error_record.into());
+ }
+ };
let is_sync = record.promise_id == 0;
let rid = record.arg;
let min_op = d(rid, zero_copy);