summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Kettmeir <crowlkats@toaxl.com>2024-11-04 09:17:21 -0800
committerGitHub <noreply@github.com>2024-11-04 09:17:21 -0800
commitfe9f0ee5934871175758857899fe64e56c397fd5 (patch)
treeee770a45366d1b054e7429cea2eff56b04532830
parentfb1d33a7111e45e9b414cfe922a5db5ee4daf3ea (diff)
refactor(runtime/permissions): use concrete error types (#26464)
-rw-r--r--Cargo.lock1
-rw-r--r--cli/args/flags.rs3
-rw-r--r--cli/args/flags_net.rs2
-rw-r--r--cli/npm/byonm.rs2
-rw-r--r--cli/npm/managed/resolvers/common.rs2
-rw-r--r--cli/tools/info.rs10
-rw-r--r--ext/fetch/lib.rs23
-rw-r--r--ext/ffi/call.rs14
-rw-r--r--ext/ffi/callback.rs6
-rw-r--r--ext/ffi/dlfcn.rs6
-rw-r--r--ext/ffi/lib.rs11
-rw-r--r--ext/ffi/repr.rs86
-rw-r--r--ext/fs/lib.rs50
-rw-r--r--ext/fs/ops.rs217
-rw-r--r--ext/kv/remote.rs13
-rw-r--r--ext/kv/sqlite.rs12
-rw-r--r--ext/napi/lib.rs15
-rw-r--r--ext/net/lib.rs17
-rw-r--r--ext/net/ops.rs36
-rw-r--r--ext/node/lib.rs34
-rw-r--r--ext/node/ops/fs.rs35
-rw-r--r--ext/node/ops/http.rs4
-rw-r--r--ext/node/ops/os/mod.rs14
-rw-r--r--ext/websocket/lib.rs18
-rw-r--r--runtime/errors.rs147
-rw-r--r--runtime/ops/fs_events.rs5
-rw-r--r--runtime/ops/os/mod.rs23
-rw-r--r--runtime/ops/permissions.rs43
-rw-r--r--runtime/ops/process.rs24
-rw-r--r--runtime/ops/worker_host.rs2
-rw-r--r--runtime/permissions.rs44
-rw-r--r--runtime/permissions/Cargo.toml1
-rw-r--r--runtime/permissions/lib.rs776
-rw-r--r--runtime/permissions/prompter.rs69
-rw-r--r--runtime/snapshot.rs64
35 files changed, 999 insertions, 830 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8c7b35ca9..a8a501716 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1972,6 +1972,7 @@ dependencies = [
"once_cell",
"percent-encoding",
"serde",
+ "thiserror",
"which 4.4.2",
"winapi",
]
diff --git a/cli/args/flags.rs b/cli/args/flags.rs
index 1a1213aac..eb7797174 100644
--- a/cli/args/flags.rs
+++ b/cli/args/flags.rs
@@ -3388,8 +3388,7 @@ fn permission_args(app: Command, requires: Option<&'static str>) -> Command {
.value_name("IP_OR_HOSTNAME")
.help("Allow network access. Optionally specify allowed IP addresses and host names, with ports as necessary")
.value_parser(flags_net::validator)
- .hide(true)
- ;
+ .hide(true);
if let Some(requires) = requires {
arg = arg.requires(requires)
}
diff --git a/cli/args/flags_net.rs b/cli/args/flags_net.rs
index 88ffcf0e4..abfcf2838 100644
--- a/cli/args/flags_net.rs
+++ b/cli/args/flags_net.rs
@@ -51,7 +51,7 @@ pub fn parse(paths: Vec<String>) -> clap::error::Result<Vec<String>> {
}
} else {
NetDescriptor::parse(&host_and_port).map_err(|e| {
- clap::Error::raw(clap::error::ErrorKind::InvalidValue, format!("{e:?}"))
+ clap::Error::raw(clap::error::ErrorKind::InvalidValue, e.to_string())
})?;
out.push(host_and_port)
}
diff --git a/cli/npm/byonm.rs b/cli/npm/byonm.rs
index 4535b07fc..45fa4cfd1 100644
--- a/cli/npm/byonm.rs
+++ b/cli/npm/byonm.rs
@@ -89,7 +89,7 @@ impl CliNpmResolver for CliByonmNpmResolver {
.components()
.any(|c| c.as_os_str().to_ascii_lowercase() == "node_modules")
{
- permissions.check_read_path(path)
+ permissions.check_read_path(path).map_err(Into::into)
} else {
Ok(Cow::Borrowed(path))
}
diff --git a/cli/npm/managed/resolvers/common.rs b/cli/npm/managed/resolvers/common.rs
index 590f8fb25..eee11c760 100644
--- a/cli/npm/managed/resolvers/common.rs
+++ b/cli/npm/managed/resolvers/common.rs
@@ -133,7 +133,7 @@ impl RegistryReadPermissionChecker {
}
}
- permissions.check_read_path(path)
+ permissions.check_read_path(path).map_err(Into::into)
}
}
diff --git a/cli/tools/info.rs b/cli/tools/info.rs
index b53485bd6..c2f5a8cb8 100644
--- a/cli/tools/info.rs
+++ b/cli/tools/info.rs
@@ -645,10 +645,12 @@ impl<'a> GraphDisplayContext<'a> {
let message = match err {
HttpsChecksumIntegrity(_) => "(checksum integrity error)",
Decode(_) => "(loading decode error)",
- Loader(err) => match deno_core::error::get_custom_error_class(err) {
- Some("NotCapable") => "(not capable, requires --allow-import)",
- _ => "(loading error)",
- },
+ Loader(err) => {
+ match deno_runtime::errors::get_error_class_name(err) {
+ Some("NotCapable") => "(not capable, requires --allow-import)",
+ _ => "(loading error)",
+ }
+ }
Jsr(_) => "(loading error)",
NodeUnknownBuiltinModule(_) => "(unknown node built-in error)",
Npm(_) => "(npm loading error)",
diff --git a/ext/fetch/lib.rs b/ext/fetch/lib.rs
index 4df8dc3d7..7ef26431c 100644
--- a/ext/fetch/lib.rs
+++ b/ext/fetch/lib.rs
@@ -39,6 +39,7 @@ use deno_core::OpState;
use deno_core::RcRef;
use deno_core::Resource;
use deno_core::ResourceId;
+use deno_permissions::PermissionCheckError;
use deno_tls::rustls::RootCertStore;
use deno_tls::Proxy;
use deno_tls::RootCertStoreProvider;
@@ -149,7 +150,7 @@ pub enum FetchError {
#[error(transparent)]
Resource(deno_core::error::AnyError),
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] PermissionCheckError),
#[error("NetworkError when attempting to fetch resource")]
NetworkError,
#[error("Fetching files only supports the GET method: received {0}")]
@@ -346,13 +347,13 @@ pub trait FetchPermissions {
&mut self,
url: &Url,
api_name: &str,
- ) -> Result<(), deno_core::error::AnyError>;
+ ) -> Result<(), PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_read<'a>(
&mut self,
p: &'a Path,
api_name: &str,
- ) -> Result<Cow<'a, Path>, deno_core::error::AnyError>;
+ ) -> Result<Cow<'a, Path>, PermissionCheckError>;
}
impl FetchPermissions for deno_permissions::PermissionsContainer {
@@ -361,7 +362,7 @@ impl FetchPermissions for deno_permissions::PermissionsContainer {
&mut self,
url: &Url,
api_name: &str,
- ) -> Result<(), deno_core::error::AnyError> {
+ ) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_net_url(self, url, api_name)
}
@@ -370,7 +371,7 @@ impl FetchPermissions for deno_permissions::PermissionsContainer {
&mut self,
path: &'a Path,
api_name: &str,
- ) -> Result<Cow<'a, Path>, deno_core::error::AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_read_path(
self,
path,
@@ -414,9 +415,7 @@ where
"file" => {
let path = url.to_file_path().map_err(|_| FetchError::NetworkError)?;
let permissions = state.borrow_mut::<FP>();
- let path = permissions
- .check_read(&path, "fetch()")
- .map_err(FetchError::Permission)?;
+ let path = permissions.check_read(&path, "fetch()")?;
let url = match path {
Cow::Owned(path) => Url::from_file_path(path).unwrap(),
Cow::Borrowed(_) => url,
@@ -442,9 +441,7 @@ where
}
"http" | "https" => {
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_net_url(&url, "fetch()")
- .map_err(FetchError::Resource)?;
+ permissions.check_net_url(&url, "fetch()")?;
let maybe_authority = extract_authority(&mut url);
let uri = url
@@ -863,9 +860,7 @@ where
if let Some(proxy) = args.proxy.clone() {
let permissions = state.borrow_mut::<FP>();
let url = Url::parse(&proxy.url)?;
- permissions
- .check_net_url(&url, "Deno.createHttpClient()")
- .map_err(FetchError::Permission)?;
+ permissions.check_net_url(&url, "Deno.createHttpClient()")?;
}
let options = state.borrow::<Options>();
diff --git a/ext/ffi/call.rs b/ext/ffi/call.rs
index ef61dc383..bbff0ee48 100644
--- a/ext/ffi/call.rs
+++ b/ext/ffi/call.rs
@@ -32,7 +32,9 @@ pub enum CallError {
#[error("Invalid FFI symbol name: '{0}'")]
InvalidSymbol(String),
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] deno_permissions::PermissionCheckError),
+ #[error(transparent)]
+ Resource(deno_core::error::AnyError),
#[error(transparent)]
Callback(#[from] super::CallbackError),
}
@@ -301,9 +303,7 @@ where
{
let mut state = state.borrow_mut();
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(CallError::Permission)?;
+ permissions.check_partial_no_path()?;
};
let symbol = PtrSymbol::new(pointer, &def)?;
@@ -347,7 +347,7 @@ pub fn op_ffi_call_nonblocking(
let resource = state
.resource_table
.get::<DynamicLibraryResource>(rid)
- .map_err(CallError::Permission)?;
+ .map_err(CallError::Resource)?;
let symbols = &resource.symbols;
*symbols
.get(&symbol)
@@ -401,9 +401,7 @@ where
{
let mut state = state.borrow_mut();
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(CallError::Permission)?;
+ permissions.check_partial_no_path()?;
};
let symbol = PtrSymbol::new(pointer, &def)?;
diff --git a/ext/ffi/callback.rs b/ext/ffi/callback.rs
index f33e0413a..29583c800 100644
--- a/ext/ffi/callback.rs
+++ b/ext/ffi/callback.rs
@@ -38,7 +38,7 @@ pub enum CallbackError {
#[error(transparent)]
Resource(deno_core::error::AnyError),
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] deno_permissions::PermissionCheckError),
#[error(transparent)]
Other(deno_core::error::AnyError),
}
@@ -572,9 +572,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(CallbackError::Permission)?;
+ permissions.check_partial_no_path()?;
let thread_id: u32 = LOCAL_THREAD_ID.with(|s| {
let value = *s.borrow();
diff --git a/ext/ffi/dlfcn.rs b/ext/ffi/dlfcn.rs
index 53bdcbc5c..55909468f 100644
--- a/ext/ffi/dlfcn.rs
+++ b/ext/ffi/dlfcn.rs
@@ -30,7 +30,7 @@ pub enum DlfcnError {
#[error(transparent)]
Dlopen(#[from] dlopen2::Error),
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] deno_permissions::PermissionCheckError),
#[error(transparent)]
Other(deno_core::error::AnyError),
}
@@ -133,9 +133,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- let path = permissions
- .check_partial_with_path(&args.path)
- .map_err(DlfcnError::Permission)?;
+ let path = permissions.check_partial_with_path(&args.path)?;
let lib = Library::open(&path).map_err(|e| {
dlopen2::Error::OpeningLibraryError(std::io::Error::new(
diff --git a/ext/ffi/lib.rs b/ext/ffi/lib.rs
index 237f8c3b0..73ec7757a 100644
--- a/ext/ffi/lib.rs
+++ b/ext/ffi/lib.rs
@@ -1,7 +1,5 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-use deno_core::error::AnyError;
-
use std::mem::size_of;
use std::os::raw::c_char;
use std::os::raw::c_short;
@@ -31,6 +29,7 @@ use symbol::Symbol;
pub use call::CallError;
pub use callback::CallbackError;
+use deno_permissions::PermissionCheckError;
pub use dlfcn::DlfcnError;
pub use ir::IRError;
pub use r#static::StaticError;
@@ -48,17 +47,17 @@ const _: () = {
pub const UNSTABLE_FEATURE_NAME: &str = "ffi";
pub trait FfiPermissions {
- fn check_partial_no_path(&mut self) -> Result<(), AnyError>;
+ fn check_partial_no_path(&mut self) -> Result<(), PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_partial_with_path(
&mut self,
path: &str,
- ) -> Result<PathBuf, AnyError>;
+ ) -> Result<PathBuf, PermissionCheckError>;
}
impl FfiPermissions for deno_permissions::PermissionsContainer {
#[inline(always)]
- fn check_partial_no_path(&mut self) -> Result<(), AnyError> {
+ fn check_partial_no_path(&mut self) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_ffi_partial_no_path(self)
}
@@ -66,7 +65,7 @@ impl FfiPermissions for deno_permissions::PermissionsContainer {
fn check_partial_with_path(
&mut self,
path: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_ffi_partial_with_path(
self, path,
)
diff --git a/ext/ffi/repr.rs b/ext/ffi/repr.rs
index 2f04f4feb..fd8a2c8e7 100644
--- a/ext/ffi/repr.rs
+++ b/ext/ffi/repr.rs
@@ -46,7 +46,7 @@ pub enum ReprError {
#[error("Invalid pointer pointer, pointer is null")]
InvalidPointer,
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] deno_permissions::PermissionCheckError),
}
#[op2(fast)]
@@ -58,9 +58,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
Ok(ptr_number as *mut c_void)
}
@@ -75,9 +73,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
Ok(a == b)
}
@@ -91,9 +87,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
Ok(buf as *mut c_void)
}
@@ -107,9 +101,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
let Some(buf) = buf.get_backing_store() else {
return Ok(0 as _);
@@ -130,9 +122,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidOffset);
@@ -162,9 +152,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
Ok(ptr as usize)
}
@@ -181,9 +169,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidArrayBuffer);
@@ -215,9 +201,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if src.is_null() {
Err(ReprError::InvalidArrayBuffer)
@@ -246,9 +230,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidCString);
@@ -272,9 +254,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidBool);
@@ -294,9 +274,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidU8);
@@ -318,9 +296,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidI8);
@@ -342,9 +318,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidU16);
@@ -366,9 +340,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidI16);
@@ -390,9 +362,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidU32);
@@ -412,9 +382,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidI32);
@@ -437,9 +405,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidU64);
@@ -465,9 +431,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidI64);
@@ -490,9 +454,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidF32);
@@ -512,9 +474,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidF64);
@@ -534,9 +494,7 @@ where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
- permissions
- .check_partial_no_path()
- .map_err(ReprError::Permission)?;
+ permissions.check_partial_no_path()?;
if ptr.is_null() {
return Err(ReprError::InvalidPointer);
diff --git a/ext/fs/lib.rs b/ext/fs/lib.rs
index cd2baf22a..dd852e6be 100644
--- a/ext/fs/lib.rs
+++ b/ext/fs/lib.rs
@@ -22,8 +22,8 @@ pub use crate::sync::MaybeSync;
use crate::ops::*;
-use deno_core::error::AnyError;
use deno_io::fs::FsError;
+use deno_permissions::PermissionCheckError;
use std::borrow::Cow;
use std::path::Path;
use std::path::PathBuf;
@@ -42,45 +42,51 @@ pub trait FsPermissions {
&mut self,
path: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError>;
+ ) -> Result<PathBuf, PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_read_path<'a>(
&mut self,
path: &'a Path,
api_name: &str,
- ) -> Result<Cow<'a, Path>, AnyError>;
- fn check_read_all(&mut self, api_name: &str) -> Result<(), AnyError>;
+ ) -> Result<Cow<'a, Path>, PermissionCheckError>;
+ fn check_read_all(
+ &mut self,
+ api_name: &str,
+ ) -> Result<(), PermissionCheckError>;
fn check_read_blind(
&mut self,
p: &Path,
display: &str,
api_name: &str,
- ) -> Result<(), AnyError>;
+ ) -> Result<(), PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_write(
&mut self,
path: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError>;
+ ) -> Result<PathBuf, PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_write_path<'a>(
&mut self,
path: &'a Path,
api_name: &str,
- ) -> Result<Cow<'a, Path>, AnyError>;
+ ) -> Result<Cow<'a, Path>, PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_write_partial(
&mut self,
path: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError>;
- fn check_write_all(&mut self, api_name: &str) -> Result<(), AnyError>;
+ ) -> Result<PathBuf, PermissionCheckError>;
+ fn check_write_all(
+ &mut self,
+ api_name: &str,
+ ) -> Result<(), PermissionCheckError>;
fn check_write_blind(
&mut self,
p: &Path,
display: &str,
api_name: &str,
- ) -> Result<(), AnyError>;
+ ) -> Result<(), PermissionCheckError>;
fn check<'a>(
&mut self,
@@ -140,7 +146,7 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
&mut self,
path: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_read(self, path, api_name)
}
@@ -148,7 +154,7 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
&mut self,
path: &'a Path,
api_name: &str,
- ) -> Result<Cow<'a, Path>, AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_read_path(
self,
path,
@@ -160,7 +166,7 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
path: &Path,
display: &str,
api_name: &str,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_read_blind(
self, path, display, api_name,
)
@@ -170,7 +176,7 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
&mut self,
path: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_write(self, path, api_name)
}
@@ -178,7 +184,7 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
&mut self,
path: &'a Path,
api_name: &str,
- ) -> Result<Cow<'a, Path>, AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_write_path(
self, path, api_name,
)
@@ -188,7 +194,7 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
&mut self,
path: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_write_partial(
self, path, api_name,
)
@@ -199,17 +205,23 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
p: &Path,
display: &str,
api_name: &str,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_write_blind(
self, p, display, api_name,
)
}
- fn check_read_all(&mut self, api_name: &str) -> Result<(), AnyError> {
+ fn check_read_all(
+ &mut self,
+ api_name: &str,
+ ) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_read_all(self, api_name)
}
- fn check_write_all(&mut self, api_name: &str) -> Result<(), AnyError> {
+ fn check_write_all(
+ &mut self,
+ api_name: &str,
+ ) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_write_all(self, api_name)
}
}
diff --git a/ext/fs/ops.rs b/ext/fs/ops.rs
index a3f59da4e..9b76b49e6 100644
--- a/ext/fs/ops.rs
+++ b/ext/fs/ops.rs
@@ -10,6 +10,12 @@ use std::path::PathBuf;
use std::path::StripPrefixError;
use std::rc::Rc;
+use crate::interface::AccessCheckFn;
+use crate::interface::FileSystemRc;
+use crate::interface::FsDirEntry;
+use crate::interface::FsFileType;
+use crate::FsPermissions;
+use crate::OpenOptions;
use deno_core::op2;
use deno_core::CancelFuture;
use deno_core::CancelHandle;
@@ -20,18 +26,12 @@ use deno_core::ToJsBuffer;
use deno_io::fs::FileResource;
use deno_io::fs::FsError;
use deno_io::fs::FsStat;
+use deno_permissions::PermissionCheckError;
use rand::rngs::ThreadRng;
use rand::thread_rng;
use rand::Rng;
use serde::Serialize;
-use crate::interface::AccessCheckFn;
-use crate::interface::FileSystemRc;
-use crate::interface::FsDirEntry;
-use crate::interface::FsFileType;
-use crate::FsPermissions;
-use crate::OpenOptions;
-
#[derive(Debug, thiserror::Error)]
pub enum FsOpsError {
#[error("{0}")]
@@ -39,7 +39,7 @@ pub enum FsOpsError {
#[error("{0}")]
OperationError(#[source] OperationError),
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] PermissionCheckError),
#[error(transparent)]
Resource(deno_core::error::AnyError),
#[error("File name or path {0:?} is not valid UTF-8")]
@@ -150,8 +150,7 @@ where
let path = fs.cwd()?;
state
.borrow_mut::<P>()
- .check_read_blind(&path, "CWD", "Deno.cwd()")
- .map_err(FsOpsError::Permission)?;
+ .check_read_blind(&path, "CWD", "Deno.cwd()")?;
let path_str = path_into_string(path.into_os_string())?;
Ok(path_str)
}
@@ -166,8 +165,7 @@ where
{
let d = state
.borrow_mut::<P>()
- .check_read(directory, "Deno.chdir()")
- .map_err(FsOpsError::Permission)?;
+ .check_read(directory, "Deno.chdir()")?;
state
.borrow::<FileSystemRc>()
.chdir(&d)
@@ -253,8 +251,7 @@ where
let path = state
.borrow_mut::<P>()
- .check_write(&path, "Deno.mkdirSync()")
- .map_err(FsOpsError::Permission)?;
+ .check_write(&path, "Deno.mkdirSync()")?;
let fs = state.borrow::<FileSystemRc>();
fs.mkdir_sync(&path, recursive, Some(mode))
@@ -277,10 +274,7 @@ where
let (fs, path) = {
let mut state = state.borrow_mut();
- let path = state
- .borrow_mut::<P>()
- .check_write(&path, "Deno.mkdir()")
- .map_err(FsOpsError::Permission)?;
+ let path = state.borrow_mut::<P>().check_write(&path, "Deno.mkdir()")?;
(state.borrow::<FileSystemRc>().clone(), path)
};
@@ -302,8 +296,7 @@ where
{
let path = state
.borrow_mut::<P>()
- .check_write(&path, "Deno.chmodSync()")
- .map_err(FsOpsError::Permission)?;
+ .check_write(&path, "Deno.chmodSync()")?;
let fs = state.borrow::<FileSystemRc>();
fs.chmod_sync(&path, mode).context_path("chmod", &path)?;
Ok(())
@@ -320,10 +313,7 @@ where
{
let (fs, path) = {
let mut state = state.borrow_mut();
- let path = state
- .borrow_mut::<P>()
- .check_write(&path, "Deno.chmod()")
- .map_err(FsOpsError::Permission)?;
+ let path = state.borrow_mut::<P>().check_write(&path, "Deno.chmod()")?;
(state.borrow::<FileSystemRc>().clone(), path)
};
fs.chmod_async(path.clone(), mode)
@@ -344,8 +334,7 @@ where
{
let path = state
.borrow_mut::<P>()
- .check_write(&path, "Deno.chownSync()")
- .map_err(FsOpsError::Permission)?;
+ .check_write(&path, "Deno.chownSync()")?;
let fs = state.borrow::<FileSystemRc>();
fs.chown_sync(&path, uid, gid)
.context_path("chown", &path)?;
@@ -364,10 +353,7 @@ where
{
let (fs, path) = {
let mut state = state.borrow_mut();
- let path = state
- .borrow_mut::<P>()
- .check_write(&path, "Deno.chown()")
- .map_err(FsOpsError::Permission)?;
+ let path = state.borrow_mut::<P>().check_write(&path, "Deno.chown()")?;
(state.borrow::<FileSystemRc>().clone(), path)
};
fs.chown_async(path.clone(), uid, gid)
@@ -387,8 +373,7 @@ where
{
let path = state
.borrow_mut::<P>()
- .check_write(path, "Deno.removeSync()")
- .map_err(FsOpsError::Permission)?;
+ .check_write(path, "Deno.removeSync()")?;
let fs = state.borrow::<FileSystemRc>();
fs.remove_sync(&path, recursive)
@@ -411,13 +396,11 @@ where
let path = if recursive {
state
.borrow_mut::<P>()
- .check_write(&path, "Deno.remove()")
- .map_err(FsOpsError::Permission)?
+ .check_write(&path, "Deno.remove()")?
} else {
state
.borrow_mut::<P>()
- .check_write_partial(&path, "Deno.remove()")
- .map_err(FsOpsError::Permission)?
+ .check_write_partial(&path, "Deno.remove()")?
};
(state.borrow::<FileSystemRc>().clone(), path)
@@ -440,12 +423,8 @@ where
P: FsPermissions + 'static,
{
let permissions = state.borrow_mut::<P>();
- let from = permissions
- .check_read(from, "Deno.copyFileSync()")
- .map_err(FsOpsError::Permission)?;
- let to = permissions
- .check_write(to, "Deno.copyFileSync()")
- .map_err(FsOpsError::Permission)?;
+ let from = permissions.check_read(from, "Deno.copyFileSync()")?;
+ let to = permissions.check_write(to, "Deno.copyFileSync()")?;
let fs = state.borrow::<FileSystemRc>();
fs.copy_file_sync(&from, &to)
@@ -466,12 +445,8 @@ where
let (fs, from, to) = {
let mut state = state.borrow_mut();
let permissions = state.borrow_mut::<P>();
- let from = permissions
- .check_read(&from, "Deno.copyFile()")
- .map_err(FsOpsError::Permission)?;
- let to = permissions
- .check_write(&to, "Deno.copyFile()")
- .map_err(FsOpsError::Permission)?;
+ let from = permissions.check_read(&from, "Deno.copyFile()")?;
+ let to = permissions.check_write(&to, "Deno.copyFile()")?;
(state.borrow::<FileSystemRc>().clone(), from, to)
};
@@ -493,8 +468,7 @@ where
{
let path = state
.borrow_mut::<P>()
- .check_read(&path, "Deno.statSync()")
- .map_err(FsOpsError::Permission)?;
+ .check_read(&path, "Deno.statSync()")?;
let fs = state.borrow::<FileSystemRc>();
let stat = fs.stat_sync(&path).context_path("stat", &path)?;
let serializable_stat = SerializableStat::from(stat);
@@ -514,9 +488,7 @@ where
let (fs, path) = {
let mut state = state.borrow_mut();
let permissions = state.borrow_mut::<P>();
- let path = permissions
- .check_read(&path, "Deno.stat()")
- .map_err(FsOpsError::Permission)?;
+ let path = permissions.check_read(&path, "Deno.stat()")?;
(state.borrow::<FileSystemRc>().clone(), path)
};
let stat = fs
@@ -537,8 +509,7 @@ where
{
let path = state
.borrow_mut::<P>()
- .check_read(&path, "Deno.lstatSync()")
- .map_err(FsOpsError::Permission)?;
+ .check_read(&path, "Deno.lstatSync()")?;
let fs = state.borrow::<FileSystemRc>();
let stat = fs.lstat_sync(&path).context_path("lstat", &path)?;
let serializable_stat = SerializableStat::from(stat);
@@ -558,9 +529,7 @@ where
let (fs, path) = {
let mut state = state.borrow_mut();
let permissions = state.borrow_mut::<P>();
- let path = permissions
- .check_read(&path, "Deno.lstat()")
- .map_err(FsOpsError::Permission)?;
+ let path = permissions.check_read(&path, "Deno.lstat()")?;
(state.borrow::<FileSystemRc>().clone(), path)
};
let stat = fs
@@ -581,13 +550,9 @@ where
{
let fs = state.borrow::<FileSystemRc>().clone();
let permissions = state.borrow_mut::<P>();
- let path = permissions
- .check_read(&path, "Deno.realPathSync()")
- .map_err(FsOpsError::Permission)?;
+ let path = permissions.check_read(&path, "Deno.realPathSync()")?;
if path.is_relative() {
- permissions
- .check_read_blind(&fs.cwd()?, "CWD", "Deno.realPathSync()")
- .map_err(FsOpsError::Permission)?;
+ permissions.check_read_blind(&fs.cwd()?, "CWD", "Deno.realPathSync()")?;
}
let resolved_path =
@@ -610,13 +575,9 @@ where
let mut state = state.borrow_mut();
let fs = state.borrow::<FileSystemRc>().clone();
let permissions = state.borrow_mut::<P>();
- let path = permissions
- .check_read(&path, "Deno.realPath()")
- .map_err(FsOpsError::Permission)?;
+ let path = permissions.check_read(&path, "Deno.realPath()")?;
if path.is_relative() {
- permissions
- .check_read_blind(&fs.cwd()?, "CWD", "Deno.realPath()")
- .map_err(FsOpsError::Permission)?;
+ permissions.check_read_blind(&fs.cwd()?, "CWD", "Deno.realPath()")?;
}
(fs, path)
};
@@ -640,8 +601,7 @@ where
{
let path = state
.borrow_mut::<P>()
- .check_read(&path, "Deno.readDirSync()")
- .map_err(FsOpsError::Permission)?;
+ .check_read(&path, "Deno.readDirSync()")?;
let fs = state.borrow::<FileSystemRc>();
let entries = fs.read_dir_sync(&path).context_path("readdir", &path)?;
@@ -662,8 +622,7 @@ where
let mut state = state.borrow_mut();
let path = state
.borrow_mut::<P>()
- .check_read(&path, "Deno.readDir()")
- .map_err(FsOpsError::Permission)?;
+ .check_read(&path, "Deno.readDir()")?;
(state.borrow::<FileSystemRc>().clone(), path)
};
@@ -685,15 +644,9 @@ where
P: FsPermissions + 'static,
{
let permissions = state.borrow_mut::<P>();
- let _ = permissions
- .check_read(&oldpath, "Deno.renameSync()")
- .map_err(FsOpsError::Permission)?;
- let oldpath = permissions
- .check_write(&oldpath, "Deno.renameSync()")
- .map_err(FsOpsError::Permission)?;
- let newpath = permissions
- .check_write(&newpath, "Deno.renameSync()")
- .map_err(FsOpsError::Permission)?;
+ let _ = permissions.check_read(&oldpath, "Deno.renameSync()")?;
+ let oldpath = permissions.check_write(&oldpath, "Deno.renameSync()")?;
+ let newpath = permissions.check_write(&newpath, "Deno.renameSync()")?;
let fs = state.borrow::<FileSystemRc>();
fs.rename_sync(&oldpath, &newpath)
@@ -714,15 +667,9 @@ where
let (fs, oldpath, newpath) = {
let mut state = state.borrow_mut();
let permissions = state.borrow_mut::<P>();
- _ = permissions
- .check_read(&oldpath, "Deno.rename()")
- .map_err(FsOpsError::Permission)?;
- let oldpath = permissions
- .check_write(&oldpath, "Deno.rename()")
- .map_err(FsOpsError::Permission)?;
- let newpath = permissions
- .check_write(&newpath, "Deno.rename()")
- .map_err(FsOpsError::Permission)?;
+ _ = permissions.check_read(&oldpath, "Deno.rename()")?;
+ let oldpath = permissions.check_write(&oldpath, "Deno.rename()")?;
+ let newpath = permissions.check_write(&newpath, "Deno.rename()")?;
(state.borrow::<FileSystemRc>().clone(), oldpath, newpath)
};
@@ -743,18 +690,10 @@ where
P: FsPermissions + 'static,
{
let permissions = state.borrow_mut::<P>();
- _ = permissions
- .check_read(oldpath, "Deno.linkSync()")
- .map_err(FsOpsError::Permission)?;
- let oldpath = permissions
- .check_write(oldpath, "Deno.linkSync()")
- .map_err(FsOpsError::Permission)?;
- _ = permissions
- .check_read(newpath, "Deno.linkSync()")
- .map_err(FsOpsError::Permission)?;
- let newpath = permissions
- .check_write(newpath, "Deno.linkSync()")
- .map_err(FsOpsError::Permission)?;
+ _ = permissions.check_read(oldpath, "Deno.linkSync()")?;
+ let oldpath = permissions.check_write(oldpath, "Deno.linkSync()")?;
+ _ = permissions.check_read(newpath, "Deno.linkSync()")?;
+ let newpath = permissions.check_write(newpath, "Deno.linkSync()")?;
let fs = state.borrow::<FileSystemRc>();
fs.link_sync(&oldpath, &newpath)
@@ -775,18 +714,10 @@ where
let (fs, oldpath, newpath) = {
let mut state = state.borrow_mut();
let permissions = state.borrow_mut::<P>();
- _ = permissions
- .check_read(&oldpath, "Deno.link()")
- .map_err(FsOpsError::Permission)?;
- let oldpath = permissions
- .check_write(&oldpath, "Deno.link()")
- .map_err(FsOpsError::Permission)?;
- _ = permissions
- .check_read(&newpath, "Deno.link()")
- .map_err(FsOpsError::Permission)?;
- let newpath = permissions
- .check_write(&newpath, "Deno.link()")
- .map_err(FsOpsError::Permission)?;
+ _ = permissions.check_read(&oldpath, "Deno.link()")?;
+ let oldpath = permissions.check_write(&oldpath, "Deno.link()")?;
+ _ = permissions.check_read(&newpath, "Deno.link()")?;
+ let newpath = permissions.check_write(&newpath, "Deno.link()")?;
(state.borrow::<FileSystemRc>().clone(), oldpath, newpath)
};
@@ -811,12 +742,8 @@ where
let newpath = PathBuf::from(newpath);
let permissions = state.borrow_mut::<P>();
- permissions
- .check_write_all("Deno.symlinkSync()")
- .map_err(FsOpsError::Permission)?;
- permissions
- .check_read_all("Deno.symlinkSync()")
- .map_err(FsOpsError::Permission)?;
+ permissions.check_write_all("Deno.symlinkSync()")?;
+ permissions.check_read_all("Deno.symlinkSync()")?;
let fs = state.borrow::<FileSystemRc>();
fs.symlink_sync(&oldpath, &newpath, file_type)
@@ -841,12 +768,8 @@ where
let fs = {
let mut state = state.borrow_mut();
let permissions = state.borrow_mut::<P>();
- permissions
- .check_write_all("Deno.symlink()")
- .map_err(FsOpsError::Permission)?;
- permissions
- .check_read_all("Deno.symlink()")
- .map_err(FsOpsError::Permission)?;
+ permissions.check_write_all("Deno.symlink()")?;
+ permissions.check_read_all("Deno.symlink()")?;
state.borrow::<FileSystemRc>().clone()
};
@@ -868,8 +791,7 @@ where
{
let path = state
.borrow_mut::<P>()
- .check_read(&path, "Deno.readLink()")
- .map_err(FsOpsError::Permission)?;
+ .check_read(&path, "Deno.readLink()")?;
let fs = state.borrow::<FileSystemRc>();
@@ -891,8 +813,7 @@ where
let mut state = state.borrow_mut();
let path = state
.borrow_mut::<P>()
- .check_read(&path, "Deno.readLink()")
- .map_err(FsOpsError::Permission)?;
+ .check_read(&path, "Deno.readLink()")?;
(state.borrow::<FileSystemRc>().clone(), path)
};
@@ -915,8 +836,7 @@ where
{
let path = state
.borrow_mut::<P>()
- .check_write(path, "Deno.truncateSync()")
- .map_err(FsOpsError::Permission)?;
+ .check_write(path, "Deno.truncateSync()")?;
let fs = state.borrow::<FileSystemRc>();
fs.truncate_sync(&path, len)
@@ -938,8 +858,7 @@ where
let mut state = state.borrow_mut();
let path = state
.borrow_mut::<P>()
- .check_write(&path, "Deno.truncate()")
- .map_err(FsOpsError::Permission)?;
+ .check_write(&path, "Deno.truncate()")?;
(state.borrow::<FileSystemRc>().clone(), path)
};
@@ -962,10 +881,7 @@ pub fn op_fs_utime_sync<P>(
where
P: FsPermissions + 'static,
{
- let path = state
- .borrow_mut::<P>()
- .check_write(path, "Deno.utime()")
- .map_err(FsOpsError::Permission)?;
+ let path = state.borrow_mut::<P>().check_write(path, "Deno.utime()")?;
let fs = state.borrow::<FileSystemRc>();
fs.utime_sync(&path, atime_secs, atime_nanos, mtime_secs, mtime_nanos)
@@ -988,10 +904,7 @@ where
{
let (fs, path) = {
let mut state = state.borrow_mut();
- let path = state
- .borrow_mut::<P>()
- .check_write(&path, "Deno.utime()")
- .map_err(FsOpsError::Permission)?;
+ let path = state.borrow_mut::<P>().check_write(&path, "Deno.utime()")?;
(state.borrow::<FileSystemRc>().clone(), path)
};
@@ -1219,16 +1132,12 @@ where
{
let fs = state.borrow::<FileSystemRc>().clone();
let dir = match dir {
- Some(dir) => state
- .borrow_mut::<P>()
- .check_write(dir, api_name)
- .map_err(FsOpsError::Permission)?,
+ Some(dir) => state.borrow_mut::<P>().check_write(dir, api_name)?,
None => {
let dir = fs.tmp_dir().context("tmpdir")?;
state
.borrow_mut::<P>()
- .check_write_blind(&dir, "TMP", api_name)
- .map_err(FsOpsError::Permission)?;
+ .check_write_blind(&dir, "TMP", api_name)?;
dir
}
};
@@ -1246,16 +1155,12 @@ where
let mut state = state.borrow_mut();
let fs = state.borrow::<FileSystemRc>().clone();
let dir = match dir {
- Some(dir) => state
- .borrow_mut::<P>()
- .check_write(dir, api_name)
- .map_err(FsOpsError::Permission)?,
+ Some(dir) => state.borrow_mut::<P>().check_write(dir, api_name)?,
None => {
let dir = fs.tmp_dir().context("tmpdir")?;
state
.borrow_mut::<P>()
- .check_write_blind(&dir, "TMP", api_name)
- .map_err(FsOpsError::Permission)?;
+ .check_write_blind(&dir, "TMP", api_name)?;
dir
}
};
diff --git a/ext/kv/remote.rs b/ext/kv/remote.rs
index 922853588..4930aacfe 100644
--- a/ext/kv/remote.rs
+++ b/ext/kv/remote.rs
@@ -15,6 +15,7 @@ use deno_core::futures::Stream;
use deno_core::OpState;
use deno_fetch::create_http_client;
use deno_fetch::CreateHttpClientOptions;
+use deno_permissions::PermissionCheckError;
use deno_tls::rustls::RootCertStore;
use deno_tls::Proxy;
use deno_tls::RootCertStoreProvider;
@@ -45,17 +46,17 @@ impl HttpOptions {
}
pub trait RemoteDbHandlerPermissions {
- fn check_env(&mut self, var: &str) -> Result<(), AnyError>;
+ fn check_env(&mut self, var: &str) -> Result<(), PermissionCheckError>;
fn check_net_url(
&mut self,
url: &Url,
api_name: &str,
- ) -> Result<(), AnyError>;
+ ) -> Result<(), PermissionCheckError>;
}
impl RemoteDbHandlerPermissions for deno_permissions::PermissionsContainer {
#[inline(always)]
- fn check_env(&mut self, var: &str) -> Result<(), AnyError> {
+ fn check_env(&mut self, var: &str) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_env(self, var)
}
@@ -64,7 +65,7 @@ impl RemoteDbHandlerPermissions for deno_permissions::PermissionsContainer {
&mut self,
url: &Url,
api_name: &str,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_net_url(self, url, api_name)
}
}
@@ -103,7 +104,9 @@ impl<P: RemoteDbHandlerPermissions + 'static> denokv_remote::RemotePermissions
fn check_net_url(&self, url: &Url) -> Result<(), anyhow::Error> {
let mut state = self.state.borrow_mut();
let permissions = state.borrow_mut::<P>();
- permissions.check_net_url(url, "Deno.openKv")
+ permissions
+ .check_net_url(url, "Deno.openKv")
+ .map_err(Into::into)
}
}
diff --git a/ext/kv/sqlite.rs b/ext/kv/sqlite.rs
index 0b4a3693c..9de520927 100644
--- a/ext/kv/sqlite.rs
+++ b/ext/kv/sqlite.rs
@@ -13,20 +13,20 @@ use std::sync::Arc;
use std::sync::Mutex;
use std::sync::OnceLock;
+use crate::DatabaseHandler;
use async_trait::async_trait;
use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::unsync::spawn_blocking;
use deno_core::OpState;
use deno_path_util::normalize_path;
+use deno_permissions::PermissionCheckError;
pub use denokv_sqlite::SqliteBackendError;
use denokv_sqlite::SqliteConfig;
use denokv_sqlite::SqliteNotifier;
use rand::SeedableRng;
use rusqlite::OpenFlags;
-use crate::DatabaseHandler;
-
static SQLITE_NOTIFIERS_MAP: OnceLock<Mutex<HashMap<PathBuf, SqliteNotifier>>> =
OnceLock::new();
@@ -42,13 +42,13 @@ pub trait SqliteDbHandlerPermissions {
&mut self,
p: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError>;
+ ) -> Result<PathBuf, PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_write<'a>(
&mut self,
p: &'a Path,
api_name: &str,
- ) -> Result<Cow<'a, Path>, AnyError>;
+ ) -> Result<Cow<'a, Path>, PermissionCheckError>;
}
impl SqliteDbHandlerPermissions for deno_permissions::PermissionsContainer {
@@ -57,7 +57,7 @@ impl SqliteDbHandlerPermissions for deno_permissions::PermissionsContainer {
&mut self,
p: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_read(self, p, api_name)
}
@@ -66,7 +66,7 @@ impl SqliteDbHandlerPermissions for deno_permissions::PermissionsContainer {
&mut self,
p: &'a Path,
api_name: &str,
- ) -> Result<Cow<'a, Path>, AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_write_path(self, p, api_name)
}
}
diff --git a/ext/napi/lib.rs b/ext/napi/lib.rs
index 20f924bdb..88b8c238d 100644
--- a/ext/napi/lib.rs
+++ b/ext/napi/lib.rs
@@ -43,7 +43,7 @@ pub enum NApiError {
#[error("Unable to find register Node-API module at {}", .0.display())]
ModuleNotFound(PathBuf),
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] PermissionCheckError),
}
#[cfg(unix)]
@@ -55,6 +55,7 @@ use libloading::os::windows::*;
// Expose common stuff for ease of use.
// `use deno_napi::*`
pub use deno_core::v8;
+use deno_permissions::PermissionCheckError;
pub use std::ffi::CStr;
pub use std::os::raw::c_char;
pub use std::os::raw::c_void;
@@ -508,20 +509,14 @@ deno_core::extension!(deno_napi,
pub trait NapiPermissions {
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
- fn check(
- &mut self,
- path: &str,
- ) -> Result<PathBuf, deno_core::error::AnyError>;
+ fn check(&mut self, path: &str) -> Result<PathBuf, PermissionCheckError>;
}
// NOTE(bartlomieju): for now, NAPI uses `--allow-ffi` flag, but that might
// change in the future.
impl NapiPermissions for deno_permissions::PermissionsContainer {
#[inline(always)]
- fn check(
- &mut self,
- path: &str,
- ) -> Result<PathBuf, deno_core::error::AnyError> {
+ fn check(&mut self, path: &str) -> Result<PathBuf, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_ffi(self, path)
}
}
@@ -553,7 +548,7 @@ where
let (async_work_sender, cleanup_hooks, external_ops_tracker, path) = {
let mut op_state = op_state.borrow_mut();
let permissions = op_state.borrow_mut::<NP>();
- let path = permissions.check(&path).map_err(NApiError::Permission)?;
+ let path = permissions.check(&path)?;
let napi_state = op_state.borrow::<NapiState>();
(
op_state.borrow::<V8CrossThreadTaskSpawner>().clone(),
diff --git a/ext/net/lib.rs b/ext/net/lib.rs
index b039965d4..bf8f58aa2 100644
--- a/ext/net/lib.rs
+++ b/ext/net/lib.rs
@@ -11,6 +11,7 @@ mod tcp;
use deno_core::error::AnyError;
use deno_core::OpState;
+use deno_permissions::PermissionCheckError;
use deno_tls::rustls::RootCertStore;
use deno_tls::RootCertStoreProvider;
use std::borrow::Cow;
@@ -25,25 +26,25 @@ pub trait NetPermissions {
&mut self,
host: &(T, Option<u16>),
api_name: &str,
- ) -> Result<(), AnyError>;
+ ) -> Result<(), PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_read(
&mut self,
p: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError>;
+ ) -> Result<PathBuf, PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_write(
&mut self,
p: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError>;
+ ) -> Result<PathBuf, PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_write_path<'a>(
&mut self,
p: &'a Path,
api_name: &str,
- ) -> Result<Cow<'a, Path>, AnyError>;
+ ) -> Result<Cow<'a, Path>, PermissionCheckError>;
}
impl NetPermissions for deno_permissions::PermissionsContainer {
@@ -52,7 +53,7 @@ impl NetPermissions for deno_permissions::PermissionsContainer {
&mut self,
host: &(T, Option<u16>),
api_name: &str,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_net(self, host, api_name)
}
@@ -61,7 +62,7 @@ impl NetPermissions for deno_permissions::PermissionsContainer {
&mut self,
path: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_read(self, path, api_name)
}
@@ -70,7 +71,7 @@ impl NetPermissions for deno_permissions::PermissionsContainer {
&mut self,
path: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_write(self, path, api_name)
}
@@ -79,7 +80,7 @@ impl NetPermissions for deno_permissions::PermissionsContainer {
&mut self,
path: &'a Path,
api_name: &str,
- ) -> Result<Cow<'a, Path>, AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_write_path(
self, path, api_name,
)
diff --git a/ext/net/ops.rs b/ext/net/ops.rs
index 0f92dead0..35bcff8dc 100644
--- a/ext/net/ops.rs
+++ b/ext/net/ops.rs
@@ -81,8 +81,8 @@ pub enum NetError {
Io(#[from] std::io::Error),
#[error("Another accept task is ongoing")]
AcceptTaskOngoing,
- #[error("{0}")]
- Permission(deno_core::error::AnyError),
+ #[error(transparent)]
+ Permission(#[from] deno_permissions::PermissionCheckError),
#[error("{0}")]
Resource(deno_core::error::AnyError),
#[error("No resolved address found")]
@@ -195,12 +195,10 @@ where
{
{
let mut s = state.borrow_mut();
- s.borrow_mut::<NP>()
- .check_net(
- &(&addr.hostname, Some(addr.port)),
- "Deno.DatagramConn.send()",
- )
- .map_err(NetError::Permission)?;
+ s.borrow_mut::<NP>().check_net(
+ &(&addr.hostname, Some(addr.port)),
+ "Deno.DatagramConn.send()",
+ )?;
}
let addr = resolve_addr(&addr.hostname, addr.port)
.await?
@@ -369,8 +367,7 @@ where
let mut state_ = state.borrow_mut();
state_
.borrow_mut::<NP>()
- .check_net(&(&addr.hostname, Some(addr.port)), "Deno.connect()")
- .map_err(NetError::Permission)?;
+ .check_net(&(&addr.hostname, Some(addr.port)), "Deno.connect()")?;
}
let addr = resolve_addr(&addr.hostname, addr.port)
@@ -420,8 +417,7 @@ where
}
state
.borrow_mut::<NP>()
- .check_net(&(&addr.hostname, Some(addr.port)), "Deno.listen()")
- .map_err(NetError::Permission)?;
+ .check_net(&(&addr.hostname, Some(addr.port)), "Deno.listen()")?;
let addr = resolve_addr_sync(&addr.hostname, addr.port)?
.next()
.ok_or_else(|| NetError::NoResolvedAddress)?;
@@ -449,8 +445,7 @@ where
{
state
.borrow_mut::<NP>()
- .check_net(&(&addr.hostname, Some(addr.port)), "Deno.listenDatagram()")
- .map_err(NetError::Permission)?;
+ .check_net(&(&addr.hostname, Some(addr.port)), "Deno.listenDatagram()")?;
let addr = resolve_addr_sync(&addr.hostname, addr.port)?
.next()
.ok_or_else(|| NetError::NoResolvedAddress)?;
@@ -647,9 +642,7 @@ where
let socker_addr = &ns.socket_addr;
let ip = socker_addr.ip().to_string();
let port = socker_addr.port();
- perm
- .check_net(&(ip, Some(port)), "Deno.resolveDns()")
- .map_err(NetError::Permission)?;
+ perm.check_net(&(ip, Some(port)), "Deno.resolveDns()")?;
}
}
@@ -834,6 +827,7 @@ mod tests {
use deno_core::futures::FutureExt;
use deno_core::JsRuntime;
use deno_core::RuntimeOptions;
+ use deno_permissions::PermissionCheckError;
use socket2::SockRef;
use std::net::Ipv4Addr;
use std::net::Ipv6Addr;
@@ -1041,7 +1035,7 @@ mod tests {
&mut self,
_host: &(T, Option<u16>),
_api_name: &str,
- ) -> Result<(), deno_core::error::AnyError> {
+ ) -> Result<(), PermissionCheckError> {
Ok(())
}
@@ -1049,7 +1043,7 @@ mod tests {
&mut self,
p: &str,
_api_name: &str,
- ) -> Result<PathBuf, deno_core::error::AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
Ok(PathBuf::from(p))
}
@@ -1057,7 +1051,7 @@ mod tests {
&mut self,
p: &str,
_api_name: &str,
- ) -> Result<PathBuf, deno_core::error::AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
Ok(PathBuf::from(p))
}
@@ -1065,7 +1059,7 @@ mod tests {
&mut self,
p: &'a Path,
_api_name: &str,
- ) -> Result<Cow<'a, Path>, deno_core::error::AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
Ok(Cow::Borrowed(p))
}
}
diff --git a/ext/node/lib.rs b/ext/node/lib.rs
index db6d08e11..b08b0493b 100644
--- a/ext/node/lib.rs
+++ b/ext/node/lib.rs
@@ -24,6 +24,7 @@ pub mod ops;
mod polyfill;
pub use deno_package_json::PackageJson;
+use deno_permissions::PermissionCheckError;
pub use node_resolver::PathClean;
pub use ops::ipc::ChildPipeFd;
pub use ops::ipc::IpcJsonStreamResource;
@@ -45,10 +46,13 @@ pub trait NodePermissions {
&mut self,
url: &Url,
api_name: &str,
- ) -> Result<(), AnyError>;
+ ) -> Result<(), PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
#[inline(always)]
- fn check_read(&mut self, path: &str) -> Result<PathBuf, AnyError> {
+ fn check_read(
+ &mut self,
+ path: &str,
+ ) -> Result<PathBuf, PermissionCheckError> {
self.check_read_with_api_name(path, None)
}
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
@@ -56,20 +60,24 @@ pub trait NodePermissions {
&mut self,
path: &str,
api_name: Option<&str>,
- ) -> Result<PathBuf, AnyError>;
+ ) -> Result<PathBuf, PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_read_path<'a>(
&mut self,
path: &'a Path,
- ) -> Result<Cow<'a, Path>, AnyError>;
+ ) -> Result<Cow<'a, Path>, PermissionCheckError>;
fn query_read_all(&mut self) -> bool;
- fn check_sys(&mut self, kind: &str, api_name: &str) -> Result<(), AnyError>;
+ fn check_sys(
+ &mut self,
+ kind: &str,
+ api_name: &str,
+ ) -> Result<(), PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_write_with_api_name(
&mut self,
path: &str,
api_name: Option<&str>,
- ) -> Result<PathBuf, AnyError>;
+ ) -> Result<PathBuf, PermissionCheckError>;
}
impl NodePermissions for deno_permissions::PermissionsContainer {
@@ -78,7 +86,7 @@ impl NodePermissions for deno_permissions::PermissionsContainer {
&mut self,
url: &Url,
api_name: &str,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_net_url(self, url, api_name)
}
@@ -87,7 +95,7 @@ impl NodePermissions for deno_permissions::PermissionsContainer {
&mut self,
path: &str,
api_name: Option<&str>,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_read_with_api_name(
self, path, api_name,
)
@@ -96,7 +104,7 @@ impl NodePermissions for deno_permissions::PermissionsContainer {
fn check_read_path<'a>(
&mut self,
path: &'a Path,
- ) -> Result<Cow<'a, Path>, AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_read_path(self, path, None)
}
@@ -109,13 +117,17 @@ impl NodePermissions for deno_permissions::PermissionsContainer {
&mut self,
path: &str,
api_name: Option<&str>,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_write_with_api_name(
self, path, api_name,
)
}
- fn check_sys(&mut self, kind: &str, api_name: &str) -> Result<(), AnyError> {
+ fn check_sys(
+ &mut self,
+ kind: &str,
+ api_name: &str,
+ ) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_sys(self, kind, api_name)
}
}
diff --git a/ext/node/ops/fs.rs b/ext/node/ops/fs.rs
index 98b3c46a1..9c0e4e1cc 100644
--- a/ext/node/ops/fs.rs
+++ b/ext/node/ops/fs.rs
@@ -13,7 +13,7 @@ use crate::NodePermissions;
#[derive(Debug, thiserror::Error)]
pub enum FsError {
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] deno_permissions::PermissionCheckError),
#[error("{0}")]
Io(#[from] std::io::Error),
#[cfg(windows)]
@@ -53,8 +53,7 @@ where
let mut state = state.borrow_mut();
let path = state
.borrow_mut::<P>()
- .check_read_with_api_name(&path, Some("node:fs.exists()"))
- .map_err(FsError::Permission)?;
+ .check_read_with_api_name(&path, Some("node:fs.exists()"))?;
(state.borrow::<FileSystemRc>().clone(), path)
};
@@ -72,12 +71,10 @@ where
{
let path = state
.borrow_mut::<P>()
- .check_read_with_api_name(path, Some("node:fs.cpSync"))
- .map_err(FsError::Permission)?;
+ .check_read_with_api_name(path, Some("node:fs.cpSync"))?;
let new_path = state
.borrow_mut::<P>()
- .check_write_with_api_name(new_path, Some("node:fs.cpSync"))
- .map_err(FsError::Permission)?;
+ .check_write_with_api_name(new_path, Some("node:fs.cpSync"))?;
let fs = state.borrow::<FileSystemRc>();
fs.cp_sync(&path, &new_path)?;
@@ -97,12 +94,10 @@ where
let mut state = state.borrow_mut();
let path = state
.borrow_mut::<P>()
- .check_read_with_api_name(&path, Some("node:fs.cpSync"))
- .map_err(FsError::Permission)?;
+ .check_read_with_api_name(&path, Some("node:fs.cpSync"))?;
let new_path = state
.borrow_mut::<P>()
- .check_write_with_api_name(&new_path, Some("node:fs.cpSync"))
- .map_err(FsError::Permission)?;
+ .check_write_with_api_name(&new_path, Some("node:fs.cpSync"))?;
(state.borrow::<FileSystemRc>().clone(), path, new_path)
};
@@ -136,12 +131,10 @@ where
let mut state = state.borrow_mut();
let path = state
.borrow_mut::<P>()
- .check_read_with_api_name(&path, Some("node:fs.statfs"))
- .map_err(FsError::Permission)?;
+ .check_read_with_api_name(&path, Some("node:fs.statfs"))?;
state
.borrow_mut::<P>()
- .check_sys("statfs", "node:fs.statfs")
- .map_err(FsError::Permission)?;
+ .check_sys("statfs", "node:fs.statfs")?;
path
};
#[cfg(unix)]
@@ -279,8 +272,7 @@ where
{
let path = state
.borrow_mut::<P>()
- .check_write_with_api_name(path, Some("node:fs.lutimes"))
- .map_err(FsError::Permission)?;
+ .check_write_with_api_name(path, Some("node:fs.lutimes"))?;
let fs = state.borrow::<FileSystemRc>();
fs.lutime_sync(&path, atime_secs, atime_nanos, mtime_secs, mtime_nanos)?;
@@ -303,8 +295,7 @@ where
let mut state = state.borrow_mut();
let path = state
.borrow_mut::<P>()
- .check_write_with_api_name(&path, Some("node:fs.lutimesSync"))
- .map_err(FsError::Permission)?;
+ .check_write_with_api_name(&path, Some("node:fs.lutimesSync"))?;
(state.borrow::<FileSystemRc>().clone(), path)
};
@@ -326,8 +317,7 @@ where
{
let path = state
.borrow_mut::<P>()
- .check_write_with_api_name(&path, Some("node:fs.lchownSync"))
- .map_err(FsError::Permission)?;
+ .check_write_with_api_name(&path, Some("node:fs.lchownSync"))?;
let fs = state.borrow::<FileSystemRc>();
fs.lchown_sync(&path, uid, gid)?;
Ok(())
@@ -347,8 +337,7 @@ where
let mut state = state.borrow_mut();
let path = state
.borrow_mut::<P>()
- .check_write_with_api_name(&path, Some("node:fs.lchown"))
- .map_err(FsError::Permission)?;
+ .check_write_with_api_name(&path, Some("node:fs.lchown"))?;
(state.borrow::<FileSystemRc>().clone(), path)
};
fs.lchown_async(path, uid, gid).await?;
diff --git a/ext/node/ops/http.rs b/ext/node/ops/http.rs
index 730e1e482..69571078f 100644
--- a/ext/node/ops/http.rs
+++ b/ext/node/ops/http.rs
@@ -78,9 +78,7 @@ where
{
let permissions = state.borrow_mut::<P>();
- permissions
- .check_net_url(&url, "ClientRequest")
- .map_err(FetchError::Permission)?;
+ permissions.check_net_url(&url, "ClientRequest")?;
}
let mut header_map = HeaderMap::new();
diff --git a/ext/node/ops/os/mod.rs b/ext/node/ops/os/mod.rs
index ea7e6b99f..d291277ad 100644
--- a/ext/node/ops/os/mod.rs
+++ b/ext/node/ops/os/mod.rs
@@ -14,7 +14,7 @@ pub enum OsError {
#[error(transparent)]
Priority(priority::PriorityError),
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] deno_permissions::PermissionCheckError),
#[error("Failed to get cpu info")]
FailedToGetCpuInfo,
#[error("Failed to get user info")]
@@ -31,9 +31,7 @@ where
{
{
let permissions = state.borrow_mut::<P>();
- permissions
- .check_sys("getPriority", "node:os.getPriority()")
- .map_err(OsError::Permission)?;
+ permissions.check_sys("getPriority", "node:os.getPriority()")?;
}
priority::get_priority(pid).map_err(OsError::Priority)
@@ -50,9 +48,7 @@ where
{
{
let permissions = state.borrow_mut::<P>();
- permissions
- .check_sys("setPriority", "node:os.setPriority()")
- .map_err(OsError::Permission)?;
+ permissions.check_sys("setPriority", "node:os.setPriority()")?;
}
priority::set_priority(pid, priority).map_err(OsError::Priority)
@@ -266,9 +262,7 @@ where
{
{
let permissions = state.borrow_mut::<P>();
- permissions
- .check_sys("cpus", "node:os.cpus()")
- .map_err(OsError::Permission)?;
+ permissions.check_sys("cpus", "node:os.cpus()")?;
}
cpus::cpu_info().ok_or(OsError::FailedToGetCpuInfo)
diff --git a/ext/websocket/lib.rs b/ext/websocket/lib.rs
index 2a67ac5a1..a5734271c 100644
--- a/ext/websocket/lib.rs
+++ b/ext/websocket/lib.rs
@@ -50,6 +50,7 @@ use tokio::io::ReadHalf;
use tokio::io::WriteHalf;
use tokio::net::TcpStream;
+use deno_permissions::PermissionCheckError;
use fastwebsockets::CloseCode;
use fastwebsockets::FragmentCollectorRead;
use fastwebsockets::Frame;
@@ -75,7 +76,7 @@ pub enum WebsocketError {
#[error(transparent)]
Url(url::ParseError),
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] PermissionCheckError),
#[error(transparent)]
Resource(deno_core::error::AnyError),
#[error(transparent)]
@@ -112,7 +113,7 @@ pub trait WebSocketPermissions {
&mut self,
_url: &url::Url,
_api_name: &str,
- ) -> Result<(), deno_core::error::AnyError>;
+ ) -> Result<(), PermissionCheckError>;
}
impl WebSocketPermissions for deno_permissions::PermissionsContainer {
@@ -121,7 +122,7 @@ impl WebSocketPermissions for deno_permissions::PermissionsContainer {
&mut self,
url: &url::Url,
api_name: &str,
- ) -> Result<(), deno_core::error::AnyError> {
+ ) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_net_url(self, url, api_name)
}
}
@@ -158,13 +159,10 @@ pub fn op_ws_check_permission_and_cancel_handle<WP>(
where
WP: WebSocketPermissions + 'static,
{
- state
- .borrow_mut::<WP>()
- .check_net_url(
- &url::Url::parse(&url).map_err(WebsocketError::Url)?,
- &api_name,
- )
- .map_err(WebsocketError::Permission)?;
+ state.borrow_mut::<WP>().check_net_url(
+ &url::Url::parse(&url).map_err(WebsocketError::Url)?,
+ &api_name,
+ )?;
if cancel_handle {
let rid = state
diff --git a/runtime/errors.rs b/runtime/errors.rs
index ada26ec35..5051150f2 100644
--- a/runtime/errors.rs
+++ b/runtime/errors.rs
@@ -12,6 +12,8 @@
use crate::ops::fs_events::FsEventsError;
use crate::ops::http::HttpStartError;
use crate::ops::os::OsError;
+use crate::ops::permissions::PermissionError;
+use crate::ops::process::CheckRunPermissionError;
use crate::ops::process::ProcessError;
use crate::ops::signal::SignalError;
use crate::ops::tty::TtyError;
@@ -48,6 +50,12 @@ use deno_kv::KvError;
use deno_kv::KvMutationError;
use deno_napi::NApiError;
use deno_net::ops::NetError;
+use deno_permissions::ChildPermissionError;
+use deno_permissions::NetDescriptorFromUrlParseError;
+use deno_permissions::PathResolveError;
+use deno_permissions::PermissionCheckError;
+use deno_permissions::RunDescriptorParseError;
+use deno_permissions::SysDescriptorParseError;
use deno_tls::TlsError;
use deno_web::BlobError;
use deno_web::CompressionError;
@@ -63,6 +71,54 @@ use std::error::Error;
use std::io;
use std::sync::Arc;
+fn get_run_descriptor_parse_error(e: &RunDescriptorParseError) -> &'static str {
+ match e {
+ RunDescriptorParseError::Which(_) => "Error",
+ RunDescriptorParseError::PathResolve(e) => get_path_resolve_error(e),
+ RunDescriptorParseError::EmptyRunQuery => "Error",
+ }
+}
+
+fn get_sys_descriptor_parse_error(e: &SysDescriptorParseError) -> &'static str {
+ match e {
+ SysDescriptorParseError::InvalidKind(_) => "TypeError",
+ SysDescriptorParseError::Empty => "Error",
+ }
+}
+
+fn get_path_resolve_error(e: &PathResolveError) -> &'static str {
+ match e {
+ PathResolveError::CwdResolve(e) => get_io_error_class(e),
+ PathResolveError::EmptyPath => "Error",
+ }
+}
+
+fn get_permission_error_class(e: &PermissionError) -> &'static str {
+ match e {
+ PermissionError::InvalidPermissionName(_) => "ReferenceError",
+ PermissionError::PathResolve(e) => get_path_resolve_error(e),
+ PermissionError::NetDescriptorParse(_) => "URIError",
+ PermissionError::SysDescriptorParse(e) => get_sys_descriptor_parse_error(e),
+ PermissionError::RunDescriptorParse(e) => get_run_descriptor_parse_error(e),
+ }
+}
+
+fn get_permission_check_error_class(e: &PermissionCheckError) -> &'static str {
+ match e {
+ PermissionCheckError::PermissionDenied(_) => "NotCapable",
+ PermissionCheckError::InvalidFilePath(_) => "URIError",
+ PermissionCheckError::NetDescriptorForUrlParse(e) => match e {
+ NetDescriptorFromUrlParseError::MissingHost(_) => "TypeError",
+ NetDescriptorFromUrlParseError::Host(_) => "URIError",
+ },
+ PermissionCheckError::SysDescriptorParse(e) => {
+ get_sys_descriptor_parse_error(e)
+ }
+ PermissionCheckError::PathResolve(e) => get_path_resolve_error(e),
+ PermissionCheckError::HostParse(_) => "URIError",
+ }
+}
+
fn get_dlopen_error_class(error: &dlopen2::Error) -> &'static str {
use dlopen2::Error::*;
match error {
@@ -445,7 +501,7 @@ fn get_napi_error_class(e: &NApiError) -> &'static str {
NApiError::InvalidPath
| NApiError::LibLoading(_)
| NApiError::ModuleNotFound(_) => "TypeError",
- NApiError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
+ NApiError::Permission(e) => get_permission_check_error_class(e),
}
}
@@ -523,7 +579,7 @@ fn get_ffi_repr_error_class(e: &ReprError) -> &'static str {
ReprError::InvalidF32 => "TypeError",
ReprError::InvalidF64 => "TypeError",
ReprError::InvalidPointer => "TypeError",
- ReprError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
+ ReprError::Permission(e) => get_permission_check_error_class(e),
}
}
@@ -531,7 +587,7 @@ fn get_ffi_dlfcn_error_class(e: &DlfcnError) -> &'static str {
match e {
DlfcnError::RegisterSymbol { .. } => "Error",
DlfcnError::Dlopen(_) => "Error",
- DlfcnError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
+ DlfcnError::Permission(e) => get_permission_check_error_class(e),
DlfcnError::Other(e) => get_error_class_name(e).unwrap_or("Error"),
}
}
@@ -549,7 +605,7 @@ fn get_ffi_callback_error_class(e: &CallbackError) -> &'static str {
match e {
CallbackError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
CallbackError::Other(e) => get_error_class_name(e).unwrap_or("Error"),
- CallbackError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
+ CallbackError::Permission(e) => get_permission_check_error_class(e),
}
}
@@ -558,8 +614,9 @@ fn get_ffi_call_error_class(e: &CallError) -> &'static str {
CallError::IR(_) => "TypeError",
CallError::NonblockingCallFailure(_) => "Error",
CallError::InvalidSymbol(_) => "TypeError",
- CallError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
+ CallError::Permission(e) => get_permission_check_error_class(e),
CallError::Callback(e) => get_ffi_callback_error_class(e),
+ CallError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
}
}
@@ -633,9 +690,8 @@ fn get_broadcast_channel_error(error: &BroadcastChannelError) -> &'static str {
fn get_fetch_error(error: &FetchError) -> &'static str {
match error {
- FetchError::Resource(e) | FetchError::Permission(e) => {
- get_error_class_name(e).unwrap_or("Error")
- }
+ FetchError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
+ FetchError::Permission(e) => get_permission_check_error_class(e),
FetchError::NetworkError => "TypeError",
FetchError::FsNotGet(_) => "TypeError",
FetchError::InvalidUrl(_) => "TypeError",
@@ -669,9 +725,8 @@ fn get_http_client_create_error(error: &HttpClientCreateError) -> &'static str {
fn get_websocket_error(error: &WebsocketError) -> &'static str {
match error {
- WebsocketError::Permission(e) | WebsocketError::Resource(e) => {
- get_error_class_name(e).unwrap_or("Error")
- }
+ WebsocketError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
+ WebsocketError::Permission(e) => get_permission_check_error_class(e),
WebsocketError::Url(e) => get_url_parse_error_class(e),
WebsocketError::Io(e) => get_io_error_class(e),
WebsocketError::WebSocket(_) => "TypeError",
@@ -708,9 +763,10 @@ fn get_fs_ops_error(error: &FsOpsError) -> &'static str {
match error {
FsOpsError::Io(e) => get_io_error_class(e),
FsOpsError::OperationError(e) => get_fs_error(&e.err),
- FsOpsError::Permission(e)
- | FsOpsError::Resource(e)
- | FsOpsError::Other(e) => get_error_class_name(e).unwrap_or("Error"),
+ FsOpsError::Permission(e) => get_permission_check_error_class(e),
+ FsOpsError::Resource(e) | FsOpsError::Other(e) => {
+ get_error_class_name(e).unwrap_or("Error")
+ }
FsOpsError::InvalidUtf8(_) => "InvalidData",
FsOpsError::StripPrefix(_) => "Error",
FsOpsError::Canceled(e) => {
@@ -777,9 +833,10 @@ fn get_net_error(error: &NetError) -> &'static str {
NetError::SocketBusy => "Busy",
NetError::Io(e) => get_io_error_class(e),
NetError::AcceptTaskOngoing => "Busy",
- NetError::RootCertStore(e)
- | NetError::Permission(e)
- | NetError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
+ NetError::RootCertStore(e) | NetError::Resource(e) => {
+ get_error_class_name(e).unwrap_or("Error")
+ }
+ NetError::Permission(e) => get_permission_check_error_class(e),
NetError::NoResolvedAddress => "Error",
NetError::AddrParse(_) => "Error",
NetError::Map(e) => get_net_map_error(e),
@@ -810,12 +867,25 @@ fn get_net_map_error(error: &deno_net::io::MapError) -> &'static str {
}
}
+fn get_child_permission_error(e: &ChildPermissionError) -> &'static str {
+ match e {
+ ChildPermissionError::Escalation => "NotCapable",
+ ChildPermissionError::PathResolve(e) => get_path_resolve_error(e),
+ ChildPermissionError::NetDescriptorParse(_) => "URIError",
+ ChildPermissionError::EnvDescriptorParse(_) => "Error",
+ ChildPermissionError::SysDescriptorParse(e) => {
+ get_sys_descriptor_parse_error(e)
+ }
+ ChildPermissionError::RunDescriptorParse(e) => {
+ get_run_descriptor_parse_error(e)
+ }
+ }
+}
+
fn get_create_worker_error(error: &CreateWorkerError) -> &'static str {
match error {
CreateWorkerError::ClassicWorkers => "DOMExceptionNotSupportedError",
- CreateWorkerError::Permission(e) => {
- get_error_class_name(e).unwrap_or("Error")
- }
+ CreateWorkerError::Permission(e) => get_child_permission_error(e),
CreateWorkerError::ModuleResolution(e) => {
get_module_resolution_error_class(e)
}
@@ -862,9 +932,8 @@ fn get_signal_error(error: &SignalError) -> &'static str {
fn get_fs_events_error(error: &FsEventsError) -> &'static str {
match error {
- FsEventsError::Resource(e) | FsEventsError::Permission(e) => {
- get_error_class_name(e).unwrap_or("Error")
- }
+ FsEventsError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
+ FsEventsError::Permission(e) => get_permission_check_error_class(e),
FsEventsError::Notify(e) => get_notify_error_class(e),
FsEventsError::Canceled(e) => {
let io_err: io::Error = e.to_owned().into();
@@ -892,9 +961,8 @@ fn get_process_error(error: &ProcessError) -> &'static str {
ProcessError::FailedResolvingCwd(e) | ProcessError::Io(e) => {
get_io_error_class(e)
}
- ProcessError::Permission(e) | ProcessError::Resource(e) => {
- get_error_class_name(e).unwrap_or("Error")
- }
+ ProcessError::Permission(e) => get_permission_check_error_class(e),
+ ProcessError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
ProcessError::BorrowMut(_) => "Error",
ProcessError::Which(_) => "Error",
ProcessError::ChildProcessAlreadyTerminated => "TypeError",
@@ -903,6 +971,14 @@ fn get_process_error(error: &ProcessError) -> &'static str {
ProcessError::InvalidPid => "TypeError",
#[cfg(unix)]
ProcessError::Nix(e) => get_nix_error_class(e),
+ ProcessError::RunPermission(e) => match e {
+ CheckRunPermissionError::Permission(e) => {
+ get_permission_check_error_class(e)
+ }
+ CheckRunPermissionError::Other(e) => {
+ get_error_class_name(e).unwrap_or("Error")
+ }
+ },
}
}
@@ -971,6 +1047,7 @@ fn get_fs_error(e: &FsError) -> &'static str {
mod node {
use super::get_error_class_name;
use super::get_io_error_class;
+ use super::get_permission_check_error_class;
use super::get_serde_json_error_class;
use super::get_url_parse_error_class;
pub use deno_node::ops::blocklist::BlocklistError;
@@ -998,7 +1075,7 @@ mod node {
pub fn get_fs_error(error: &FsError) -> &'static str {
match error {
- FsError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
+ FsError::Permission(e) => get_permission_check_error_class(e),
FsError::Io(e) => get_io_error_class(e),
#[cfg(windows)]
FsError::PathHasNoRoot => "Error",
@@ -1084,7 +1161,7 @@ mod node {
#[cfg(windows)]
PriorityError::InvalidPriority => "TypeError",
},
- OsError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
+ OsError::Permission(e) => get_permission_check_error_class(e),
OsError::FailedToGetCpuInfo => "TypeError",
OsError::FailedToGetUserInfo(e) => get_io_error_class(e),
}
@@ -1116,7 +1193,7 @@ mod node {
fn get_os_error(error: &OsError) -> &'static str {
match error {
- OsError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
+ OsError::Permission(e) => get_permission_check_error_class(e),
OsError::InvalidUtf8(_) => "InvalidData",
OsError::EnvEmptyKey => "TypeError",
OsError::EnvInvalidKey(_) => "TypeError",
@@ -1144,6 +1221,18 @@ fn get_sync_fetch_error(error: &SyncFetchError) -> &'static str {
pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> {
deno_core::error::get_custom_error_class(e)
+ .or_else(|| {
+ e.downcast_ref::<ChildPermissionError>()
+ .map(get_child_permission_error)
+ })
+ .or_else(|| {
+ e.downcast_ref::<PermissionCheckError>()
+ .map(get_permission_check_error_class)
+ })
+ .or_else(|| {
+ e.downcast_ref::<PermissionError>()
+ .map(get_permission_error_class)
+ })
.or_else(|| e.downcast_ref::<FsError>().map(get_fs_error))
.or_else(|| {
e.downcast_ref::<node::BlocklistError>()
diff --git a/runtime/ops/fs_events.rs b/runtime/ops/fs_events.rs
index 648553376..c8e0228bc 100644
--- a/runtime/ops/fs_events.rs
+++ b/runtime/ops/fs_events.rs
@@ -114,7 +114,7 @@ pub enum FsEventsError {
#[error(transparent)]
Resource(deno_core::error::AnyError),
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] deno_permissions::PermissionCheckError),
#[error(transparent)]
Notify(#[from] NotifyError),
#[error(transparent)]
@@ -181,8 +181,7 @@ fn op_fs_events_open(
for path in &paths {
let path = state
.borrow_mut::<PermissionsContainer>()
- .check_read(path, "Deno.watchFs()")
- .map_err(FsEventsError::Permission)?;
+ .check_read(path, "Deno.watchFs()")?;
let watcher = state.borrow_mut::<WatcherState>();
watcher.watcher.watch(&path, recursive_mode)?;
diff --git a/runtime/ops/os/mod.rs b/runtime/ops/os/mod.rs
index 24b0389e1..9bee9d823 100644
--- a/runtime/ops/os/mod.rs
+++ b/runtime/ops/os/mod.rs
@@ -73,7 +73,7 @@ deno_core::extension!(
#[derive(Debug, thiserror::Error)]
pub enum OsError {
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] deno_permissions::PermissionCheckError),
#[error("File name or path {0:?} is not valid UTF-8")]
InvalidUtf8(std::ffi::OsString),
#[error("Key is an empty string.")]
@@ -94,8 +94,7 @@ fn op_exec_path(state: &mut OpState) -> Result<String, OsError> {
let current_exe = env::current_exe().unwrap();
state
.borrow_mut::<PermissionsContainer>()
- .check_read_blind(&current_exe, "exec_path", "Deno.execPath()")
- .map_err(OsError::Permission)?;
+ .check_read_blind(&current_exe, "exec_path", "Deno.execPath()")?;
// normalize path so it doesn't include '.' or '..' components
let path = normalize_path(current_exe);
@@ -111,10 +110,7 @@ fn op_set_env(
#[string] key: &str,
#[string] value: &str,
) -> Result<(), OsError> {
- state
- .borrow_mut::<PermissionsContainer>()
- .check_env(key)
- .map_err(OsError::Permission)?;
+ state.borrow_mut::<PermissionsContainer>().check_env(key)?;
if key.is_empty() {
return Err(OsError::EnvEmptyKey);
}
@@ -146,10 +142,7 @@ fn op_get_env(
let skip_permission_check = NODE_ENV_VAR_ALLOWLIST.contains(&key);
if !skip_permission_check {
- state
- .borrow_mut::<PermissionsContainer>()
- .check_env(&key)
- .map_err(OsError::Permission)?;
+ state.borrow_mut::<PermissionsContainer>().check_env(&key)?;
}
if key.is_empty() {
@@ -172,10 +165,7 @@ fn op_delete_env(
state: &mut OpState,
#[string] key: String,
) -> Result<(), OsError> {
- state
- .borrow_mut::<PermissionsContainer>()
- .check_env(&key)
- .map_err(OsError::Permission)?;
+ state.borrow_mut::<PermissionsContainer>().check_env(&key)?;
if key.is_empty() || key.contains(&['=', '\0'] as &[char]) {
return Err(OsError::EnvInvalidKey(key.to_string()));
}
@@ -240,8 +230,7 @@ fn op_network_interfaces(
) -> Result<Vec<NetworkInterface>, OsError> {
state
.borrow_mut::<PermissionsContainer>()
- .check_sys("networkInterfaces", "Deno.networkInterfaces()")
- .map_err(OsError::Permission)?;
+ .check_sys("networkInterfaces", "Deno.networkInterfaces()")?;
Ok(netif::up()?.map(NetworkInterface::from).collect())
}
diff --git a/runtime/ops/permissions.rs b/runtime/ops/permissions.rs
index 1dbc85259..9ad963f3b 100644
--- a/runtime/ops/permissions.rs
+++ b/runtime/ops/permissions.rs
@@ -2,8 +2,6 @@
use ::deno_permissions::PermissionState;
use ::deno_permissions::PermissionsContainer;
-use deno_core::error::custom_error;
-use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::OpState;
use serde::Deserialize;
@@ -47,12 +45,26 @@ impl From<PermissionState> for PermissionStatus {
}
}
+#[derive(Debug, thiserror::Error)]
+pub enum PermissionError {
+ #[error("No such permission name: {0}")]
+ InvalidPermissionName(String),
+ #[error("{0}")]
+ PathResolve(#[from] ::deno_permissions::PathResolveError),
+ #[error("{0}")]
+ NetDescriptorParse(#[from] ::deno_permissions::NetDescriptorParseError),
+ #[error("{0}")]
+ SysDescriptorParse(#[from] ::deno_permissions::SysDescriptorParseError),
+ #[error("{0}")]
+ RunDescriptorParse(#[from] ::deno_permissions::RunDescriptorParseError),
+}
+
#[op2]
#[serde]
pub fn op_query_permission(
state: &mut OpState,
#[serde] args: PermissionArgs,
-) -> Result<PermissionStatus, AnyError> {
+) -> Result<PermissionStatus, PermissionError> {
let permissions = state.borrow::<PermissionsContainer>();
let perm = match args.name.as_ref() {
"read" => permissions.query_read(args.path.as_deref())?,
@@ -62,12 +74,7 @@ pub fn op_query_permission(
"sys" => permissions.query_sys(args.kind.as_deref())?,
"run" => permissions.query_run(args.command.as_deref())?,
"ffi" => permissions.query_ffi(args.path.as_deref())?,
- n => {
- return Err(custom_error(
- "ReferenceError",
- format!("No such permission name: {n}"),
- ))
- }
+ _ => return Err(PermissionError::InvalidPermissionName(args.name)),
};
Ok(PermissionStatus::from(perm))
}
@@ -77,7 +84,7 @@ pub fn op_query_permission(
pub fn op_revoke_permission(
state: &mut OpState,
#[serde] args: PermissionArgs,
-) -> Result<PermissionStatus, AnyError> {
+) -> Result<PermissionStatus, PermissionError> {
let permissions = state.borrow::<PermissionsContainer>();
let perm = match args.name.as_ref() {
"read" => permissions.revoke_read(args.path.as_deref())?,
@@ -87,12 +94,7 @@ pub fn op_revoke_permission(
"sys" => permissions.revoke_sys(args.kind.as_deref())?,
"run" => permissions.revoke_run(args.command.as_deref())?,
"ffi" => permissions.revoke_ffi(args.path.as_deref())?,
- n => {
- return Err(custom_error(
- "ReferenceError",
- format!("No such permission name: {n}"),
- ))
- }
+ _ => return Err(PermissionError::InvalidPermissionName(args.name)),
};
Ok(PermissionStatus::from(perm))
}
@@ -102,7 +104,7 @@ pub fn op_revoke_permission(
pub fn op_request_permission(
state: &mut OpState,
#[serde] args: PermissionArgs,
-) -> Result<PermissionStatus, AnyError> {
+) -> Result<PermissionStatus, PermissionError> {
let permissions = state.borrow::<PermissionsContainer>();
let perm = match args.name.as_ref() {
"read" => permissions.request_read(args.path.as_deref())?,
@@ -112,12 +114,7 @@ pub fn op_request_permission(
"sys" => permissions.request_sys(args.kind.as_deref())?,
"run" => permissions.request_run(args.command.as_deref())?,
"ffi" => permissions.request_ffi(args.path.as_deref())?,
- n => {
- return Err(custom_error(
- "ReferenceError",
- format!("No such permission name: {n}"),
- ))
- }
+ _ => return Err(PermissionError::InvalidPermissionName(args.name)),
};
Ok(PermissionStatus::from(perm))
}
diff --git a/runtime/ops/process.rs b/runtime/ops/process.rs
index 28913f7c1..de3141f1f 100644
--- a/runtime/ops/process.rs
+++ b/runtime/ops/process.rs
@@ -206,7 +206,9 @@ pub enum ProcessError {
#[error("failed resolving cwd: {0}")]
FailedResolvingCwd(#[source] std::io::Error),
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(#[from] deno_permissions::PermissionCheckError),
+ #[error(transparent)]
+ RunPermission(#[from] CheckRunPermissionError),
#[error(transparent)]
Resource(deno_core::error::AnyError),
#[error(transparent)]
@@ -653,8 +655,7 @@ fn compute_run_cmd_and_check_permissions(
},
&run_env,
api_name,
- )
- .map_err(ProcessError::Permission)?;
+ )?;
Ok((cmd, run_env))
}
@@ -734,12 +735,20 @@ fn resolve_path(path: &str, cwd: &Path) -> PathBuf {
deno_path_util::normalize_path(cwd.join(path))
}
+#[derive(Debug, thiserror::Error)]
+pub enum CheckRunPermissionError {
+ #[error(transparent)]
+ Permission(#[from] deno_permissions::PermissionCheckError),
+ #[error("{0}")]
+ Other(deno_core::error::AnyError),
+}
+
fn check_run_permission(
state: &mut OpState,
cmd: &RunQueryDescriptor,
run_env: &RunEnv,
api_name: &str,
-) -> Result<(), deno_core::error::AnyError> {
+) -> Result<(), CheckRunPermissionError> {
let permissions = state.borrow_mut::<PermissionsContainer>();
if !permissions.query_run_all(api_name) {
// error the same on all platforms
@@ -747,14 +756,14 @@ fn check_run_permission(
if !env_var_names.is_empty() {
// we don't allow users to launch subprocesses with any LD_ or DYLD_*
// env vars set because this allows executing code (ex. LD_PRELOAD)
- return Err(deno_core::error::custom_error(
+ return Err(CheckRunPermissionError::Other(deno_core::error::custom_error(
"NotCapable",
format!(
"Requires --allow-all permissions to spawn subprocess with {} environment variable{}.",
env_var_names.join(", "),
if env_var_names.len() != 1 { "s" } else { "" }
)
- ));
+ )));
}
permissions.check_run(cmd, api_name)?;
}
@@ -1126,8 +1135,7 @@ mod deprecated {
) -> Result<(), ProcessError> {
state
.borrow_mut::<PermissionsContainer>()
- .check_run_all(&api_name)
- .map_err(ProcessError::Permission)?;
+ .check_run_all(&api_name)?;
kill(pid, &signal)
}
}
diff --git a/runtime/ops/worker_host.rs b/runtime/ops/worker_host.rs
index 82cc94924..521284a6a 100644
--- a/runtime/ops/worker_host.rs
+++ b/runtime/ops/worker_host.rs
@@ -123,7 +123,7 @@ pub enum CreateWorkerError {
#[error("Classic workers are not supported.")]
ClassicWorkers,
#[error(transparent)]
- Permission(deno_core::error::AnyError),
+ Permission(deno_permissions::ChildPermissionError),
#[error(transparent)]
ModuleResolution(#[from] deno_core::ModuleResolutionError),
#[error(transparent)]
diff --git a/runtime/permissions.rs b/runtime/permissions.rs
index fa62227e0..e8460e03f 100644
--- a/runtime/permissions.rs
+++ b/runtime/permissions.rs
@@ -3,9 +3,6 @@
use std::path::Path;
use std::path::PathBuf;
-use deno_core::anyhow::bail;
-use deno_core::anyhow::Context;
-use deno_core::error::AnyError;
use deno_path_util::normalize_path;
use deno_permissions::AllowRunDescriptor;
use deno_permissions::AllowRunDescriptorParseResult;
@@ -15,9 +12,12 @@ use deno_permissions::FfiDescriptor;
use deno_permissions::ImportDescriptor;
use deno_permissions::NetDescriptor;
use deno_permissions::PathQueryDescriptor;
+use deno_permissions::PathResolveError;
use deno_permissions::ReadDescriptor;
+use deno_permissions::RunDescriptorParseError;
use deno_permissions::RunQueryDescriptor;
use deno_permissions::SysDescriptor;
+use deno_permissions::SysDescriptorParseError;
use deno_permissions::WriteDescriptor;
#[derive(Debug)]
@@ -30,9 +30,9 @@ impl RuntimePermissionDescriptorParser {
Self { fs }
}
- fn resolve_from_cwd(&self, path: &str) -> Result<PathBuf, AnyError> {
+ fn resolve_from_cwd(&self, path: &str) -> Result<PathBuf, PathResolveError> {
if path.is_empty() {
- bail!("Empty path is not allowed");
+ return Err(PathResolveError::EmptyPath);
}
let path = Path::new(path);
if path.is_absolute() {
@@ -43,12 +43,11 @@ impl RuntimePermissionDescriptorParser {
}
}
- fn resolve_cwd(&self) -> Result<PathBuf, AnyError> {
+ fn resolve_cwd(&self) -> Result<PathBuf, PathResolveError> {
self
.fs
.cwd()
- .map_err(|e| e.into_io_error())
- .context("failed resolving cwd")
+ .map_err(|e| PathResolveError::CwdResolve(e.into_io_error()))
}
}
@@ -58,37 +57,37 @@ impl deno_permissions::PermissionDescriptorParser
fn parse_read_descriptor(
&self,
text: &str,
- ) -> Result<ReadDescriptor, AnyError> {
+ ) -> Result<ReadDescriptor, PathResolveError> {
Ok(ReadDescriptor(self.resolve_from_cwd(text)?))
}
fn parse_write_descriptor(
&self,
text: &str,
- ) -> Result<WriteDescriptor, AnyError> {
+ ) -> Result<WriteDescriptor, PathResolveError> {
Ok(WriteDescriptor(self.resolve_from_cwd(text)?))
}
fn parse_net_descriptor(
&self,
text: &str,
- ) -> Result<NetDescriptor, AnyError> {
+ ) -> Result<NetDescriptor, deno_permissions::NetDescriptorParseError> {
NetDescriptor::parse(text)
}
fn parse_import_descriptor(
&self,
text: &str,
- ) -> Result<ImportDescriptor, AnyError> {
+ ) -> Result<ImportDescriptor, deno_permissions::NetDescriptorParseError> {
ImportDescriptor::parse(text)
}
fn parse_env_descriptor(
&self,
text: &str,
- ) -> Result<EnvDescriptor, AnyError> {
+ ) -> Result<EnvDescriptor, deno_permissions::EnvDescriptorParseError> {
if text.is_empty() {
- Err(AnyError::msg("Empty env not allowed"))
+ Err(deno_permissions::EnvDescriptorParseError)
} else {
Ok(EnvDescriptor::new(text))
}
@@ -97,9 +96,9 @@ impl deno_permissions::PermissionDescriptorParser
fn parse_sys_descriptor(
&self,
text: &str,
- ) -> Result<deno_permissions::SysDescriptor, AnyError> {
+ ) -> Result<SysDescriptor, SysDescriptorParseError> {
if text.is_empty() {
- Err(AnyError::msg("Empty sys not allowed"))
+ Err(SysDescriptorParseError::Empty)
} else {
Ok(SysDescriptor::parse(text.to_string())?)
}
@@ -108,21 +107,21 @@ impl deno_permissions::PermissionDescriptorParser
fn parse_allow_run_descriptor(
&self,
text: &str,
- ) -> Result<AllowRunDescriptorParseResult, AnyError> {
+ ) -> Result<AllowRunDescriptorParseResult, RunDescriptorParseError> {
Ok(AllowRunDescriptor::parse(text, &self.resolve_cwd()?)?)
}
fn parse_deny_run_descriptor(
&self,
text: &str,
- ) -> Result<DenyRunDescriptor, AnyError> {
+ ) -> Result<DenyRunDescriptor, PathResolveError> {
Ok(DenyRunDescriptor::parse(text, &self.resolve_cwd()?))
}
fn parse_ffi_descriptor(
&self,
text: &str,
- ) -> Result<deno_permissions::FfiDescriptor, AnyError> {
+ ) -> Result<FfiDescriptor, PathResolveError> {
Ok(FfiDescriptor(self.resolve_from_cwd(text)?))
}
@@ -131,7 +130,7 @@ impl deno_permissions::PermissionDescriptorParser
fn parse_path_query(
&self,
path: &str,
- ) -> Result<PathQueryDescriptor, AnyError> {
+ ) -> Result<PathQueryDescriptor, PathResolveError> {
Ok(PathQueryDescriptor {
resolved: self.resolve_from_cwd(path)?,
requested: path.to_string(),
@@ -141,11 +140,12 @@ impl deno_permissions::PermissionDescriptorParser
fn parse_run_query(
&self,
requested: &str,
- ) -> Result<RunQueryDescriptor, AnyError> {
+ ) -> Result<RunQueryDescriptor, RunDescriptorParseError> {
if requested.is_empty() {
- bail!("Empty run query is not allowed");
+ return Err(RunDescriptorParseError::EmptyRunQuery);
}
RunQueryDescriptor::parse(requested)
+ .map_err(RunDescriptorParseError::PathResolve)
}
}
diff --git a/runtime/permissions/Cargo.toml b/runtime/permissions/Cargo.toml
index bfa37b489..f0b2e71b5 100644
--- a/runtime/permissions/Cargo.toml
+++ b/runtime/permissions/Cargo.toml
@@ -23,6 +23,7 @@ log.workspace = true
once_cell.workspace = true
percent-encoding = { version = "2.3.1", features = [] }
serde.workspace = true
+thiserror.workspace = true
which.workspace = true
[target.'cfg(windows)'.dependencies]
diff --git a/runtime/permissions/lib.rs b/runtime/permissions/lib.rs
index 84503f025..6480f4bf5 100644
--- a/runtime/permissions/lib.rs
+++ b/runtime/permissions/lib.rs
@@ -1,11 +1,5 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-use deno_core::anyhow::bail;
-use deno_core::anyhow::Context;
-use deno_core::error::custom_error;
-use deno_core::error::type_error;
-use deno_core::error::uri_error;
-use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex;
use deno_core::serde::de;
use deno_core::serde::Deserialize;
@@ -43,6 +37,21 @@ pub use prompter::PermissionPrompter;
pub use prompter::PromptCallback;
pub use prompter::PromptResponse;
+#[derive(Debug, thiserror::Error)]
+#[error("Requires {access}, {}", format_permission_error(.name))]
+pub struct PermissionDeniedError {
+ access: String,
+ name: &'static str,
+}
+
+fn format_permission_error(name: &'static str) -> String {
+ if is_standalone() {
+ format!("specify the required permissions during compilation using `deno compile --allow-{name}`")
+ } else {
+ format!("run again with the --allow-{name} flag")
+ }
+}
+
/// Fast exit from permission check routines if this permission
/// is in the "fully-granted" state.
macro_rules! skip_check_if_is_permission_fully_granted {
@@ -104,7 +113,10 @@ impl From<bool> for AllowPartial {
impl PermissionState {
#[inline(always)]
- fn log_perm_access(name: &str, info: impl FnOnce() -> Option<String>) {
+ fn log_perm_access(
+ name: &'static str,
+ info: impl FnOnce() -> Option<String>,
+ ) {
// Eliminates log overhead (when logging is disabled),
// log_enabled!(Debug) check in a hot path still has overhead
// TODO(AaronO): generalize or upstream this optimization
@@ -120,53 +132,47 @@ impl PermissionState {
}
}
- fn fmt_access(name: &str, info: impl FnOnce() -> Option<String>) -> String {
+ fn fmt_access(
+ name: &'static str,
+ info: impl FnOnce() -> Option<String>,
+ ) -> String {
format!(
"{} access{}",
name,
- info()
- .map(|info| { format!(" to {info}") })
- .unwrap_or_default(),
+ info().map(|info| format!(" to {info}")).unwrap_or_default(),
)
}
- fn error(name: &str, info: impl FnOnce() -> Option<String>) -> AnyError {
- let msg = if is_standalone() {
- format!(
- "Requires {}, specify the required permissions during compilation using `deno compile --allow-{}`",
- Self::fmt_access(name, info),
- name
- )
- } else {
- format!(
- "Requires {}, run again with the --allow-{} flag",
- Self::fmt_access(name, info),
- name
- )
- };
- custom_error("NotCapable", msg)
+ fn error(
+ name: &'static str,
+ info: impl FnOnce() -> Option<String>,
+ ) -> PermissionDeniedError {
+ PermissionDeniedError {
+ access: Self::fmt_access(name, info),
+ name,
+ }
}
/// Check the permission state. bool is whether a prompt was issued.
#[inline]
fn check(
self,
- name: &str,
+ name: &'static str,
api_name: Option<&str>,
info: Option<&str>,
prompt: bool,
- ) -> (Result<(), AnyError>, bool, bool) {
+ ) -> (Result<(), PermissionDeniedError>, bool, bool) {
self.check2(name, api_name, || info.map(|s| s.to_string()), prompt)
}
#[inline]
fn check2(
self,
- name: &str,
+ name: &'static str,
api_name: Option<&str>,
info: impl Fn() -> Option<String>,
prompt: bool,
- ) -> (Result<(), AnyError>, bool, bool) {
+ ) -> (Result<(), PermissionDeniedError>, bool, bool) {
match self {
PermissionState::Granted => {
Self::log_perm_access(name, info);
@@ -246,7 +252,7 @@ impl UnitPermission {
self.state
}
- pub fn check(&mut self) -> Result<(), AnyError> {
+ pub fn check(&mut self) -> Result<(), PermissionDeniedError> {
let (result, prompted, _is_allow_all) =
self.state.check(self.name, None, None, self.prompt);
if prompted {
@@ -262,7 +268,7 @@ impl UnitPermission {
fn create_child_permissions(
&mut self,
flag: ChildUnitPermissionArg,
- ) -> Result<Self, AnyError> {
+ ) -> Result<Self, ChildPermissionError> {
let mut perm = self.clone();
match flag {
ChildUnitPermissionArg::Inherit => {
@@ -270,7 +276,7 @@ impl UnitPermission {
}
ChildUnitPermissionArg::Granted => {
if self.check().is_err() {
- return Err(escalation_error());
+ return Err(ChildPermissionError::Escalation);
}
perm.state = PermissionState::Granted;
}
@@ -327,7 +333,7 @@ pub trait QueryDescriptor: Debug {
&self,
perm: &mut UnaryPermission<Self>,
api_name: Option<&str>,
- ) -> Result<(), AnyError>;
+ ) -> Result<(), PermissionDeniedError>;
fn matches_allow(&self, other: &Self::AllowDesc) -> bool;
fn matches_deny(&self, other: &Self::DenyDesc) -> bool;
@@ -402,7 +408,7 @@ impl<TQuery: QueryDescriptor> UnaryPermission<TQuery> {
pub fn check_all_api(
&mut self,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(None, false, api_name)
}
@@ -412,7 +418,7 @@ impl<TQuery: QueryDescriptor> UnaryPermission<TQuery> {
desc: Option<&TQuery>,
assert_non_partial: bool,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
let (result, prompted, is_allow_all) = self
.query_desc(desc, AllowPartial::from(!assert_non_partial))
.check2(
@@ -599,11 +605,14 @@ impl<TQuery: QueryDescriptor> UnaryPermission<TQuery> {
}
}
- fn create_child_permissions(
+ fn create_child_permissions<E>(
&mut self,
flag: ChildUnaryPermissionArg,
- parse: impl Fn(&str) -> Result<Option<TQuery::AllowDesc>, AnyError>,
- ) -> Result<UnaryPermission<TQuery>, AnyError> {
+ parse: impl Fn(&str) -> Result<Option<TQuery::AllowDesc>, E>,
+ ) -> Result<UnaryPermission<TQuery>, ChildPermissionError>
+ where
+ ChildPermissionError: From<E>,
+ {
let mut perms = Self::default();
match flag {
@@ -612,7 +621,7 @@ impl<TQuery: QueryDescriptor> UnaryPermission<TQuery> {
}
ChildUnaryPermissionArg::Granted => {
if self.check_all_api(None).is_err() {
- return Err(escalation_error());
+ return Err(ChildPermissionError::Escalation);
}
perms.granted_global = true;
}
@@ -621,13 +630,13 @@ impl<TQuery: QueryDescriptor> UnaryPermission<TQuery> {
perms.granted_list = granted_list
.iter()
.filter_map(|i| parse(i).transpose())
- .collect::<Result<_, _>>()?;
+ .collect::<Result<_, E>>()?;
if !perms.granted_list.iter().all(|desc| {
TQuery::from_allow(desc)
.check_in_permission(self, None)
.is_ok()
}) {
- return Err(escalation_error());
+ return Err(ChildPermissionError::Escalation);
}
}
}
@@ -698,7 +707,7 @@ impl QueryDescriptor for ReadQueryDescriptor {
&self,
perm: &mut UnaryPermission<Self>,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(perm);
perm.check_desc(Some(self), true, api_name)
}
@@ -761,7 +770,7 @@ impl QueryDescriptor for WriteQueryDescriptor {
&self,
perm: &mut UnaryPermission<Self>,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(perm);
perm.check_desc(Some(self), true, api_name)
}
@@ -796,22 +805,37 @@ pub enum Host {
Ip(IpAddr),
}
+#[derive(Debug, thiserror::Error)]
+pub enum HostParseError {
+ #[error("invalid IPv6 address: '{0}'")]
+ InvalidIpv6(String),
+ #[error("invalid host: '{0}'")]
+ InvalidHost(String),
+ #[error("invalid empty host: '{0}'")]
+ InvalidEmptyHost(String),
+ #[error("invalid host '{host}': {error}")]
+ Fqdn {
+ #[source]
+ error: fqdn::Error,
+ host: String,
+ },
+}
+
impl Host {
- // TODO(bartlomieju): rewrite to not use `AnyError` but a specific error implementations
- fn parse(s: &str) -> Result<Self, AnyError> {
+ fn parse(s: &str) -> Result<Self, HostParseError> {
if s.starts_with('[') && s.ends_with(']') {
let ip = s[1..s.len() - 1]
.parse::<Ipv6Addr>()
- .map_err(|_| uri_error(format!("invalid IPv6 address: '{s}'")))?;
+ .map_err(|_| HostParseError::InvalidIpv6(s.to_string()))?;
return Ok(Host::Ip(IpAddr::V6(ip)));
}
let (without_trailing_dot, has_trailing_dot) =
s.strip_suffix('.').map_or((s, false), |s| (s, true));
if let Ok(ip) = without_trailing_dot.parse::<IpAddr>() {
if has_trailing_dot {
- return Err(uri_error(format!(
- "invalid host: '{without_trailing_dot}'"
- )));
+ return Err(HostParseError::InvalidHost(
+ without_trailing_dot.to_string(),
+ ));
}
Ok(Host::Ip(ip))
} else {
@@ -822,11 +846,13 @@ impl Host {
};
let fqdn = {
use std::str::FromStr;
- FQDN::from_str(&lower)
- .with_context(|| format!("invalid host: '{s}'"))?
+ FQDN::from_str(&lower).map_err(|e| HostParseError::Fqdn {
+ error: e,
+ host: s.to_string(),
+ })?
};
if fqdn.is_root() {
- return Err(uri_error(format!("invalid empty host: '{s}'")));
+ return Err(HostParseError::InvalidEmptyHost(s.to_string()));
}
Ok(Host::Fqdn(fqdn))
}
@@ -870,7 +896,7 @@ impl QueryDescriptor for NetDescriptor {
&self,
perm: &mut UnaryPermission<Self>,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(perm);
perm.check_desc(Some(self), false, api_name)
}
@@ -896,39 +922,72 @@ impl QueryDescriptor for NetDescriptor {
}
}
-// TODO(bartlomieju): rewrite to not use `AnyError` but a specific error implementations
+#[derive(Debug, thiserror::Error)]
+pub enum NetDescriptorParseError {
+ #[error("invalid value '{0}': URLs are not supported, only domains and ips")]
+ Url(String),
+ #[error("invalid IPv6 address in '{hostname}': '{ip}'")]
+ InvalidIpv6 { hostname: String, ip: String },
+ #[error("invalid port in '{hostname}': '{port}'")]
+ InvalidPort { hostname: String, port: String },
+ #[error("invalid host: '{0}'")]
+ InvalidHost(String),
+ #[error("invalid empty port in '{0}'")]
+ EmptyPort(String),
+ #[error("ipv6 addresses must be enclosed in square brackets: '{0}'")]
+ Ipv6MissingSquareBrackets(String),
+ #[error("{0}")]
+ Host(#[from] HostParseError),
+}
+
+#[derive(Debug, thiserror::Error)]
+pub enum NetDescriptorFromUrlParseError {
+ #[error("Missing host in url: '{0}'")]
+ MissingHost(Url),
+ #[error("{0}")]
+ Host(#[from] HostParseError),
+}
+
impl NetDescriptor {
- pub fn parse(hostname: &str) -> Result<Self, AnyError> {
+ pub fn parse(hostname: &str) -> Result<Self, NetDescriptorParseError> {
if hostname.starts_with("http://") || hostname.starts_with("https://") {
- return Err(uri_error(format!("invalid value '{hostname}': URLs are not supported, only domains and ips")));
+ return Err(NetDescriptorParseError::Url(hostname.to_string()));
}
// If this is a IPv6 address enclosed in square brackets, parse it as such.
if hostname.starts_with('[') {
if let Some((ip, after)) = hostname.split_once(']') {
let ip = ip[1..].parse::<Ipv6Addr>().map_err(|_| {
- uri_error(format!("invalid IPv6 address in '{hostname}': '{ip}'"))
+ NetDescriptorParseError::InvalidIpv6 {
+ hostname: hostname.to_string(),
+ ip: ip.to_string(),
+ }
})?;
let port = if let Some(port) = after.strip_prefix(':') {
let port = port.parse::<u16>().map_err(|_| {
- uri_error(format!("invalid port in '{hostname}': '{port}'"))
+ NetDescriptorParseError::InvalidPort {
+ hostname: hostname.to_string(),
+ port: port.to_string(),
+ }
})?;
Some(port)
} else if after.is_empty() {
None
} else {
- return Err(uri_error(format!("invalid host: '{hostname}'")));
+ return Err(NetDescriptorParseError::InvalidHost(
+ hostname.to_string(),
+ ));
};
return Ok(NetDescriptor(Host::Ip(IpAddr::V6(ip)), port));
} else {
- return Err(uri_error(format!("invalid host: '{hostname}'")));
+ return Err(NetDescriptorParseError::InvalidHost(hostname.to_string()));
}
}
// Otherwise it is an IPv4 address or a FQDN with an optional port.
let (host, port) = match hostname.split_once(':') {
Some((_, "")) => {
- return Err(uri_error(format!("invalid empty port in '{hostname}'")));
+ return Err(NetDescriptorParseError::EmptyPort(hostname.to_string()));
}
Some((host, port)) => (host, port),
None => (hostname, ""),
@@ -943,11 +1002,14 @@ impl NetDescriptor {
// should give them a hint. There are always at least two colons in an
// IPv6 address, so this heuristic finds likely a bare IPv6 address.
if port.contains(':') {
- uri_error(format!(
- "ipv6 addresses must be enclosed in square brackets: '{hostname}'"
- ))
+ NetDescriptorParseError::Ipv6MissingSquareBrackets(
+ hostname.to_string(),
+ )
} else {
- uri_error(format!("invalid port in '{hostname}': '{port}'"))
+ NetDescriptorParseError::InvalidPort {
+ hostname: hostname.to_string(),
+ port: port.to_string(),
+ }
}
})?;
Some(port)
@@ -956,10 +1018,10 @@ impl NetDescriptor {
Ok(NetDescriptor(host, port))
}
- pub fn from_url(url: &Url) -> Result<Self, AnyError> {
- let host = url
- .host_str()
- .ok_or_else(|| type_error(format!("Missing host in url: '{}'", url)))?;
+ pub fn from_url(url: &Url) -> Result<Self, NetDescriptorFromUrlParseError> {
+ let host = url.host_str().ok_or_else(|| {
+ NetDescriptorFromUrlParseError::MissingHost(url.clone())
+ })?;
let host = Host::parse(host)?;
let port = url.port_or_known_default();
Ok(NetDescriptor(host, port))
@@ -1011,7 +1073,7 @@ impl QueryDescriptor for ImportDescriptor {
&self,
perm: &mut UnaryPermission<Self>,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(perm);
perm.check_desc(Some(self), false, api_name)
}
@@ -1038,15 +1100,19 @@ impl QueryDescriptor for ImportDescriptor {
}
impl ImportDescriptor {
- pub fn parse(specifier: &str) -> Result<Self, AnyError> {
+ pub fn parse(specifier: &str) -> Result<Self, NetDescriptorParseError> {
Ok(ImportDescriptor(NetDescriptor::parse(specifier)?))
}
- pub fn from_url(url: &Url) -> Result<Self, AnyError> {
+ pub fn from_url(url: &Url) -> Result<Self, NetDescriptorFromUrlParseError> {
Ok(ImportDescriptor(NetDescriptor::from_url(url)?))
}
}
+#[derive(Debug, thiserror::Error)]
+#[error("Empty env not allowed")]
+pub struct EnvDescriptorParseError;
+
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub struct EnvDescriptor(EnvVarName);
@@ -1084,7 +1150,7 @@ impl QueryDescriptor for EnvDescriptor {
&self,
perm: &mut UnaryPermission<Self>,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(perm);
perm.check_desc(Some(self), false, api_name)
}
@@ -1131,14 +1197,25 @@ pub enum RunQueryDescriptor {
Name(String),
}
+#[derive(Debug, thiserror::Error)]
+pub enum PathResolveError {
+ #[error("failed resolving cwd: {0}")]
+ CwdResolve(#[source] std::io::Error),
+ #[error("Empty path is not allowed")]
+ EmptyPath,
+}
+
impl RunQueryDescriptor {
- pub fn parse(requested: &str) -> Result<RunQueryDescriptor, AnyError> {
+ pub fn parse(
+ requested: &str,
+ ) -> Result<RunQueryDescriptor, PathResolveError> {
if is_path(requested) {
let path = PathBuf::from(requested);
let resolved = if path.is_absolute() {
normalize_path(path)
} else {
- let cwd = std::env::current_dir().context("failed resolving cwd")?;
+ let cwd =
+ std::env::current_dir().map_err(PathResolveError::CwdResolve)?;
normalize_path(cwd.join(path))
};
Ok(RunQueryDescriptor::Path {
@@ -1210,7 +1287,7 @@ impl QueryDescriptor for RunQueryDescriptor {
&self,
perm: &mut UnaryPermission<Self>,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(perm);
perm.check_desc(Some(self), false, api_name)
}
@@ -1280,6 +1357,16 @@ pub enum AllowRunDescriptorParseResult {
Descriptor(AllowRunDescriptor),
}
+#[derive(Debug, thiserror::Error)]
+pub enum RunDescriptorParseError {
+ #[error("{0}")]
+ Which(#[from] which::Error),
+ #[error("{0}")]
+ PathResolve(#[from] PathResolveError),
+ #[error("Empty run query is not allowed")]
+ EmptyRunQuery,
+}
+
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub struct AllowRunDescriptor(pub PathBuf);
@@ -1360,11 +1447,19 @@ fn denies_run_name(name: &str, cmd_path: &Path) -> bool {
suffix.is_empty() || suffix.starts_with('.')
}
+#[derive(Debug, thiserror::Error)]
+pub enum SysDescriptorParseError {
+ #[error("unknown system info kind \"{0}\"")]
+ InvalidKind(String), // TypeError
+ #[error("Empty sys not allowed")]
+ Empty, // Error
+}
+
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub struct SysDescriptor(String);
impl SysDescriptor {
- pub fn parse(kind: String) -> Result<Self, AnyError> {
+ pub fn parse(kind: String) -> Result<Self, SysDescriptorParseError> {
match kind.as_str() {
"hostname" | "osRelease" | "osUptime" | "loadavg"
| "networkInterfaces" | "systemMemoryInfo" | "uid" | "gid" | "cpus"
@@ -1374,7 +1469,7 @@ impl SysDescriptor {
// the underlying permission check changed to `userInfo` to better match the API,
// alias this to avoid breaking existing projects with `--allow-sys=username`
"username" => Ok(Self("userInfo".into())),
- _ => Err(type_error(format!("unknown system info kind \"{kind}\""))),
+ _ => Err(SysDescriptorParseError::InvalidKind(kind)),
}
}
@@ -1411,7 +1506,7 @@ impl QueryDescriptor for SysDescriptor {
&self,
perm: &mut UnaryPermission<Self>,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(perm);
perm.check_desc(Some(self), false, api_name)
}
@@ -1472,7 +1567,7 @@ impl QueryDescriptor for FfiQueryDescriptor {
&self,
perm: &mut UnaryPermission<Self>,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(perm);
perm.check_desc(Some(self), true, api_name)
}
@@ -1524,7 +1619,7 @@ impl UnaryPermission<ReadQueryDescriptor> {
&mut self,
desc: &ReadQueryDescriptor,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(Some(desc), true, api_name)
}
@@ -1534,12 +1629,15 @@ impl UnaryPermission<ReadQueryDescriptor> {
&mut self,
desc: &ReadQueryDescriptor,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(Some(desc), false, api_name)
}
- pub fn check_all(&mut self, api_name: Option<&str>) -> Result<(), AnyError> {
+ pub fn check_all(
+ &mut self,
+ api_name: Option<&str>,
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(None, false, api_name)
}
@@ -1568,7 +1666,7 @@ impl UnaryPermission<WriteQueryDescriptor> {
&mut self,
path: &WriteQueryDescriptor,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(Some(path), true, api_name)
}
@@ -1578,12 +1676,15 @@ impl UnaryPermission<WriteQueryDescriptor> {
&mut self,
path: &WriteQueryDescriptor,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(Some(path), false, api_name)
}
- pub fn check_all(&mut self, api_name: Option<&str>) -> Result<(), AnyError> {
+ pub fn check_all(
+ &mut self,
+ api_name: Option<&str>,
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(None, false, api_name)
}
@@ -1606,12 +1707,12 @@ impl UnaryPermission<NetDescriptor> {
&mut self,
host: &NetDescriptor,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(Some(host), false, api_name)
}
- pub fn check_all(&mut self) -> Result<(), AnyError> {
+ pub fn check_all(&mut self) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(None, false, None)
}
@@ -1637,12 +1738,12 @@ impl UnaryPermission<ImportDescriptor> {
&mut self,
host: &ImportDescriptor,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(Some(host), false, api_name)
}
- pub fn check_all(&mut self) -> Result<(), AnyError> {
+ pub fn check_all(&mut self) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(None, false, None)
}
@@ -1668,12 +1769,12 @@ impl UnaryPermission<EnvDescriptor> {
&mut self,
env: &str,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(Some(&EnvDescriptor::new(env)), false, api_name)
}
- pub fn check_all(&mut self) -> Result<(), AnyError> {
+ pub fn check_all(&mut self) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(None, false, None)
}
@@ -1696,12 +1797,12 @@ impl UnaryPermission<SysDescriptor> {
&mut self,
kind: &SysDescriptor,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(Some(kind), false, api_name)
}
- pub fn check_all(&mut self) -> Result<(), AnyError> {
+ pub fn check_all(&mut self) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(None, false, None)
}
@@ -1730,11 +1831,14 @@ impl UnaryPermission<RunQueryDescriptor> {
&mut self,
cmd: &RunQueryDescriptor,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
self.check_desc(Some(cmd), false, api_name)
}
- pub fn check_all(&mut self, api_name: Option<&str>) -> Result<(), AnyError> {
+ pub fn check_all(
+ &mut self,
+ api_name: Option<&str>,
+ ) -> Result<(), PermissionDeniedError> {
self.check_desc(None, false, api_name)
}
@@ -1777,7 +1881,7 @@ impl UnaryPermission<FfiQueryDescriptor> {
&mut self,
path: &FfiQueryDescriptor,
api_name: Option<&str>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(Some(path), true, api_name)
}
@@ -1785,12 +1889,12 @@ impl UnaryPermission<FfiQueryDescriptor> {
pub fn check_partial(
&mut self,
path: Option<&FfiQueryDescriptor>,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(path, false, None)
}
- pub fn check_all(&mut self) -> Result<(), AnyError> {
+ pub fn check_all(&mut self) -> Result<(), PermissionDeniedError> {
skip_check_if_is_permission_fully_granted!(self);
self.check_desc(None, false, Some("all"))
}
@@ -1830,23 +1934,39 @@ pub struct PermissionsOptions {
pub prompt: bool,
}
+#[derive(Debug, thiserror::Error)]
+pub enum PermissionsFromOptionsError {
+ #[error("{0}")]
+ PathResolve(#[from] PathResolveError),
+ #[error("{0}")]
+ SysDescriptorParse(#[from] SysDescriptorParseError),
+ #[error("{0}")]
+ NetDescriptorParse(#[from] NetDescriptorParseError),
+ #[error("{0}")]
+ EnvDescriptorParse(#[from] EnvDescriptorParseError),
+ #[error("{0}")]
+ RunDescriptorParse(#[from] RunDescriptorParseError),
+ #[error("Empty command name not allowed in --allow-run=...")]
+ RunEmptyCommandName,
+}
+
impl Permissions {
pub fn new_unary<TQuery>(
allow_list: Option<HashSet<TQuery::AllowDesc>>,
deny_list: Option<HashSet<TQuery::DenyDesc>>,
prompt: bool,
- ) -> Result<UnaryPermission<TQuery>, AnyError>
+ ) -> UnaryPermission<TQuery>
where
TQuery: QueryDescriptor,
{
- Ok(UnaryPermission::<TQuery> {
+ UnaryPermission::<TQuery> {
granted_global: global_from_option(allow_list.as_ref()),
granted_list: allow_list.unwrap_or_default(),
flag_denied_global: global_from_option(deny_list.as_ref()),
flag_denied_list: deny_list.unwrap_or_default(),
prompt,
..Default::default()
- })
+ }
}
pub const fn new_all(allow_state: bool) -> UnitPermission {
@@ -1862,15 +1982,15 @@ impl Permissions {
pub fn from_options(
parser: &dyn PermissionDescriptorParser,
opts: &PermissionsOptions,
- ) -> Result<Self, AnyError> {
+ ) -> Result<Self, PermissionsFromOptionsError> {
fn resolve_allow_run(
parser: &dyn PermissionDescriptorParser,
allow_run: &[String],
- ) -> Result<HashSet<AllowRunDescriptor>, AnyError> {
+ ) -> Result<HashSet<AllowRunDescriptor>, PermissionsFromOptionsError> {
let mut new_allow_run = HashSet::with_capacity(allow_run.len());
for unresolved in allow_run {
if unresolved.is_empty() {
- bail!("Empty command name not allowed in --allow-run=...")
+ return Err(PermissionsFromOptionsError::RunEmptyCommandName);
}
match parser.parse_allow_run_descriptor(unresolved)? {
AllowRunDescriptorParseResult::Descriptor(descriptor) => {
@@ -1889,10 +2009,13 @@ impl Permissions {
Ok(new_allow_run)
}
- fn parse_maybe_vec<T: Eq + PartialEq + Hash>(
+ fn parse_maybe_vec<T: Eq + PartialEq + Hash, E>(
items: Option<&[String]>,
- parse: impl Fn(&str) -> Result<T, AnyError>,
- ) -> Result<Option<HashSet<T>>, AnyError> {
+ parse: impl Fn(&str) -> Result<T, E>,
+ ) -> Result<Option<HashSet<T>>, PermissionsFromOptionsError>
+ where
+ PermissionsFromOptionsError: From<E>,
+ {
match items {
Some(items) => Ok(Some(
items
@@ -1944,14 +2067,14 @@ impl Permissions {
parser.parse_read_descriptor(item)
})?,
opts.prompt,
- )?,
+ ),
write: Permissions::new_unary(
parse_maybe_vec(opts.allow_write.as_deref(), |item| {
parser.parse_write_descriptor(item)
})?,
deny_write,
opts.prompt,
- )?,
+ ),
net: Permissions::new_unary(
parse_maybe_vec(opts.allow_net.as_deref(), |item| {
parser.parse_net_descriptor(item)
@@ -1960,7 +2083,7 @@ impl Permissions {
parser.parse_net_descriptor(item)
})?,
opts.prompt,
- )?,
+ ),
env: Permissions::new_unary(
parse_maybe_vec(opts.allow_env.as_deref(), |item| {
parser.parse_env_descriptor(item)
@@ -1969,7 +2092,7 @@ impl Permissions {
parser.parse_env_descriptor(text)
})?,
opts.prompt,
- )?,
+ ),
sys: Permissions::new_unary(
parse_maybe_vec(opts.allow_sys.as_deref(), |text| {
parser.parse_sys_descriptor(text)
@@ -1978,14 +2101,14 @@ impl Permissions {
parser.parse_sys_descriptor(text)
})?,
opts.prompt,
- )?,
+ ),
run: Permissions::new_unary(
allow_run,
parse_maybe_vec(opts.deny_run.as_deref(), |text| {
parser.parse_deny_run_descriptor(text)
})?,
opts.prompt,
- )?,
+ ),
ffi: Permissions::new_unary(
parse_maybe_vec(opts.allow_ffi.as_deref(), |text| {
parser.parse_ffi_descriptor(text)
@@ -1994,14 +2117,14 @@ impl Permissions {
parser.parse_ffi_descriptor(text)
})?,
opts.prompt,
- )?,
+ ),
import: Permissions::new_unary(
parse_maybe_vec(opts.allow_import.as_deref(), |item| {
parser.parse_import_descriptor(item)
})?,
None,
opts.prompt,
- )?,
+ ),
all: Permissions::new_all(opts.allow_all),
})
}
@@ -2033,14 +2156,14 @@ impl Permissions {
fn none(prompt: bool) -> Self {
Self {
- read: Permissions::new_unary(None, None, prompt).unwrap(),
- write: Permissions::new_unary(None, None, prompt).unwrap(),
- net: Permissions::new_unary(None, None, prompt).unwrap(),
- env: Permissions::new_unary(None, None, prompt).unwrap(),
- sys: Permissions::new_unary(None, None, prompt).unwrap(),
- run: Permissions::new_unary(None, None, prompt).unwrap(),
- ffi: Permissions::new_unary(None, None, prompt).unwrap(),
- import: Permissions::new_unary(None, None, prompt).unwrap(),
+ read: Permissions::new_unary(None, None, prompt),
+ write: Permissions::new_unary(None, None, prompt),
+ net: Permissions::new_unary(None, None, prompt),
+ env: Permissions::new_unary(None, None, prompt),
+ sys: Permissions::new_unary(None, None, prompt),
+ run: Permissions::new_unary(None, None, prompt),
+ ffi: Permissions::new_unary(None, None, prompt),
+ import: Permissions::new_unary(None, None, prompt),
all: Permissions::new_all(false),
}
}
@@ -2052,6 +2175,38 @@ pub enum CheckSpecifierKind {
Dynamic,
}
+#[derive(Debug, thiserror::Error)]
+pub enum ChildPermissionError {
+ #[error("Can't escalate parent thread permissions")]
+ Escalation,
+ #[error("{0}")]
+ PathResolve(#[from] PathResolveError),
+ #[error("{0}")]
+ NetDescriptorParse(#[from] NetDescriptorParseError),
+ #[error("{0}")]
+ EnvDescriptorParse(#[from] EnvDescriptorParseError),
+ #[error("{0}")]
+ SysDescriptorParse(#[from] SysDescriptorParseError),
+ #[error("{0}")]
+ RunDescriptorParse(#[from] RunDescriptorParseError),
+}
+
+#[derive(Debug, thiserror::Error)]
+pub enum PermissionCheckError {
+ #[error(transparent)]
+ PermissionDenied(#[from] PermissionDeniedError),
+ #[error("Invalid file path.\n Specifier: {0}")]
+ InvalidFilePath(Url),
+ #[error(transparent)]
+ NetDescriptorForUrlParse(#[from] NetDescriptorFromUrlParseError),
+ #[error(transparent)]
+ SysDescriptorParse(#[from] SysDescriptorParseError),
+ #[error(transparent)]
+ PathResolve(#[from] PathResolveError),
+ #[error(transparent)]
+ HostParse(#[from] HostParseError),
+}
+
/// Wrapper struct for `Permissions` that can be shared across threads.
///
/// We need a way to have internal mutability for permissions as they might get
@@ -2084,7 +2239,7 @@ impl PermissionsContainer {
pub fn create_child_permissions(
&self,
child_permissions_arg: ChildPermissionsArg,
- ) -> Result<PermissionsContainer, AnyError> {
+ ) -> Result<PermissionsContainer, ChildPermissionError> {
fn is_granted_unary(arg: &ChildUnaryPermissionArg) -> bool {
match arg {
ChildUnaryPermissionArg::Inherit | ChildUnaryPermissionArg::Granted => {
@@ -2122,48 +2277,71 @@ impl PermissionsContainer {
// WARNING: When adding a permission here, ensure it is handled
// in the worker_perms.all block above
- worker_perms.read = inner
- .read
- .create_child_permissions(child_permissions_arg.read, |text| {
- Ok(Some(self.descriptor_parser.parse_read_descriptor(text)?))
- })?;
- worker_perms.write = inner
- .write
- .create_child_permissions(child_permissions_arg.write, |text| {
- Ok(Some(self.descriptor_parser.parse_write_descriptor(text)?))
- })?;
- worker_perms.import = inner
- .import
- .create_child_permissions(child_permissions_arg.import, |text| {
- Ok(Some(self.descriptor_parser.parse_import_descriptor(text)?))
- })?;
- worker_perms.net = inner
- .net
- .create_child_permissions(child_permissions_arg.net, |text| {
- Ok(Some(self.descriptor_parser.parse_net_descriptor(text)?))
- })?;
- worker_perms.env = inner
- .env
- .create_child_permissions(child_permissions_arg.env, |text| {
- Ok(Some(self.descriptor_parser.parse_env_descriptor(text)?))
- })?;
- worker_perms.sys = inner
- .sys
- .create_child_permissions(child_permissions_arg.sys, |text| {
- Ok(Some(self.descriptor_parser.parse_sys_descriptor(text)?))
- })?;
+ worker_perms.read = inner.read.create_child_permissions(
+ child_permissions_arg.read,
+ |text| {
+ Ok::<_, PathResolveError>(Some(
+ self.descriptor_parser.parse_read_descriptor(text)?,
+ ))
+ },
+ )?;
+ worker_perms.write = inner.write.create_child_permissions(
+ child_permissions_arg.write,
+ |text| {
+ Ok::<_, PathResolveError>(Some(
+ self.descriptor_parser.parse_write_descriptor(text)?,
+ ))
+ },
+ )?;
+ worker_perms.import = inner.import.create_child_permissions(
+ child_permissions_arg.import,
+ |text| {
+ Ok::<_, NetDescriptorParseError>(Some(
+ self.descriptor_parser.parse_import_descriptor(text)?,
+ ))
+ },
+ )?;
+ worker_perms.net = inner.net.create_child_permissions(
+ child_permissions_arg.net,
+ |text| {
+ Ok::<_, NetDescriptorParseError>(Some(
+ self.descriptor_parser.parse_net_descriptor(text)?,
+ ))
+ },
+ )?;
+ worker_perms.env = inner.env.create_child_permissions(
+ child_permissions_arg.env,
+ |text| {
+ Ok::<_, EnvDescriptorParseError>(Some(
+ self.descriptor_parser.parse_env_descriptor(text)?,
+ ))
+ },
+ )?;
+ worker_perms.sys = inner.sys.create_child_permissions(
+ child_permissions_arg.sys,
+ |text| {
+ Ok::<_, SysDescriptorParseError>(Some(
+ self.descriptor_parser.parse_sys_descriptor(text)?,
+ ))
+ },
+ )?;
worker_perms.run = inner.run.create_child_permissions(
child_permissions_arg.run,
|text| match self.descriptor_parser.parse_allow_run_descriptor(text)? {
- AllowRunDescriptorParseResult::Unresolved(_) => Ok(None),
+ AllowRunDescriptorParseResult::Unresolved(_) => {
+ Ok::<_, RunDescriptorParseError>(None)
+ }
AllowRunDescriptorParseResult::Descriptor(desc) => Ok(Some(desc)),
},
)?;
- worker_perms.ffi = inner
- .ffi
- .create_child_permissions(child_permissions_arg.ffi, |text| {
- Ok(Some(self.descriptor_parser.parse_ffi_descriptor(text)?))
- })?;
+ worker_perms.ffi = inner.ffi.create_child_permissions(
+ child_permissions_arg.ffi,
+ |text| {
+ Ok::<_, PathResolveError>(Some(
+ self.descriptor_parser.parse_ffi_descriptor(text)?,
+ ))
+ },
+ )?;
Ok(PermissionsContainer::new(
self.descriptor_parser.clone(),
@@ -2176,7 +2354,7 @@ impl PermissionsContainer {
&self,
specifier: &ModuleSpecifier,
kind: CheckSpecifierKind,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionCheckError> {
let mut inner = self.inner.lock();
match specifier.scheme() {
"file" => {
@@ -2185,17 +2363,20 @@ impl PermissionsContainer {
}
match url_to_file_path(specifier) {
- Ok(path) => inner.read.check(
- &PathQueryDescriptor {
- requested: path.to_string_lossy().into_owned(),
- resolved: path,
- }
- .into_read(),
- Some("import()"),
- ),
- Err(_) => Err(uri_error(format!(
- "Invalid file path.\n Specifier: {specifier}"
- ))),
+ Ok(path) => inner
+ .read
+ .check(
+ &PathQueryDescriptor {
+ requested: path.to_string_lossy().into_owned(),
+ resolved: path,
+ }
+ .into_read(),
+ Some("import()"),
+ )
+ .map_err(PermissionCheckError::PermissionDenied),
+ Err(_) => {
+ Err(PermissionCheckError::InvalidFilePath(specifier.clone()))
+ }
}
}
"data" => Ok(()),
@@ -2220,7 +2401,7 @@ impl PermissionsContainer {
&self,
path: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
self.check_read_with_api_name(path, Some(api_name))
}
@@ -2230,7 +2411,7 @@ impl PermissionsContainer {
&self,
path: &str,
api_name: Option<&str>,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
let mut inner = self.inner.lock();
let inner = &mut inner.read;
if inner.is_allow_all() {
@@ -2248,7 +2429,7 @@ impl PermissionsContainer {
&self,
path: &'a Path,
api_name: Option<&str>,
- ) -> Result<Cow<'a, Path>, AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
let mut inner = self.inner.lock();
let inner = &mut inner.read;
if inner.is_allow_all() {
@@ -2272,7 +2453,7 @@ impl PermissionsContainer {
path: &Path,
display: &str,
api_name: &str,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionCheckError> {
let mut inner = self.inner.lock();
let inner = &mut inner.read;
skip_check_if_is_permission_fully_granted!(inner);
@@ -2283,12 +2464,17 @@ impl PermissionsContainer {
}
.into_read(),
Some(api_name),
- )
+ )?;
+ Ok(())
}
#[inline(always)]
- pub fn check_read_all(&self, api_name: &str) -> Result<(), AnyError> {
- self.inner.lock().read.check_all(Some(api_name))
+ pub fn check_read_all(
+ &self,
+ api_name: &str,
+ ) -> Result<(), PermissionCheckError> {
+ self.inner.lock().read.check_all(Some(api_name))?;
+ Ok(())
}
#[inline(always)]
@@ -2302,7 +2488,7 @@ impl PermissionsContainer {
&self,
path: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
self.check_write_with_api_name(path, Some(api_name))
}
@@ -2312,7 +2498,7 @@ impl PermissionsContainer {
&self,
path: &str,
api_name: Option<&str>,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
let mut inner = self.inner.lock();
let inner = &mut inner.write;
if inner.is_allow_all() {
@@ -2330,7 +2516,7 @@ impl PermissionsContainer {
&self,
path: &'a Path,
api_name: &str,
- ) -> Result<Cow<'a, Path>, AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
let mut inner = self.inner.lock();
let inner = &mut inner.write;
if inner.is_allow_all() {
@@ -2347,8 +2533,12 @@ impl PermissionsContainer {
}
#[inline(always)]
- pub fn check_write_all(&self, api_name: &str) -> Result<(), AnyError> {
- self.inner.lock().write.check_all(Some(api_name))
+ pub fn check_write_all(
+ &self,
+ api_name: &str,
+ ) -> Result<(), PermissionCheckError> {
+ self.inner.lock().write.check_all(Some(api_name))?;
+ Ok(())
}
/// As `check_write()`, but permission error messages will anonymize the path
@@ -2359,7 +2549,7 @@ impl PermissionsContainer {
path: &Path,
display: &str,
api_name: &str,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionCheckError> {
let mut inner = self.inner.lock();
let inner = &mut inner.write;
skip_check_if_is_permission_fully_granted!(inner);
@@ -2370,7 +2560,8 @@ impl PermissionsContainer {
}
.into_write(),
Some(api_name),
- )
+ )?;
+ Ok(())
}
#[inline(always)]
@@ -2378,7 +2569,7 @@ impl PermissionsContainer {
&mut self,
path: &str,
api_name: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
let mut inner = self.inner.lock();
let inner = &mut inner.write;
if inner.is_allow_all() {
@@ -2395,13 +2586,18 @@ impl PermissionsContainer {
&mut self,
cmd: &RunQueryDescriptor,
api_name: &str,
- ) -> Result<(), AnyError> {
- self.inner.lock().run.check(cmd, Some(api_name))
+ ) -> Result<(), PermissionCheckError> {
+ self.inner.lock().run.check(cmd, Some(api_name))?;
+ Ok(())
}
#[inline(always)]
- pub fn check_run_all(&mut self, api_name: &str) -> Result<(), AnyError> {
- self.inner.lock().run.check_all(Some(api_name))
+ pub fn check_run_all(
+ &mut self,
+ api_name: &str,
+ ) -> Result<(), PermissionCheckError> {
+ self.inner.lock().run.check_all(Some(api_name))?;
+ Ok(())
}
#[inline(always)]
@@ -2410,38 +2606,50 @@ impl PermissionsContainer {
}
#[inline(always)]
- pub fn check_sys(&self, kind: &str, api_name: &str) -> Result<(), AnyError> {
+ pub fn check_sys(
+ &self,
+ kind: &str,
+ api_name: &str,
+ ) -> Result<(), PermissionCheckError> {
self.inner.lock().sys.check(
&self.descriptor_parser.parse_sys_descriptor(kind)?,
Some(api_name),
- )
+ )?;
+ Ok(())
}
#[inline(always)]
- pub fn check_env(&mut self, var: &str) -> Result<(), AnyError> {
- self.inner.lock().env.check(var, None)
+ pub fn check_env(&mut self, var: &str) -> Result<(), PermissionCheckError> {
+ self.inner.lock().env.check(var, None)?;
+ Ok(())
}
#[inline(always)]
- pub fn check_env_all(&mut self) -> Result<(), AnyError> {
- self.inner.lock().env.check_all()
+ pub fn check_env_all(&mut self) -> Result<(), PermissionCheckError> {
+ self.inner.lock().env.check_all()?;
+ Ok(())
}
#[inline(always)]
- pub fn check_sys_all(&mut self) -> Result<(), AnyError> {
- self.inner.lock().sys.check_all()
+ pub fn check_sys_all(&mut self) -> Result<(), PermissionCheckError> {
+ self.inner.lock().sys.check_all()?;
+ Ok(())
}
#[inline(always)]
- pub fn check_ffi_all(&mut self) -> Result<(), AnyError> {
- self.inner.lock().ffi.check_all()
+ pub fn check_ffi_all(&mut self) -> Result<(), PermissionCheckError> {
+ self.inner.lock().ffi.check_all()?;
+ Ok(())
}
/// This checks to see if the allow-all flag was passed, not whether all
/// permissions are enabled!
#[inline(always)]
- pub fn check_was_allow_all_flag_passed(&mut self) -> Result<(), AnyError> {
- self.inner.lock().all.check()
+ pub fn check_was_allow_all_flag_passed(
+ &mut self,
+ ) -> Result<(), PermissionCheckError> {
+ self.inner.lock().all.check()?;
+ Ok(())
}
/// Checks special file access, returning the failed permission type if
@@ -2553,13 +2761,14 @@ impl PermissionsContainer {
&mut self,
url: &Url,
api_name: &str,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionCheckError> {
let mut inner = self.inner.lock();
if inner.net.is_allow_all() {
return Ok(());
}
let desc = self.descriptor_parser.parse_net_descriptor_from_url(url)?;
- inner.net.check(&desc, Some(api_name))
+ inner.net.check(&desc, Some(api_name))?;
+ Ok(())
}
#[inline(always)]
@@ -2567,17 +2776,21 @@ impl PermissionsContainer {
&mut self,
host: &(T, Option<u16>),
api_name: &str,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionCheckError> {
let mut inner = self.inner.lock();
let inner = &mut inner.net;
skip_check_if_is_permission_fully_granted!(inner);
let hostname = Host::parse(host.0.as_ref())?;
let descriptor = NetDescriptor(hostname, host.1);
- inner.check(&descriptor, Some(api_name))
+ inner.check(&descriptor, Some(api_name))?;
+ Ok(())
}
#[inline(always)]
- pub fn check_ffi(&mut self, path: &str) -> Result<PathBuf, AnyError> {
+ pub fn check_ffi(
+ &mut self,
+ path: &str,
+ ) -> Result<PathBuf, PermissionCheckError> {
let mut inner = self.inner.lock();
let inner = &mut inner.ffi;
if inner.is_allow_all() {
@@ -2591,14 +2804,15 @@ impl PermissionsContainer {
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
#[inline(always)]
- pub fn check_ffi_partial_no_path(&mut self) -> Result<(), AnyError> {
+ pub fn check_ffi_partial_no_path(
+ &mut self,
+ ) -> Result<(), PermissionCheckError> {
let mut inner = self.inner.lock();
let inner = &mut inner.ffi;
- if inner.is_allow_all() {
- Ok(())
- } else {
- inner.check_partial(None)
+ if !inner.is_allow_all() {
+ inner.check_partial(None)?;
}
+ Ok(())
}
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
@@ -2606,7 +2820,7 @@ impl PermissionsContainer {
pub fn check_ffi_partial_with_path(
&mut self,
path: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
let mut inner = self.inner.lock();
let inner = &mut inner.ffi;
if inner.is_allow_all() {
@@ -2624,7 +2838,7 @@ impl PermissionsContainer {
pub fn query_read(
&self,
path: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, PathResolveError> {
let inner = self.inner.lock();
let permission = &inner.read;
if permission.is_allow_all() {
@@ -2634,7 +2848,7 @@ impl PermissionsContainer {
permission.query(
path
.map(|path| {
- Result::<_, AnyError>::Ok(
+ Ok::<_, PathResolveError>(
self.descriptor_parser.parse_path_query(path)?.into_read(),
)
})
@@ -2648,7 +2862,7 @@ impl PermissionsContainer {
pub fn query_write(
&self,
path: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, PathResolveError> {
let inner = self.inner.lock();
let permission = &inner.write;
if permission.is_allow_all() {
@@ -2658,7 +2872,7 @@ impl PermissionsContainer {
permission.query(
path
.map(|path| {
- Result::<_, AnyError>::Ok(
+ Ok::<_, PathResolveError>(
self.descriptor_parser.parse_path_query(path)?.into_write(),
)
})
@@ -2672,7 +2886,7 @@ impl PermissionsContainer {
pub fn query_net(
&self,
host: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, NetDescriptorParseError> {
let inner = self.inner.lock();
let permission = &inner.net;
if permission.is_allow_all() {
@@ -2703,7 +2917,7 @@ impl PermissionsContainer {
pub fn query_sys(
&self,
kind: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, SysDescriptorParseError> {
let inner = self.inner.lock();
let permission = &inner.sys;
if permission.is_allow_all() {
@@ -2723,7 +2937,7 @@ impl PermissionsContainer {
pub fn query_run(
&self,
cmd: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, RunDescriptorParseError> {
let inner = self.inner.lock();
let permission = &inner.run;
if permission.is_allow_all() {
@@ -2743,7 +2957,7 @@ impl PermissionsContainer {
pub fn query_ffi(
&self,
path: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, PathResolveError> {
let inner = self.inner.lock();
let permission = &inner.ffi;
if permission.is_allow_all() {
@@ -2753,7 +2967,7 @@ impl PermissionsContainer {
permission.query(
path
.map(|path| {
- Result::<_, AnyError>::Ok(
+ Ok::<_, PathResolveError>(
self.descriptor_parser.parse_path_query(path)?.into_ffi(),
)
})
@@ -2769,12 +2983,12 @@ impl PermissionsContainer {
pub fn revoke_read(
&self,
path: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, PathResolveError> {
Ok(
self.inner.lock().read.revoke(
path
.map(|path| {
- Result::<_, AnyError>::Ok(
+ Ok::<_, PathResolveError>(
self.descriptor_parser.parse_path_query(path)?.into_read(),
)
})
@@ -2788,12 +3002,12 @@ impl PermissionsContainer {
pub fn revoke_write(
&self,
path: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, PathResolveError> {
Ok(
self.inner.lock().write.revoke(
path
.map(|path| {
- Result::<_, AnyError>::Ok(
+ Ok::<_, PathResolveError>(
self.descriptor_parser.parse_path_query(path)?.into_write(),
)
})
@@ -2807,7 +3021,7 @@ impl PermissionsContainer {
pub fn revoke_net(
&self,
host: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, NetDescriptorParseError> {
Ok(
self.inner.lock().net.revoke(
match host {
@@ -2828,7 +3042,7 @@ impl PermissionsContainer {
pub fn revoke_sys(
&self,
kind: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, SysDescriptorParseError> {
Ok(
self.inner.lock().sys.revoke(
kind
@@ -2843,7 +3057,7 @@ impl PermissionsContainer {
pub fn revoke_run(
&self,
cmd: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, RunDescriptorParseError> {
Ok(
self.inner.lock().run.revoke(
cmd
@@ -2858,12 +3072,12 @@ impl PermissionsContainer {
pub fn revoke_ffi(
&self,
path: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, PathResolveError> {
Ok(
self.inner.lock().ffi.revoke(
path
.map(|path| {
- Result::<_, AnyError>::Ok(
+ Ok::<_, PathResolveError>(
self.descriptor_parser.parse_path_query(path)?.into_ffi(),
)
})
@@ -2879,12 +3093,12 @@ impl PermissionsContainer {
pub fn request_read(
&self,
path: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, PathResolveError> {
Ok(
self.inner.lock().read.request(
path
.map(|path| {
- Result::<_, AnyError>::Ok(
+ Ok::<_, PathResolveError>(
self.descriptor_parser.parse_path_query(path)?.into_read(),
)
})
@@ -2898,12 +3112,12 @@ impl PermissionsContainer {
pub fn request_write(
&self,
path: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, PathResolveError> {
Ok(
self.inner.lock().write.request(
path
.map(|path| {
- Result::<_, AnyError>::Ok(
+ Ok::<_, PathResolveError>(
self.descriptor_parser.parse_path_query(path)?.into_write(),
)
})
@@ -2917,7 +3131,7 @@ impl PermissionsContainer {
pub fn request_net(
&self,
host: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, NetDescriptorParseError> {
Ok(
self.inner.lock().net.request(
match host {
@@ -2938,7 +3152,7 @@ impl PermissionsContainer {
pub fn request_sys(
&self,
kind: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, SysDescriptorParseError> {
Ok(
self.inner.lock().sys.request(
kind
@@ -2953,7 +3167,7 @@ impl PermissionsContainer {
pub fn request_run(
&self,
cmd: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, RunDescriptorParseError> {
Ok(
self.inner.lock().run.request(
cmd
@@ -2968,12 +3182,12 @@ impl PermissionsContainer {
pub fn request_ffi(
&self,
path: Option<&str>,
- ) -> Result<PermissionState, AnyError> {
+ ) -> Result<PermissionState, PathResolveError> {
Ok(
self.inner.lock().ffi.request(
path
.map(|path| {
- Result::<_, AnyError>::Ok(
+ Ok::<_, PathResolveError>(
self.descriptor_parser.parse_path_query(path)?.into_ffi(),
)
})
@@ -3009,10 +3223,6 @@ fn global_from_option<T>(flag: Option<&HashSet<T>>) -> bool {
matches!(flag, Some(v) if v.is_empty())
}
-fn escalation_error() -> AnyError {
- custom_error("NotCapable", "Can't escalate parent thread permissions")
-}
-
#[derive(Debug, Eq, PartialEq)]
pub enum ChildUnitPermissionArg {
Inherit,
@@ -3273,65 +3483,73 @@ pub trait PermissionDescriptorParser: Debug + Send + Sync {
fn parse_read_descriptor(
&self,
text: &str,
- ) -> Result<ReadDescriptor, AnyError>;
+ ) -> Result<ReadDescriptor, PathResolveError>;
fn parse_write_descriptor(
&self,
text: &str,
- ) -> Result<WriteDescriptor, AnyError>;
+ ) -> Result<WriteDescriptor, PathResolveError>;
- fn parse_net_descriptor(&self, text: &str)
- -> Result<NetDescriptor, AnyError>;
+ fn parse_net_descriptor(
+ &self,
+ text: &str,
+ ) -> Result<NetDescriptor, NetDescriptorParseError>;
fn parse_net_descriptor_from_url(
&self,
url: &Url,
- ) -> Result<NetDescriptor, AnyError> {
+ ) -> Result<NetDescriptor, NetDescriptorFromUrlParseError> {
NetDescriptor::from_url(url)
}
fn parse_import_descriptor(
&self,
text: &str,
- ) -> Result<ImportDescriptor, AnyError>;
+ ) -> Result<ImportDescriptor, NetDescriptorParseError>;
fn parse_import_descriptor_from_url(
&self,
url: &Url,
- ) -> Result<ImportDescriptor, AnyError> {
+ ) -> Result<ImportDescriptor, NetDescriptorFromUrlParseError> {
ImportDescriptor::from_url(url)
}
- fn parse_env_descriptor(&self, text: &str)
- -> Result<EnvDescriptor, AnyError>;
+ fn parse_env_descriptor(
+ &self,
+ text: &str,
+ ) -> Result<EnvDescriptor, EnvDescriptorParseError>;
- fn parse_sys_descriptor(&self, text: &str)
- -> Result<SysDescriptor, AnyError>;
+ fn parse_sys_descriptor(
+ &self,
+ text: &str,
+ ) -> Result<SysDescriptor, SysDescriptorParseError>;
fn parse_allow_run_descriptor(
&self,
text: &str,
- ) -> Result<AllowRunDescriptorParseResult, AnyError>;
+ ) -> Result<AllowRunDescriptorParseResult, RunDescriptorParseError>;
fn parse_deny_run_descriptor(
&self,
text: &str,
- ) -> Result<DenyRunDescriptor, AnyError>;
+ ) -> Result<DenyRunDescriptor, PathResolveError>;
- fn parse_ffi_descriptor(&self, text: &str)
- -> Result<FfiDescriptor, AnyError>;
+ fn parse_ffi_descriptor(
+ &self,
+ text: &str,
+ ) -> Result<FfiDescriptor, PathResolveError>;
// queries
fn parse_path_query(
&self,
path: &str,
- ) -> Result<PathQueryDescriptor, AnyError>;
+ ) -> Result<PathQueryDescriptor, PathResolveError>;
fn parse_run_query(
&self,
requested: &str,
- ) -> Result<RunQueryDescriptor, AnyError>;
+ ) -> Result<RunQueryDescriptor, RunDescriptorParseError>;
}
static IS_STANDALONE: AtomicFlag = AtomicFlag::lowered();
@@ -3374,49 +3592,49 @@ mod tests {
fn parse_read_descriptor(
&self,
text: &str,
- ) -> Result<ReadDescriptor, AnyError> {
+ ) -> Result<ReadDescriptor, PathResolveError> {
Ok(ReadDescriptor(self.join_path_with_root(text)))
}
fn parse_write_descriptor(
&self,
text: &str,
- ) -> Result<WriteDescriptor, AnyError> {
+ ) -> Result<WriteDescriptor, PathResolveError> {
Ok(WriteDescriptor(self.join_path_with_root(text)))
}
fn parse_net_descriptor(
&self,
text: &str,
- ) -> Result<NetDescriptor, AnyError> {
+ ) -> Result<NetDescriptor, NetDescriptorParseError> {
NetDescriptor::parse(text)
}
fn parse_import_descriptor(
&self,
text: &str,
- ) -> Result<ImportDescriptor, AnyError> {
+ ) -> Result<ImportDescriptor, NetDescriptorParseError> {
ImportDescriptor::parse(text)
}
fn parse_env_descriptor(
&self,
text: &str,
- ) -> Result<EnvDescriptor, AnyError> {
+ ) -> Result<EnvDescriptor, EnvDescriptorParseError> {
Ok(EnvDescriptor::new(text))
}
fn parse_sys_descriptor(
&self,
text: &str,
- ) -> Result<SysDescriptor, AnyError> {
+ ) -> Result<SysDescriptor, SysDescriptorParseError> {
SysDescriptor::parse(text.to_string())
}
fn parse_allow_run_descriptor(
&self,
text: &str,
- ) -> Result<AllowRunDescriptorParseResult, AnyError> {
+ ) -> Result<AllowRunDescriptorParseResult, RunDescriptorParseError> {
Ok(AllowRunDescriptorParseResult::Descriptor(
AllowRunDescriptor(self.join_path_with_root(text)),
))
@@ -3425,7 +3643,7 @@ mod tests {
fn parse_deny_run_descriptor(
&self,
text: &str,
- ) -> Result<DenyRunDescriptor, AnyError> {
+ ) -> Result<DenyRunDescriptor, PathResolveError> {
if text.contains("/") {
Ok(DenyRunDescriptor::Path(self.join_path_with_root(text)))
} else {
@@ -3436,14 +3654,14 @@ mod tests {
fn parse_ffi_descriptor(
&self,
text: &str,
- ) -> Result<FfiDescriptor, AnyError> {
+ ) -> Result<FfiDescriptor, PathResolveError> {
Ok(FfiDescriptor(self.join_path_with_root(text)))
}
fn parse_path_query(
&self,
path: &str,
- ) -> Result<PathQueryDescriptor, AnyError> {
+ ) -> Result<PathQueryDescriptor, PathResolveError> {
Ok(PathQueryDescriptor {
resolved: self.join_path_with_root(path),
requested: path.to_string(),
@@ -3453,8 +3671,8 @@ mod tests {
fn parse_run_query(
&self,
requested: &str,
- ) -> Result<RunQueryDescriptor, AnyError> {
- RunQueryDescriptor::parse(requested)
+ ) -> Result<RunQueryDescriptor, RunDescriptorParseError> {
+ RunQueryDescriptor::parse(requested).map_err(Into::into)
}
}
@@ -4335,7 +4553,6 @@ mod tests {
None,
false,
)
- .unwrap()
};
prompt_value.set(true);
@@ -4562,13 +4779,12 @@ mod tests {
.lock()
.clone(),
Permissions {
- env: Permissions::new_unary(Some(HashSet::new()), None, false).unwrap(),
+ env: Permissions::new_unary(Some(HashSet::new()), None, false),
net: Permissions::new_unary(
Some(HashSet::from([NetDescriptor::parse("foo").unwrap()])),
None,
false
- )
- .unwrap(),
+ ),
..Permissions::none_without_prompt()
}
);
diff --git a/runtime/permissions/prompter.rs b/runtime/permissions/prompter.rs
index b582b4f53..168a845a2 100644
--- a/runtime/permissions/prompter.rs
+++ b/runtime/permissions/prompter.rs
@@ -1,6 +1,5 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex;
use deno_terminal::colors;
use once_cell::sync::Lazy;
@@ -101,8 +100,7 @@ pub struct TtyPrompter;
fn clear_stdin(
_stdin_lock: &mut StdinLock,
_stderr_lock: &mut StderrLock,
-) -> Result<(), AnyError> {
- use deno_core::anyhow::bail;
+) -> Result<(), std::io::Error> {
use std::mem::MaybeUninit;
const STDIN_FD: i32 = 0;
@@ -117,7 +115,10 @@ fn clear_stdin(
loop {
let r = libc::tcflush(STDIN_FD, libc::TCIFLUSH);
if r != 0 {
- bail!("clear_stdin failed (tcflush)");
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::Other,
+ "clear_stdin failed (tcflush)",
+ ));
}
// Initialize timeout for select to be 100ms
@@ -137,7 +138,10 @@ fn clear_stdin(
// Check if select returned an error
if r < 0 {
- bail!("clear_stdin failed (select)");
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::Other,
+ "clear_stdin failed (select)",
+ ));
}
// Check if select returned due to timeout (stdin is quiescent)
@@ -156,8 +160,7 @@ fn clear_stdin(
fn clear_stdin(
stdin_lock: &mut StdinLock,
stderr_lock: &mut StderrLock,
-) -> Result<(), AnyError> {
- use deno_core::anyhow::bail;
+) -> Result<(), std::io::Error> {
use winapi::shared::minwindef::TRUE;
use winapi::shared::minwindef::UINT;
use winapi::shared::minwindef::WORD;
@@ -194,18 +197,23 @@ fn clear_stdin(
return Ok(());
- unsafe fn flush_input_buffer(stdin: HANDLE) -> Result<(), AnyError> {
+ unsafe fn flush_input_buffer(stdin: HANDLE) -> Result<(), std::io::Error> {
let success = FlushConsoleInputBuffer(stdin);
if success != TRUE {
- bail!(
- "Could not flush the console input buffer: {}",
- std::io::Error::last_os_error()
- )
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::Other,
+ format!(
+ "Could not flush the console input buffer: {}",
+ std::io::Error::last_os_error()
+ ),
+ ));
}
Ok(())
}
- unsafe fn emulate_enter_key_press(stdin: HANDLE) -> Result<(), AnyError> {
+ unsafe fn emulate_enter_key_press(
+ stdin: HANDLE,
+ ) -> Result<(), std::io::Error> {
// https://github.com/libuv/libuv/blob/a39009a5a9252a566ca0704d02df8dabc4ce328f/src/win/tty.c#L1121-L1131
let mut input_record: INPUT_RECORD = std::mem::zeroed();
input_record.EventType = KEY_EVENT;
@@ -220,34 +228,43 @@ fn clear_stdin(
let success =
WriteConsoleInputW(stdin, &input_record, 1, &mut record_written);
if success != TRUE {
- bail!(
- "Could not emulate enter key press: {}",
- std::io::Error::last_os_error()
- );
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::Other,
+ format!(
+ "Could not emulate enter key press: {}",
+ std::io::Error::last_os_error()
+ ),
+ ));
}
Ok(())
}
- unsafe fn is_input_buffer_empty(stdin: HANDLE) -> Result<bool, AnyError> {
+ unsafe fn is_input_buffer_empty(
+ stdin: HANDLE,
+ ) -> Result<bool, std::io::Error> {
let mut buffer = Vec::with_capacity(1);
let mut events_read = 0;
let success =
PeekConsoleInputW(stdin, buffer.as_mut_ptr(), 1, &mut events_read);
if success != TRUE {
- bail!(
- "Could not peek the console input buffer: {}",
- std::io::Error::last_os_error()
- )
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::Other,
+ format!(
+ "Could not peek the console input buffer: {}",
+ std::io::Error::last_os_error()
+ ),
+ ));
}
Ok(events_read == 0)
}
- fn move_cursor_up(stderr_lock: &mut StderrLock) -> Result<(), AnyError> {
- write!(stderr_lock, "\x1B[1A")?;
- Ok(())
+ fn move_cursor_up(
+ stderr_lock: &mut StderrLock,
+ ) -> Result<(), std::io::Error> {
+ write!(stderr_lock, "\x1B[1A")
}
- fn read_stdin_line(stdin_lock: &mut StdinLock) -> Result<(), AnyError> {
+ fn read_stdin_line(stdin_lock: &mut StdinLock) -> Result<(), std::io::Error> {
let mut input = String::new();
stdin_lock.read_line(&mut input)?;
Ok(())
diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs
index 041132f97..0d81af6e7 100644
--- a/runtime/snapshot.rs
+++ b/runtime/snapshot.rs
@@ -5,12 +5,12 @@ use crate::ops::bootstrap::SnapshotOptions;
use crate::shared::maybe_transpile_source;
use crate::shared::runtime;
use deno_cache::SqliteBackedCache;
-use deno_core::error::AnyError;
use deno_core::snapshot::*;
use deno_core::v8;
use deno_core::Extension;
use deno_http::DefaultHttpPropertyExtractor;
use deno_io::fs::FsError;
+use deno_permissions::PermissionCheckError;
use std::borrow::Cow;
use std::io::Write;
use std::path::Path;
@@ -26,7 +26,7 @@ impl deno_websocket::WebSocketPermissions for Permissions {
&mut self,
_url: &deno_core::url::Url,
_api_name: &str,
- ) -> Result<(), deno_core::error::AnyError> {
+ ) -> Result<(), PermissionCheckError> {
unreachable!("snapshotting!")
}
}
@@ -42,7 +42,7 @@ impl deno_fetch::FetchPermissions for Permissions {
&mut self,
_url: &deno_core::url::Url,
_api_name: &str,
- ) -> Result<(), deno_core::error::AnyError> {
+ ) -> Result<(), PermissionCheckError> {
unreachable!("snapshotting!")
}
@@ -50,28 +50,26 @@ impl deno_fetch::FetchPermissions for Permissions {
&mut self,
_p: &'a Path,
_api_name: &str,
- ) -> Result<Cow<'a, Path>, AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
unreachable!("snapshotting!")
}
}
impl deno_ffi::FfiPermissions for Permissions {
- fn check_partial_no_path(
- &mut self,
- ) -> Result<(), deno_core::error::AnyError> {
+ fn check_partial_no_path(&mut self) -> Result<(), PermissionCheckError> {
unreachable!("snapshotting!")
}
fn check_partial_with_path(
&mut self,
_path: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
unreachable!("snapshotting!")
}
}
impl deno_napi::NapiPermissions for Permissions {
- fn check(&mut self, _path: &str) -> std::result::Result<PathBuf, AnyError> {
+ fn check(&mut self, _path: &str) -> Result<PathBuf, PermissionCheckError> {
unreachable!("snapshotting!")
}
}
@@ -81,20 +79,20 @@ impl deno_node::NodePermissions for Permissions {
&mut self,
_url: &deno_core::url::Url,
_api_name: &str,
- ) -> Result<(), deno_core::error::AnyError> {
+ ) -> Result<(), PermissionCheckError> {
unreachable!("snapshotting!")
}
fn check_read_path<'a>(
&mut self,
_path: &'a Path,
- ) -> Result<Cow<'a, Path>, AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
unreachable!("snapshotting!")
}
fn check_read_with_api_name(
&mut self,
_p: &str,
_api_name: Option<&str>,
- ) -> Result<PathBuf, deno_core::error::AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
unreachable!("snapshotting!")
}
fn query_read_all(&mut self) -> bool {
@@ -104,14 +102,14 @@ impl deno_node::NodePermissions for Permissions {
&mut self,
_p: &str,
_api_name: Option<&str>,
- ) -> Result<PathBuf, deno_core::error::AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
unreachable!("snapshotting!")
}
fn check_sys(
&mut self,
_kind: &str,
_api_name: &str,
- ) -> Result<(), deno_core::error::AnyError> {
+ ) -> Result<(), PermissionCheckError> {
unreachable!("snapshotting!")
}
}
@@ -121,7 +119,7 @@ impl deno_net::NetPermissions for Permissions {
&mut self,
_host: &(T, Option<u16>),
_api_name: &str,
- ) -> Result<(), deno_core::error::AnyError> {
+ ) -> Result<(), PermissionCheckError> {
unreachable!("snapshotting!")
}
@@ -129,7 +127,7 @@ impl deno_net::NetPermissions for Permissions {
&mut self,
_p: &str,
_api_name: &str,
- ) -> Result<PathBuf, deno_core::error::AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
unreachable!("snapshotting!")
}
@@ -137,7 +135,7 @@ impl deno_net::NetPermissions for Permissions {
&mut self,
_p: &str,
_api_name: &str,
- ) -> Result<PathBuf, deno_core::error::AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
unreachable!("snapshotting!")
}
@@ -145,7 +143,7 @@ impl deno_net::NetPermissions for Permissions {
&mut self,
_p: &'a Path,
_api_name: &str,
- ) -> Result<std::borrow::Cow<'a, Path>, AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
unreachable!("snapshotting!")
}
}
@@ -158,7 +156,7 @@ impl deno_fs::FsPermissions for Permissions {
_write: bool,
_path: &'a Path,
_api_name: &str,
- ) -> Result<std::borrow::Cow<'a, Path>, FsError> {
+ ) -> Result<Cow<'a, Path>, FsError> {
unreachable!("snapshotting!")
}
@@ -166,11 +164,14 @@ impl deno_fs::FsPermissions for Permissions {
&mut self,
_path: &str,
_api_name: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
unreachable!("snapshotting!")
}
- fn check_read_all(&mut self, _api_name: &str) -> Result<(), AnyError> {
+ fn check_read_all(
+ &mut self,
+ _api_name: &str,
+ ) -> Result<(), PermissionCheckError> {
unreachable!("snapshotting!")
}
@@ -179,7 +180,7 @@ impl deno_fs::FsPermissions for Permissions {
_path: &Path,
_display: &str,
_api_name: &str,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionCheckError> {
unreachable!("snapshotting!")
}
@@ -187,7 +188,7 @@ impl deno_fs::FsPermissions for Permissions {
&mut self,
_path: &str,
_api_name: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
unreachable!("snapshotting!")
}
@@ -195,11 +196,14 @@ impl deno_fs::FsPermissions for Permissions {
&mut self,
_path: &str,
_api_name: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
unreachable!("snapshotting!")
}
- fn check_write_all(&mut self, _api_name: &str) -> Result<(), AnyError> {
+ fn check_write_all(
+ &mut self,
+ _api_name: &str,
+ ) -> Result<(), PermissionCheckError> {
unreachable!("snapshotting!")
}
@@ -208,7 +212,7 @@ impl deno_fs::FsPermissions for Permissions {
_path: &Path,
_display: &str,
_api_name: &str,
- ) -> Result<(), AnyError> {
+ ) -> Result<(), PermissionCheckError> {
unreachable!("snapshotting!")
}
@@ -216,7 +220,7 @@ impl deno_fs::FsPermissions for Permissions {
&mut self,
_path: &'a Path,
_api_name: &str,
- ) -> Result<std::borrow::Cow<'a, Path>, AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
unreachable!("snapshotting!")
}
@@ -224,7 +228,7 @@ impl deno_fs::FsPermissions for Permissions {
&mut self,
_path: &'a Path,
_api_name: &str,
- ) -> Result<std::borrow::Cow<'a, Path>, AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
unreachable!("snapshotting!")
}
}
@@ -234,7 +238,7 @@ impl deno_kv::sqlite::SqliteDbHandlerPermissions for Permissions {
&mut self,
_path: &str,
_api_name: &str,
- ) -> Result<PathBuf, AnyError> {
+ ) -> Result<PathBuf, PermissionCheckError> {
unreachable!("snapshotting!")
}
@@ -242,7 +246,7 @@ impl deno_kv::sqlite::SqliteDbHandlerPermissions for Permissions {
&mut self,
_path: &'a Path,
_api_name: &str,
- ) -> Result<Cow<'a, Path>, AnyError> {
+ ) -> Result<Cow<'a, Path>, PermissionCheckError> {
unreachable!("snapshotting!")
}
}