summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2024-06-06 23:37:53 -0400
committerGitHub <noreply@github.com>2024-06-06 23:37:53 -0400
commit386d5c8310891c5dc9627abbf2374e60bb4e50d2 (patch)
tree920367bb6e14a5d259a01765962e93ff991c1fa0 /ext
parenta17794d5cf0c8d1ecc624c490071e5b3a5856bc7 (diff)
refactor: remove `PermissionsContainer` in deno_runtime (#24119)
Also removes permissions being passed in for node resolution. It was completely useless because we only checked it for reading package.json files, but Deno reading package.json files for resolution is perfectly fine. My guess is this is also a perf improvement because Deno is doing less work.
Diffstat (limited to 'ext')
-rw-r--r--ext/fetch/Cargo.toml1
-rw-r--r--ext/fetch/lib.rs20
-rw-r--r--ext/ffi/Cargo.toml1
-rw-r--r--ext/ffi/lib.rs7
-rw-r--r--ext/fs/Cargo.toml1
-rw-r--r--ext/fs/lib.rs89
-rw-r--r--ext/kv/Cargo.toml1
-rw-r--r--ext/kv/remote.rs16
-rw-r--r--ext/kv/sqlite.rs12
-rw-r--r--ext/napi/Cargo.toml1
-rw-r--r--ext/napi/lib.rs9
-rw-r--r--ext/net/Cargo.toml1
-rw-r--r--ext/net/lib.rs29
-rw-r--r--ext/node/analyze.rs12
-rw-r--r--ext/node/global.rs5
-rw-r--r--ext/node/lib.rs78
-rw-r--r--ext/node/ops/require.rs37
-rw-r--r--ext/node/ops/worker_threads.rs9
-rw-r--r--ext/node/package_json.rs2
-rw-r--r--ext/node/resolution.rs106
-rw-r--r--ext/web/Cargo.toml1
-rw-r--r--ext/web/timers.rs7
-rw-r--r--ext/websocket/Cargo.toml1
-rw-r--r--ext/websocket/lib.rs11
24 files changed, 325 insertions, 132 deletions
diff --git a/ext/fetch/Cargo.toml b/ext/fetch/Cargo.toml
index 75884466b..a5cc650b1 100644
--- a/ext/fetch/Cargo.toml
+++ b/ext/fetch/Cargo.toml
@@ -17,6 +17,7 @@ path = "lib.rs"
bytes.workspace = true
data-url.workspace = true
deno_core.workspace = true
+deno_permissions.workspace = true
deno_tls.workspace = true
dyn-clone = "1"
http_v02.workspace = true
diff --git a/ext/fetch/lib.rs b/ext/fetch/lib.rs
index 21ca04027..066f1685b 100644
--- a/ext/fetch/lib.rs
+++ b/ext/fetch/lib.rs
@@ -281,6 +281,26 @@ pub trait FetchPermissions {
fn check_read(&mut self, _p: &Path, api_name: &str) -> Result<(), AnyError>;
}
+impl FetchPermissions for deno_permissions::PermissionsContainer {
+ #[inline(always)]
+ fn check_net_url(
+ &mut self,
+ url: &Url,
+ api_name: &str,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_net_url(self, url, api_name)
+ }
+
+ #[inline(always)]
+ fn check_read(
+ &mut self,
+ path: &Path,
+ api_name: &str,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_read(self, path, api_name)
+ }
+}
+
#[op2]
#[serde]
#[allow(clippy::too_many_arguments)]
diff --git a/ext/ffi/Cargo.toml b/ext/ffi/Cargo.toml
index fb0d4ae2a..e8e984acb 100644
--- a/ext/ffi/Cargo.toml
+++ b/ext/ffi/Cargo.toml
@@ -15,6 +15,7 @@ path = "lib.rs"
[dependencies]
deno_core.workspace = true
+deno_permissions.workspace = true
dlopen2.workspace = true
dynasmrt = "1.2.3"
libffi = "=3.2.0"
diff --git a/ext/ffi/lib.rs b/ext/ffi/lib.rs
index 4e8129240..26b06d98f 100644
--- a/ext/ffi/lib.rs
+++ b/ext/ffi/lib.rs
@@ -53,6 +53,13 @@ pub trait FfiPermissions {
fn check_partial(&mut self, path: Option<&Path>) -> Result<(), AnyError>;
}
+impl FfiPermissions for deno_permissions::PermissionsContainer {
+ #[inline(always)]
+ fn check_partial(&mut self, path: Option<&Path>) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_ffi_partial(self, path)
+ }
+}
+
deno_core::extension!(deno_ffi,
deps = [ deno_web ],
parameters = [P: FfiPermissions],
diff --git a/ext/fs/Cargo.toml b/ext/fs/Cargo.toml
index b5ac5199c..f13dc1cbf 100644
--- a/ext/fs/Cargo.toml
+++ b/ext/fs/Cargo.toml
@@ -21,6 +21,7 @@ async-trait.workspace = true
base32.workspace = true
deno_core.workspace = true
deno_io.workspace = true
+deno_permissions.workspace = true
filetime.workspace = true
libc.workspace = true
rand.workspace = true
diff --git a/ext/fs/lib.rs b/ext/fs/lib.rs
index d6794d3ac..2dce04b32 100644
--- a/ext/fs/lib.rs
+++ b/ext/fs/lib.rs
@@ -23,9 +23,10 @@ use crate::ops::*;
use deno_core::error::AnyError;
use deno_core::OpState;
use deno_io::fs::FsError;
+use std::borrow::Cow;
use std::path::Path;
-pub trait FsPermissions: Send + Sync {
+pub trait FsPermissions {
fn check_open<'a>(
&mut self,
resolved: bool,
@@ -78,6 +79,92 @@ pub trait FsPermissions: Send + Sync {
}
}
+impl FsPermissions for deno_permissions::PermissionsContainer {
+ fn check_open<'a>(
+ &mut self,
+ resolved: bool,
+ read: bool,
+ write: bool,
+ path: &'a Path,
+ api_name: &str,
+ ) -> Result<Cow<'a, Path>, FsError> {
+ if resolved {
+ self.check_special_file(path, api_name).map_err(|_| {
+ std::io::Error::from(std::io::ErrorKind::PermissionDenied)
+ })?;
+ return Ok(Cow::Borrowed(path));
+ }
+
+ // If somehow read or write aren't specified, use read
+ let read = read || !write;
+ if read {
+ FsPermissions::check_read(self, path, api_name)
+ .map_err(|_| FsError::PermissionDenied("read"))?;
+ }
+ if write {
+ FsPermissions::check_write(self, path, api_name)
+ .map_err(|_| FsError::PermissionDenied("write"))?;
+ }
+ Ok(Cow::Borrowed(path))
+ }
+
+ fn check_read(
+ &mut self,
+ path: &Path,
+ api_name: &str,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_read(self, path, api_name)
+ }
+
+ fn check_read_blind(
+ &mut self,
+ path: &Path,
+ display: &str,
+ api_name: &str,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_read_blind(
+ self, path, display, api_name,
+ )
+ }
+
+ fn check_write(
+ &mut self,
+ path: &Path,
+ api_name: &str,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_write(self, path, api_name)
+ }
+
+ fn check_write_partial(
+ &mut self,
+ path: &Path,
+ api_name: &str,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_write_partial(
+ self, path, api_name,
+ )
+ }
+
+ fn check_write_blind(
+ &mut self,
+ p: &Path,
+ display: &str,
+ api_name: &str,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_write_blind(
+ self, p, display, api_name,
+ )
+ }
+
+ fn check_read_all(&mut self, api_name: &str) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_read_all(self, api_name)
+ }
+
+ fn check_write_all(&mut self, api_name: &str) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_write_all(self, api_name)
+ }
+}
+
pub const UNSTABLE_FEATURE_NAME: &str = "fs";
/// Helper for checking unstable features. Used for sync ops.
diff --git a/ext/kv/Cargo.toml b/ext/kv/Cargo.toml
index 9cc7e0889..99f3d8051 100644
--- a/ext/kv/Cargo.toml
+++ b/ext/kv/Cargo.toml
@@ -21,6 +21,7 @@ chrono = { workspace = true, features = ["now"] }
deno_core.workspace = true
deno_fetch.workspace = true
deno_node.workspace = true
+deno_permissions.workspace = true
deno_tls.workspace = true
denokv_proto.workspace = true
denokv_remote.workspace = true
diff --git a/ext/kv/remote.rs b/ext/kv/remote.rs
index 9d5e099c7..a1273e78b 100644
--- a/ext/kv/remote.rs
+++ b/ext/kv/remote.rs
@@ -48,6 +48,22 @@ pub trait RemoteDbHandlerPermissions {
) -> Result<(), AnyError>;
}
+impl RemoteDbHandlerPermissions for deno_permissions::PermissionsContainer {
+ #[inline(always)]
+ fn check_env(&mut self, var: &str) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_env(self, var)
+ }
+
+ #[inline(always)]
+ fn check_net_url(
+ &mut self,
+ url: &Url,
+ api_name: &str,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_net_url(self, url, api_name)
+ }
+}
+
pub struct RemoteDbHandler<P: RemoteDbHandlerPermissions + 'static> {
http_options: HttpOptions,
_p: std::marker::PhantomData<P>,
diff --git a/ext/kv/sqlite.rs b/ext/kv/sqlite.rs
index a8a7fbace..6dd821bda 100644
--- a/ext/kv/sqlite.rs
+++ b/ext/kv/sqlite.rs
@@ -40,6 +40,18 @@ pub trait SqliteDbHandlerPermissions {
fn check_write(&mut self, p: &Path, api_name: &str) -> Result<(), AnyError>;
}
+impl SqliteDbHandlerPermissions for deno_permissions::PermissionsContainer {
+ #[inline(always)]
+ fn check_read(&mut self, p: &Path, api_name: &str) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_read(self, p, api_name)
+ }
+
+ #[inline(always)]
+ fn check_write(&mut self, p: &Path, api_name: &str) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_write(self, p, api_name)
+ }
+}
+
impl<P: SqliteDbHandlerPermissions> SqliteDbHandler<P> {
pub fn new(
default_storage_dir: Option<PathBuf>,
diff --git a/ext/napi/Cargo.toml b/ext/napi/Cargo.toml
index 2342f313f..c6f3c7685 100644
--- a/ext/napi/Cargo.toml
+++ b/ext/napi/Cargo.toml
@@ -15,4 +15,5 @@ path = "lib.rs"
[dependencies]
deno_core.workspace = true
+deno_permissions.workspace = true
libloading = { version = "0.7" }
diff --git a/ext/napi/lib.rs b/ext/napi/lib.rs
index b3313f0fe..f4fa33438 100644
--- a/ext/napi/lib.rs
+++ b/ext/napi/lib.rs
@@ -432,6 +432,15 @@ pub trait NapiPermissions {
-> std::result::Result<(), AnyError>;
}
+// 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: Option<&Path>) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_ffi(self, path)
+ }
+}
+
/// # Safety
///
/// This function is unsafe because it dereferences raw pointer Env.
diff --git a/ext/net/Cargo.toml b/ext/net/Cargo.toml
index b9ddf8d70..10dfd0d77 100644
--- a/ext/net/Cargo.toml
+++ b/ext/net/Cargo.toml
@@ -15,6 +15,7 @@ path = "lib.rs"
[dependencies]
deno_core.workspace = true
+deno_permissions.workspace = true
deno_tls.workspace = true
pin-project.workspace = true
rustls-tokio-stream.workspace = true
diff --git a/ext/net/lib.rs b/ext/net/lib.rs
index fa8074b34..3b6c05282 100644
--- a/ext/net/lib.rs
+++ b/ext/net/lib.rs
@@ -30,6 +30,35 @@ pub trait NetPermissions {
-> Result<(), AnyError>;
}
+impl NetPermissions for deno_permissions::PermissionsContainer {
+ #[inline(always)]
+ fn check_net<T: AsRef<str>>(
+ &mut self,
+ host: &(T, Option<u16>),
+ api_name: &str,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_net(self, host, api_name)
+ }
+
+ #[inline(always)]
+ fn check_read(
+ &mut self,
+ path: &Path,
+ api_name: &str,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_read(self, path, api_name)
+ }
+
+ #[inline(always)]
+ fn check_write(
+ &mut self,
+ path: &Path,
+ api_name: &str,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_write(self, path, api_name)
+ }
+}
+
/// Helper for checking unstable features. Used for sync ops.
fn check_unstable(state: &OpState, api_name: &str) {
// TODO(bartlomieju): replace with `state.feature_checker.check_or_exit`
diff --git a/ext/node/analyze.rs b/ext/node/analyze.rs
index b7adfd5ce..df68cb0fc 100644
--- a/ext/node/analyze.rs
+++ b/ext/node/analyze.rs
@@ -17,8 +17,8 @@ use deno_core::error::AnyError;
use crate::path::to_file_specifier;
use crate::resolution::NodeResolverRc;
+use crate::AllowAllNodePermissions;
use crate::NodeModuleKind;
-use crate::NodePermissions;
use crate::NodeResolutionMode;
use crate::NpmResolverRc;
use crate::PackageJson;
@@ -87,7 +87,6 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
&self,
entry_specifier: &ModuleSpecifier,
source: Option<String>,
- permissions: &dyn NodePermissions,
) -> Result<String, AnyError> {
let mut temp_var_count = 0;
@@ -115,7 +114,6 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
.analyze_reexports(
entry_specifier,
analysis.reexports,
- permissions,
&mut all_exports,
&mut errors,
)
@@ -161,7 +159,6 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
&'a self,
entry_specifier: &url::Url,
reexports: Vec<String>,
- permissions: &dyn NodePermissions,
all_exports: &mut HashSet<String>,
// this goes through the modules concurrently, so collect
// the errors in order to be deterministic
@@ -194,7 +191,6 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
// should be `deno-require`, because `deno` is already used in `esm_resolver.rs`
&["deno", "require", "default"],
NodeResolutionMode::Execution,
- permissions,
);
let reexport_specifier = match result {
Ok(specifier) => specifier,
@@ -287,7 +283,6 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
referrer: &ModuleSpecifier,
conditions: &[&str],
mode: NodeResolutionMode,
- permissions: &dyn NodePermissions,
) -> Result<ModuleSpecifier, AnyError> {
if specifier.starts_with('/') {
todo!();
@@ -319,7 +314,7 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
let package_json = PackageJson::load(
&*self.fs,
&*self.npm_resolver,
- permissions,
+ &mut AllowAllNodePermissions,
package_json_path.clone(),
)?;
if package_json.exists {
@@ -332,7 +327,6 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
NodeModuleKind::Esm,
conditions,
mode,
- permissions,
);
}
@@ -345,7 +339,7 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
let package_json = PackageJson::load(
&*self.fs,
&*self.npm_resolver,
- permissions,
+ &mut AllowAllNodePermissions,
package_json_path,
)?;
if package_json.exists {
diff --git a/ext/node/global.rs b/ext/node/global.rs
index 0aaa6ed8b..d2fe7a1e5 100644
--- a/ext/node/global.rs
+++ b/ext/node/global.rs
@@ -1,13 +1,12 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use std::mem::MaybeUninit;
-use std::rc::Rc;
use deno_core::v8;
use deno_core::v8::GetPropertyNamesArgs;
use deno_core::v8::MapFnTo;
-use crate::NodeResolver;
+use crate::resolution::NodeResolverRc;
// NOTE(bartlomieju): somehow calling `.map_fn_to()` multiple times on a function
// returns two different pointers. That shouldn't be the case as `.map_fn_to()`
@@ -271,7 +270,7 @@ fn current_mode(scope: &mut v8::HandleScope) -> Mode {
};
let op_state = deno_core::JsRuntime::op_state_from(scope);
let op_state = op_state.borrow();
- let Some(node_resolver) = op_state.try_borrow::<Rc<NodeResolver>>() else {
+ let Some(node_resolver) = op_state.try_borrow::<NodeResolverRc>() else {
return Mode::Deno;
};
let mut buffer = [MaybeUninit::uninit(); 2048];
diff --git a/ext/node/lib.rs b/ext/node/lib.rs
index 2b31f704f..a15125f60 100644
--- a/ext/node/lib.rs
+++ b/ext/node/lib.rs
@@ -6,7 +6,6 @@
use std::collections::HashSet;
use std::path::Path;
use std::path::PathBuf;
-use std::rc::Rc;
use deno_core::error::AnyError;
use deno_core::located_script_name;
@@ -46,6 +45,7 @@ pub use resolution::NodeModuleKind;
pub use resolution::NodeResolution;
pub use resolution::NodeResolutionMode;
pub use resolution::NodeResolver;
+use resolution::NodeResolverRc;
use crate::global::global_object_middleware;
use crate::global::global_template_middleware;
@@ -57,23 +57,23 @@ pub trait NodePermissions {
api_name: &str,
) -> Result<(), AnyError>;
#[inline(always)]
- fn check_read(&self, path: &Path) -> Result<(), AnyError> {
+ fn check_read(&mut self, path: &Path) -> Result<(), AnyError> {
self.check_read_with_api_name(path, None)
}
fn check_read_with_api_name(
- &self,
+ &mut self,
path: &Path,
api_name: Option<&str>,
) -> Result<(), AnyError>;
- fn check_sys(&self, kind: &str, api_name: &str) -> Result<(), AnyError>;
+ fn check_sys(&mut self, kind: &str, api_name: &str) -> Result<(), AnyError>;
fn check_write_with_api_name(
- &self,
+ &mut self,
path: &Path,
api_name: Option<&str>,
) -> Result<(), AnyError>;
}
-pub(crate) struct AllowAllNodePermissions;
+pub struct AllowAllNodePermissions;
impl NodePermissions for AllowAllNodePermissions {
fn check_net_url(
@@ -84,24 +84,65 @@ impl NodePermissions for AllowAllNodePermissions {
Ok(())
}
fn check_read_with_api_name(
- &self,
+ &mut self,
_path: &Path,
_api_name: Option<&str>,
) -> Result<(), AnyError> {
Ok(())
}
fn check_write_with_api_name(
- &self,
+ &mut self,
_path: &Path,
_api_name: Option<&str>,
) -> Result<(), AnyError> {
Ok(())
}
- fn check_sys(&self, _kind: &str, _api_name: &str) -> Result<(), AnyError> {
+ fn check_sys(
+ &mut self,
+ _kind: &str,
+ _api_name: &str,
+ ) -> Result<(), AnyError> {
Ok(())
}
}
+impl NodePermissions for deno_permissions::PermissionsContainer {
+ #[inline(always)]
+ fn check_net_url(
+ &mut self,
+ url: &Url,
+ api_name: &str,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_net_url(self, url, api_name)
+ }
+
+ #[inline(always)]
+ fn check_read_with_api_name(
+ &mut self,
+ path: &Path,
+ api_name: Option<&str>,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_read_with_api_name(
+ self, path, api_name,
+ )
+ }
+
+ #[inline(always)]
+ fn check_write_with_api_name(
+ &mut self,
+ path: &Path,
+ api_name: Option<&str>,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_write_with_api_name(
+ self, path, api_name,
+ )
+ }
+
+ fn check_sys(&mut self, kind: &str, api_name: &str) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_sys(self, kind, api_name)
+ }
+}
+
#[allow(clippy::disallowed_types)]
pub type NpmResolverRc = deno_fs::sync::MaybeArc<dyn NpmResolver>;
@@ -146,7 +187,7 @@ pub trait NpmResolver: std::fmt::Debug + MaybeSend + MaybeSync {
fn ensure_read_permission(
&self,
- permissions: &dyn NodePermissions,
+ permissions: &mut dyn NodePermissions,
path: &Path,
) -> Result<(), AnyError>;
}
@@ -582,18 +623,21 @@ deno_core::extension!(deno_node,
"node:zlib" = "zlib.ts",
],
options = {
+ maybe_node_resolver: Option<NodeResolverRc>,
maybe_npm_resolver: Option<NpmResolverRc>,
fs: deno_fs::FileSystemRc,
},
state = |state, options| {
- let fs = options.fs;
- state.put(fs.clone());
- if let Some(npm_resolver) = options.maybe_npm_resolver {
+ // you should provide both of these or neither
+ debug_assert_eq!(options.maybe_node_resolver.is_some(), options.maybe_npm_resolver.is_some());
+
+ state.put(options.fs.clone());
+
+ if let Some(node_resolver) = &options.maybe_node_resolver {
+ state.put(node_resolver.clone());
+ }
+ if let Some(npm_resolver) = &options.maybe_npm_resolver {
state.put(npm_resolver.clone());
- state.put(Rc::new(NodeResolver::new(
- fs,
- npm_resolver,
- )))
}
},
global_template_middleware = global_template_middleware,
diff --git a/ext/node/ops/require.rs b/ext/node/ops/require.rs
index 176d64e56..de2687001 100644
--- a/ext/node/ops/require.rs
+++ b/ext/node/ops/require.rs
@@ -16,10 +16,11 @@ use std::path::PathBuf;
use std::rc::Rc;
use crate::resolution;
+use crate::resolution::NodeResolverRc;
+use crate::AllowAllNodePermissions;
use crate::NodeModuleKind;
use crate::NodePermissions;
use crate::NodeResolutionMode;
-use crate::NodeResolver;
use crate::NpmResolverRc;
use crate::PackageJson;
@@ -30,8 +31,8 @@ fn ensure_read_permission<P>(
where
P: NodePermissions + 'static,
{
- let resolver = state.borrow::<NpmResolverRc>();
- let permissions = state.borrow::<P>();
+ let resolver = state.borrow::<NpmResolverRc>().clone();
+ let permissions = state.borrow_mut::<P>();
resolver.ensure_read_permission(permissions, file_path)
}
@@ -386,12 +387,11 @@ where
return Ok(None);
}
- let node_resolver = state.borrow::<Rc<NodeResolver>>();
- let permissions = state.borrow::<P>();
+ let node_resolver = state.borrow::<NodeResolverRc>();
let pkg = node_resolver
.get_closest_package_json(
&Url::from_file_path(parent_path.unwrap()).unwrap(),
- permissions,
+ &mut AllowAllNodePermissions,
)
.ok()
.flatten();
@@ -428,7 +428,6 @@ where
NodeModuleKind::Cjs,
resolution::REQUIRE_CONDITIONS,
NodeResolutionMode::Execution,
- permissions,
)?;
Ok(Some(if r.scheme() == "file" {
url_to_file_path_string(&r)?
@@ -483,8 +482,7 @@ where
{
let fs = state.borrow::<FileSystemRc>();
let npm_resolver = state.borrow::<NpmResolverRc>();
- let node_resolver = state.borrow::<Rc<NodeResolver>>();
- let permissions = state.borrow::<P>();
+ let node_resolver = state.borrow::<NodeResolverRc>();
let pkg_path = if npm_resolver
.in_npm_package_at_file_path(&PathBuf::from(&modules_path))
@@ -501,7 +499,7 @@ where
}
};
let pkg = node_resolver.load_package_json(
- permissions,
+ &mut AllowAllNodePermissions,
PathBuf::from(&pkg_path).join("package.json"),
)?;
@@ -515,7 +513,6 @@ where
NodeModuleKind::Cjs,
resolution::REQUIRE_CONDITIONS,
NodeResolutionMode::Execution,
- permissions,
)?;
Ok(Some(if r.scheme() == "file" {
url_to_file_path_string(&r)?
@@ -540,8 +537,8 @@ where
state,
PathBuf::from(&filename).parent().unwrap(),
)?;
- let node_resolver = state.borrow::<Rc<NodeResolver>>();
- let permissions = state.borrow::<P>();
+ let node_resolver = state.borrow::<NodeResolverRc>().clone();
+ let permissions = state.borrow_mut::<P>();
node_resolver
.get_closest_package_json(
&Url::from_file_path(filename).unwrap(),
@@ -559,8 +556,8 @@ pub fn op_require_read_package_scope<P>(
where
P: NodePermissions + 'static,
{
- let node_resolver = state.borrow::<Rc<NodeResolver>>();
- let permissions = state.borrow::<P>();
+ let node_resolver = state.borrow::<NodeResolverRc>().clone();
+ let permissions = state.borrow_mut::<P>();
let package_json_path = PathBuf::from(package_json_path);
node_resolver
.load_package_json(permissions, package_json_path)
@@ -580,10 +577,11 @@ where
{
let referrer_path = PathBuf::from(&referrer_filename);
ensure_read_permission::<P>(state, &referrer_path)?;
- let node_resolver = state.borrow::<Rc<NodeResolver>>();
- let permissions = state.borrow::<P>();
- let Some(pkg) = node_resolver
- .get_closest_package_json_from_path(&referrer_path, permissions)?
+ let node_resolver = state.borrow::<NodeResolverRc>();
+ let Some(pkg) = node_resolver.get_closest_package_json_from_path(
+ &referrer_path,
+ &mut AllowAllNodePermissions,
+ )?
else {
return Ok(None);
};
@@ -598,7 +596,6 @@ where
Some(&pkg),
resolution::REQUIRE_CONDITIONS,
NodeResolutionMode::Execution,
- permissions,
)?;
Ok(Some(url_to_file_path_string(&url)?))
} else {
diff --git a/ext/node/ops/worker_threads.rs b/ext/node/ops/worker_threads.rs
index 18a4157d4..182ba0118 100644
--- a/ext/node/ops/worker_threads.rs
+++ b/ext/node/ops/worker_threads.rs
@@ -8,11 +8,10 @@ use deno_core::OpState;
use deno_fs::FileSystemRc;
use std::path::Path;
use std::path::PathBuf;
-use std::rc::Rc;
use crate::resolution;
+use crate::resolution::NodeResolverRc;
use crate::NodePermissions;
-use crate::NodeResolver;
use crate::NpmResolverRc;
fn ensure_read_permission<P>(
@@ -22,8 +21,8 @@ fn ensure_read_permission<P>(
where
P: NodePermissions + 'static,
{
- let resolver = state.borrow::<NpmResolverRc>();
- let permissions = state.borrow::<P>();
+ let resolver = state.borrow::<NpmResolverRc>().clone();
+ let permissions = state.borrow_mut::<P>();
resolver.ensure_read_permission(permissions, file_path)
}
@@ -63,7 +62,7 @@ where
if !fs.exists_sync(&url_path) {
return Err(generic_error(format!("File not found [{:?}]", url_path)));
}
- let node_resolver = state.borrow::<Rc<NodeResolver>>();
+ let node_resolver = state.borrow::<NodeResolverRc>();
match node_resolver.url_to_node_resolution(url)? {
resolution::NodeResolution::Esm(u) => Ok(u.to_string()),
resolution::NodeResolution::CommonJs(u) => wrap_cjs(u),
diff --git a/ext/node/package_json.rs b/ext/node/package_json.rs
index d4ffc80d6..adae7d634 100644
--- a/ext/node/package_json.rs
+++ b/ext/node/package_json.rs
@@ -65,7 +65,7 @@ impl PackageJson {
pub fn load(
fs: &dyn deno_fs::FileSystem,
resolver: &dyn NpmResolver,
- permissions: &dyn NodePermissions,
+ permissions: &mut dyn NodePermissions,
path: PathBuf,
) -> Result<Rc<PackageJson>, AnyError> {
resolver.ensure_read_permission(permissions, &path)?;
diff --git a/ext/node/resolution.rs b/ext/node/resolution.rs
index 37598810d..834b465cd 100644
--- a/ext/node/resolution.rs
+++ b/ext/node/resolution.rs
@@ -154,7 +154,6 @@ impl NodeResolver {
specifier: &str,
referrer: &ModuleSpecifier,
mode: NodeResolutionMode,
- permissions: &dyn NodePermissions,
) -> Result<Option<NodeResolution>, AnyError> {
// Note: if we are here, then the referrer is an esm module
// TODO(bartlomieju): skipped "policy" part as we don't plan to support it
@@ -187,13 +186,8 @@ impl NodeResolver {
}
}
- let url = self.module_resolve(
- specifier,
- referrer,
- DEFAULT_CONDITIONS,
- mode,
- permissions,
- )?;
+ let url =
+ self.module_resolve(specifier, referrer, DEFAULT_CONDITIONS, mode)?;
let url = match url {
Some(url) => url,
None => return Ok(None),
@@ -204,12 +198,8 @@ impl NodeResolver {
let path = url.to_file_path().unwrap();
// todo(16370): the module kind is not correct here. I think we need
// typescript to tell us if the referrer is esm or cjs
- let maybe_decl_url = self.path_to_declaration_url(
- path,
- referrer,
- NodeModuleKind::Esm,
- permissions,
- )?;
+ let maybe_decl_url =
+ self.path_to_declaration_url(path, referrer, NodeModuleKind::Esm)?;
match maybe_decl_url {
Some(url) => url,
None => return Ok(None),
@@ -229,7 +219,6 @@ impl NodeResolver {
referrer: &ModuleSpecifier,
conditions: &[&str],
mode: NodeResolutionMode,
- permissions: &dyn NodePermissions,
) -> Result<Option<ModuleSpecifier>, AnyError> {
// note: if we're here, the referrer is an esm module
let url = if should_be_treated_as_relative_or_absolute_path(specifier) {
@@ -242,13 +231,13 @@ impl NodeResolver {
file_path,
referrer,
NodeModuleKind::Esm,
- permissions,
)?
} else {
Some(resolved_specifier)
}
} else if specifier.starts_with('#') {
- let pkg_config = self.get_closest_package_json(referrer, permissions)?;
+ let pkg_config = self
+ .get_closest_package_json(referrer, &mut AllowAllNodePermissions)?;
Some(self.package_imports_resolve(
specifier,
referrer,
@@ -256,7 +245,6 @@ impl NodeResolver {
pkg_config.as_deref(),
conditions,
mode,
- permissions,
)?)
} else if let Ok(resolved) = Url::parse(specifier) {
Some(resolved)
@@ -267,7 +255,6 @@ impl NodeResolver {
NodeModuleKind::Esm,
conditions,
mode,
- permissions,
)?
};
Ok(match url {
@@ -337,11 +324,12 @@ impl NodeResolver {
package_subpath: Option<&str>,
referrer: &ModuleSpecifier,
mode: NodeResolutionMode,
- permissions: &dyn NodePermissions,
) -> Result<Option<NodeResolution>, AnyError> {
let package_json_path = package_dir.join("package.json");
- let package_json =
- self.load_package_json(permissions, package_json_path.clone())?;
+ let package_json = self.load_package_json(
+ &mut AllowAllNodePermissions,
+ package_json_path.clone(),
+ )?;
let node_module_kind = NodeModuleKind::Esm;
let package_subpath = package_subpath
.map(|s| format!("./{s}"))
@@ -354,7 +342,6 @@ impl NodeResolver {
node_module_kind,
DEFAULT_CONDITIONS,
mode,
- permissions,
)
.with_context(|| {
format!(
@@ -376,7 +363,6 @@ impl NodeResolver {
path,
referrer,
node_module_kind,
- permissions,
)? {
Some(url) => url,
None => return Ok(None),
@@ -397,8 +383,10 @@ impl NodeResolver {
package_folder: &Path,
) -> Result<Vec<String>, AnyError> {
let package_json_path = package_folder.join("package.json");
- let package_json = self
- .load_package_json(&AllowAllNodePermissions, package_json_path.clone())?;
+ let package_json = self.load_package_json(
+ &mut AllowAllNodePermissions,
+ package_json_path.clone(),
+ )?;
Ok(match &package_json.bin {
Some(Value::String(_)) => {
@@ -420,8 +408,10 @@ impl NodeResolver {
sub_path: Option<&str>,
) -> Result<NodeResolution, AnyError> {
let package_json_path = package_folder.join("package.json");
- let package_json = self
- .load_package_json(&AllowAllNodePermissions, package_json_path.clone())?;
+ let package_json = self.load_package_json(
+ &mut AllowAllNodePermissions,
+ package_json_path.clone(),
+ )?;
let bin_entry = resolve_bin_entry_value(&package_json, sub_path)?;
let url = to_file_specifier(&package_folder.join(bin_entry));
@@ -440,7 +430,7 @@ impl NodeResolver {
Ok(NodeResolution::Esm(url))
} else if url_str.ends_with(".js") || url_str.ends_with(".d.ts") {
let maybe_package_config =
- self.get_closest_package_json(&url, &AllowAllNodePermissions)?;
+ self.get_closest_package_json(&url, &mut AllowAllNodePermissions)?;
match maybe_package_config {
Some(c) if c.typ == "module" => Ok(NodeResolution::Esm(url)),
Some(_) => Ok(NodeResolution::CommonJs(url)),
@@ -467,7 +457,6 @@ impl NodeResolver {
path: PathBuf,
referrer: &ModuleSpecifier,
referrer_kind: NodeModuleKind,
- permissions: &dyn NodePermissions,
) -> Result<Option<ModuleSpecifier>, AnyError> {
fn probe_extensions(
fs: &dyn deno_fs::FileSystem,
@@ -528,7 +517,7 @@ impl NodeResolver {
if self.fs.is_dir_sync(&path) {
let package_json_path = path.join("package.json");
if let Ok(pkg_json) =
- self.load_package_json(permissions, package_json_path)
+ self.load_package_json(&mut AllowAllNodePermissions, package_json_path)
{
let maybe_resolution = self.resolve_package_subpath(
&pkg_json,
@@ -540,7 +529,6 @@ impl NodeResolver {
NodeModuleKind::Cjs => REQUIRE_CONDITIONS,
},
NodeResolutionMode::Types,
- permissions,
)?;
if let Some(resolution) = maybe_resolution {
return Ok(Some(resolution));
@@ -572,7 +560,6 @@ impl NodeResolver {
referrer_pkg_json: Option<&PackageJson>,
conditions: &[&str],
mode: NodeResolutionMode,
- permissions: &dyn NodePermissions,
) -> Result<ModuleSpecifier, AnyError> {
if name == "#" || name.starts_with("#/") || name.ends_with('/') {
let reason = "is not a valid internal imports specifier name";
@@ -601,7 +588,6 @@ impl NodeResolver {
true,
conditions,
mode,
- permissions,
)?;
if let Some(resolved) = maybe_resolved {
return Ok(resolved);
@@ -644,7 +630,6 @@ impl NodeResolver {
true,
conditions,
mode,
- permissions,
)?;
if let Some(resolved) = maybe_resolved {
return Ok(resolved);
@@ -675,7 +660,6 @@ impl NodeResolver {
internal: bool,
conditions: &[&str],
mode: NodeResolutionMode,
- permissions: &dyn NodePermissions,
) -> Result<ModuleSpecifier, AnyError> {
if !subpath.is_empty() && !pattern && !target.ends_with('/') {
return Err(throw_invalid_package_target(
@@ -715,7 +699,6 @@ impl NodeResolver {
referrer_kind,
conditions,
mode,
- permissions,
) {
Ok(Some(url)) => Ok(url),
Ok(None) => Err(generic_error("not found")),
@@ -804,7 +787,6 @@ impl NodeResolver {
internal: bool,
conditions: &[&str],
mode: NodeResolutionMode,
- permissions: &dyn NodePermissions,
) -> Result<Option<ModuleSpecifier>, AnyError> {
if let Some(target) = target.as_str() {
let url = self.resolve_package_target_string(
@@ -818,16 +800,10 @@ impl NodeResolver {
internal,
conditions,
mode,
- permissions,
)?;
if mode.is_types() && url.scheme() == "file" {
let path = url.to_file_path().unwrap();
- return self.path_to_declaration_url(
- path,
- referrer,
- referrer_kind,
- permissions,
- );
+ return self.path_to_declaration_url(path, referrer, referrer_kind);
} else {
return Ok(Some(url));
}
@@ -849,7 +825,6 @@ impl NodeResolver {
internal,
conditions,
mode,
- permissions,
);
match resolved_result {
@@ -898,7 +873,6 @@ impl NodeResolver {
internal,
conditions,
mode,
- permissions,
)?;
match resolved {
Some(resolved) => return Ok(Some(resolved)),
@@ -931,7 +905,6 @@ impl NodeResolver {
referrer_kind: NodeModuleKind,
conditions: &[&str],
mode: NodeResolutionMode,
- permissions: &dyn NodePermissions,
) -> Result<ModuleSpecifier, AnyError> {
if package_exports.contains_key(package_subpath)
&& package_subpath.find('*').is_none()
@@ -949,7 +922,6 @@ impl NodeResolver {
false,
conditions,
mode,
- permissions,
)?;
return match resolved {
Some(resolved) => Ok(resolved),
@@ -1009,7 +981,6 @@ impl NodeResolver {
false,
conditions,
mode,
- permissions,
)?;
if let Some(resolved) = maybe_resolved {
return Ok(resolved);
@@ -1038,13 +1009,12 @@ impl NodeResolver {
referrer_kind: NodeModuleKind,
conditions: &[&str],
mode: NodeResolutionMode,
- permissions: &dyn NodePermissions,
) -> Result<Option<ModuleSpecifier>, AnyError> {
let (package_name, package_subpath, _is_scoped) =
parse_npm_pkg_name(specifier, referrer)?;
let Some(package_config) =
- self.get_closest_package_json(referrer, permissions)?
+ self.get_closest_package_json(referrer, &mut AllowAllNodePermissions)?
else {
return Ok(None);
};
@@ -1062,7 +1032,6 @@ impl NodeResolver {
referrer_kind,
conditions,
mode,
- permissions,
)
.map(Some);
}
@@ -1087,8 +1056,8 @@ impl NodeResolver {
// ))
// Package match.
- let package_json =
- self.load_package_json(permissions, package_json_path)?;
+ let package_json = self
+ .load_package_json(&mut AllowAllNodePermissions, package_json_path)?;
self.resolve_package_subpath(
&package_json,
&package_subpath,
@@ -1096,7 +1065,6 @@ impl NodeResolver {
referrer_kind,
conditions,
mode,
- permissions,
)
}
@@ -1109,7 +1077,6 @@ impl NodeResolver {
referrer_kind: NodeModuleKind,
conditions: &[&str],
mode: NodeResolutionMode,
- permissions: &dyn NodePermissions,
) -> Result<Option<ModuleSpecifier>, AnyError> {
if let Some(exports) = &package_json.exports {
let result = self.package_exports_resolve(
@@ -1120,7 +1087,6 @@ impl NodeResolver {
referrer_kind,
conditions,
mode,
- permissions,
);
match result {
Ok(found) => return Ok(Some(found)),
@@ -1131,7 +1097,6 @@ impl NodeResolver {
referrer,
referrer_kind,
mode,
- permissions,
);
}
return Err(exports_err);
@@ -1144,18 +1109,12 @@ impl NodeResolver {
referrer,
referrer_kind,
mode,
- permissions,
);
}
let file_path = package_json.path.parent().unwrap().join(package_subpath);
if mode.is_types() {
- self.path_to_declaration_url(
- file_path,
- referrer,
- referrer_kind,
- permissions,
- )
+ self.path_to_declaration_url(file_path, referrer, referrer_kind)
} else {
Ok(Some(to_file_specifier(&file_path)))
}
@@ -1164,7 +1123,7 @@ impl NodeResolver {
pub fn get_closest_package_json(
&self,
url: &ModuleSpecifier,
- permissions: &dyn NodePermissions,
+ permissions: &mut dyn NodePermissions,
) -> Result<Option<Rc<PackageJson>>, AnyError> {
let Ok(file_path) = url.to_file_path() else {
return Ok(None);
@@ -1175,7 +1134,7 @@ impl NodeResolver {
pub fn get_closest_package_json_from_path(
&self,
file_path: &Path,
- permissions: &dyn NodePermissions,
+ permissions: &mut dyn NodePermissions,
) -> Result<Option<Rc<PackageJson>>, AnyError> {
let Some(package_json_path) =
self.get_closest_package_json_path(file_path)?
@@ -1212,7 +1171,7 @@ impl NodeResolver {
pub(super) fn load_package_json(
&self,
- permissions: &dyn NodePermissions,
+ permissions: &mut dyn NodePermissions,
package_json_path: PathBuf,
) -> Result<Rc<PackageJson>, AnyError> {
PackageJson::load(
@@ -1229,7 +1188,6 @@ impl NodeResolver {
referrer: &ModuleSpecifier,
referrer_kind: NodeModuleKind,
mode: NodeResolutionMode,
- permissions: &dyn NodePermissions,
) -> Result<Option<ModuleSpecifier>, AnyError> {
let maybe_main = if mode.is_types() {
match package_json.types.as_ref() {
@@ -1239,12 +1197,8 @@ impl NodeResolver {
// a corresponding declaration file
if let Some(main) = package_json.main(referrer_kind) {
let main = package_json.path.parent().unwrap().join(main).clean();
- let maybe_decl_url = self.path_to_declaration_url(
- main,
- referrer,
- referrer_kind,
- permissions,
- )?;
+ let maybe_decl_url =
+ self.path_to_declaration_url(main, referrer, referrer_kind)?;
if let Some(path) = maybe_decl_url {
return Ok(Some(path));
}
diff --git a/ext/web/Cargo.toml b/ext/web/Cargo.toml
index f99193e0b..ec65d51b4 100644
--- a/ext/web/Cargo.toml
+++ b/ext/web/Cargo.toml
@@ -18,6 +18,7 @@ async-trait.workspace = true
base64-simd = "0.8"
bytes.workspace = true
deno_core.workspace = true
+deno_permissions.workspace = true
encoding_rs.workspace = true
flate2 = { workspace = true, features = ["default"] }
futures.workspace = true
diff --git a/ext/web/timers.rs b/ext/web/timers.rs
index b3060a46f..648be5715 100644
--- a/ext/web/timers.rs
+++ b/ext/web/timers.rs
@@ -10,6 +10,13 @@ pub trait TimersPermission {
fn allow_hrtime(&mut self) -> bool;
}
+impl TimersPermission for deno_permissions::PermissionsContainer {
+ #[inline(always)]
+ fn allow_hrtime(&mut self) -> bool {
+ deno_permissions::PermissionsContainer::allow_hrtime(self)
+ }
+}
+
pub type StartTime = Instant;
// Returns a milliseconds and nanoseconds subsec
diff --git a/ext/websocket/Cargo.toml b/ext/websocket/Cargo.toml
index f2e8c90f9..059f40f63 100644
--- a/ext/websocket/Cargo.toml
+++ b/ext/websocket/Cargo.toml
@@ -17,6 +17,7 @@ path = "lib.rs"
bytes.workspace = true
deno_core.workspace = true
deno_net.workspace = true
+deno_permissions.workspace = true
deno_tls.workspace = true
fastwebsockets.workspace = true
h2.workspace = true
diff --git a/ext/websocket/lib.rs b/ext/websocket/lib.rs
index 06a75faab..87503120b 100644
--- a/ext/websocket/lib.rs
+++ b/ext/websocket/lib.rs
@@ -99,6 +99,17 @@ pub trait WebSocketPermissions {
) -> Result<(), AnyError>;
}
+impl WebSocketPermissions for deno_permissions::PermissionsContainer {
+ #[inline(always)]
+ fn check_net_url(
+ &mut self,
+ url: &url::Url,
+ api_name: &str,
+ ) -> Result<(), AnyError> {
+ deno_permissions::PermissionsContainer::check_net_url(self, url, api_name)
+ }
+}
+
/// `UnsafelyIgnoreCertificateErrors` is a wrapper struct so it can be placed inside `GothamState`;
/// using type alias for a `Option<Vec<String>>` could work, but there's a high chance
/// that there might be another type alias pointing to a `Option<Vec<String>>`, which