From 6b12b62c710b18ac10b1011cd11a9a487824eb5e Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Thu, 13 Nov 2025 13:20:36 -0800 Subject: [PATCH 01/13] remove permissions trait from deno_fetch --- ext/fetch/lib.rs | 111 +++++---------------------------------- runtime/snapshot.rs | 2 +- runtime/snapshot_info.rs | 39 +------------- runtime/web_worker.rs | 20 ++++--- runtime/worker.rs | 24 ++++----- 5 files changed, 35 insertions(+), 161 deletions(-) diff --git a/ext/fetch/lib.rs b/ext/fetch/lib.rs index 9bbea138efc627..d465c894eb9d70 100644 --- a/ext/fetch/lib.rs +++ b/ext/fetch/lib.rs @@ -51,9 +51,9 @@ use deno_core::v8; use deno_error::JsErrorBox; pub use deno_fs::FsError; use deno_path_util::PathToUrlError; -use deno_permissions::CheckedPath; use deno_permissions::OpenAccessKind; use deno_permissions::PermissionCheckError; +use deno_permissions::PermissionsContainer; use deno_tls::Proxy; use deno_tls::RootCertStoreProvider; use deno_tls::SocketUse; @@ -146,12 +146,11 @@ impl Default for Options { deno_core::extension!(deno_fetch, deps = [ deno_webidl, deno_web ], - parameters = [FP: FetchPermissions], ops = [ - op_fetch, + op_fetch, op_fetch_send, op_utf8_to_byte_string, - op_fetch_custom_client, + op_fetch_custom_client, op_fetch_promise_is_settled, ], esm = [ @@ -404,91 +403,12 @@ impl Drop for ResourceToBodyAdapter { } } -pub trait FetchPermissions { - fn check_net( - &mut self, - host: &str, - port: u16, - api_name: &str, - ) -> Result<(), PermissionCheckError>; - fn check_net_url( - &mut self, - url: &Url, - api_name: &str, - ) -> Result<(), PermissionCheckError>; - #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] - fn check_open<'a>( - &mut self, - path: Cow<'a, Path>, - open_access: OpenAccessKind, - api_name: &str, - ) -> Result, PermissionCheckError>; - fn check_net_vsock( - &mut self, - cid: u32, - port: u32, - api_name: &str, - ) -> Result<(), PermissionCheckError>; -} - -impl FetchPermissions for deno_permissions::PermissionsContainer { - #[inline(always)] - fn check_net( - &mut self, - host: &str, - port: u16, - api_name: &str, - ) -> Result<(), PermissionCheckError> { - deno_permissions::PermissionsContainer::check_net( - self, - &(host, Some(port)), - api_name, - ) - } - - #[inline(always)] - fn check_net_url( - &mut self, - url: &Url, - api_name: &str, - ) -> Result<(), PermissionCheckError> { - deno_permissions::PermissionsContainer::check_net_url(self, url, api_name) - } - - #[inline(always)] - fn check_open<'a>( - &mut self, - path: Cow<'a, Path>, - open_access: OpenAccessKind, - api_name: &str, - ) -> Result, PermissionCheckError> { - deno_permissions::PermissionsContainer::check_open( - self, - path, - open_access, - Some(api_name), - ) - } - - #[inline(always)] - fn check_net_vsock( - &mut self, - cid: u32, - port: u32, - api_name: &str, - ) -> Result<(), PermissionCheckError> { - deno_permissions::PermissionsContainer::check_net_vsock( - self, cid, port, api_name, - ) - } -} - #[op2(stack_trace)] #[serde] #[allow(clippy::too_many_arguments)] #[allow(clippy::large_enum_variant)] #[allow(clippy::result_large_err)] -pub fn op_fetch( +pub fn op_fetch( state: &mut OpState, #[serde] method: ByteString, #[string] url: String, @@ -497,10 +417,7 @@ pub fn op_fetch( has_body: bool, #[buffer] data: Option, #[smi] resource: Option, -) -> Result -where - FP: FetchPermissions + 'static, -{ +) -> Result { let (client, allow_host) = if let Some(rid) = client_rid { let r = state.resource_table.get::(rid)?; (r.client.clone(), r.allow_host) @@ -533,7 +450,7 @@ where (request_rid, maybe_cancel_handle_rid) } "http" | "https" => { - let permissions = state.borrow_mut::(); + let permissions = state.borrow_mut::(); permissions.check_net_url(&url, "fetch()")?; let maybe_authority = extract_authority(&mut url); @@ -922,23 +839,21 @@ fn default_true() -> bool { #[op2(stack_trace)] #[smi] #[allow(clippy::result_large_err)] -pub fn op_fetch_custom_client( +pub fn op_fetch_custom_client( state: &mut OpState, #[serde] mut args: CreateHttpClientArgs, #[cppgc] tls_keys: &TlsKeysHolder, -) -> Result -where - FP: FetchPermissions + 'static, -{ +) -> Result { if let Some(proxy) = &mut args.proxy { - let permissions = state.borrow_mut::(); + let permissions = state.borrow_mut::(); match proxy { Proxy::Http { url, .. } => { let url = Url::parse(url)?; permissions.check_net_url(&url, "Deno.createHttpClient()")?; } Proxy::Tcp { hostname, port } => { - permissions.check_net(hostname, *port, "Deno.createHttpClient()")?; + permissions + .check_net(&(hostname, Some(*port)), "Deno.createHttpClient()")?; } Proxy::Unix { path: original_path, @@ -948,7 +863,7 @@ where .check_open( Cow::Borrowed(path), OpenAccessKind::ReadWriteNoFollow, - "Deno.createHttpClient()", + Some("Deno.createHttpClient()"), )? .into_path(); if path != resolved_path { @@ -956,7 +871,7 @@ where } } Proxy::Vsock { cid, port } => { - let permissions = state.borrow_mut::(); + let permissions = state.borrow_mut::(); permissions.check_net_vsock(*cid, *port, "Deno.createHttpClient()")?; } } diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 9b1e353199a19c..795163dd2be16d 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -33,7 +33,7 @@ pub fn create_runtime_snapshot( >(), deno_webgpu::deno_webgpu::lazy_init(), deno_canvas::deno_canvas::lazy_init(), - deno_fetch::deno_fetch::lazy_init::(), + deno_fetch::deno_fetch::lazy_init(), deno_cache::deno_cache::lazy_init(), deno_websocket::deno_websocket::lazy_init::(), deno_webstorage::deno_webstorage::lazy_init(), diff --git a/runtime/snapshot_info.rs b/runtime/snapshot_info.rs index d05ad072ad43fa..f9344c4c5d90c7 100644 --- a/runtime/snapshot_info.rs +++ b/runtime/snapshot_info.rs @@ -33,43 +33,6 @@ impl deno_web::TimersPermission for Permissions { } } -impl deno_fetch::FetchPermissions for Permissions { - fn check_net( - &mut self, - _host: &str, - _port: u16, - _api_name: &str, - ) -> Result<(), PermissionCheckError> { - unreachable!("snapshotting!") - } - - fn check_net_url( - &mut self, - _url: &deno_core::url::Url, - _api_name: &str, - ) -> Result<(), PermissionCheckError> { - unreachable!("snapshotting!") - } - - fn check_open<'a>( - &mut self, - _path: Cow<'a, Path>, - _open_access: OpenAccessKind, - _api_name: &str, - ) -> Result, PermissionCheckError> { - unreachable!("snapshotting!") - } - - fn check_net_vsock( - &mut self, - _cid: u32, - _port: u32, - _api_name: &str, - ) -> Result<(), PermissionCheckError> { - unreachable!("snapshotting!") - } -} - impl deno_ffi::FfiPermissions for Permissions { fn check_partial_no_path(&mut self) -> Result<(), PermissionCheckError> { unreachable!("snapshotting!") @@ -224,7 +187,7 @@ pub fn get_extensions_in_snapshot() -> Vec { ), deno_webgpu::deno_webgpu::init(), deno_canvas::deno_canvas::init(), - deno_fetch::deno_fetch::init::(Default::default()), + deno_fetch::deno_fetch::init(Default::default()), deno_cache::deno_cache::init(None), deno_websocket::deno_websocket::init::(), deno_webstorage::deno_webstorage::init(None), diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 2284cabacfae7b..8fb9673dc4f3e8 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -529,17 +529,15 @@ impl WebWorker { ), deno_webgpu::deno_webgpu::init(), deno_canvas::deno_canvas::init(), - deno_fetch::deno_fetch::init::( - deno_fetch::Options { - user_agent: options.bootstrap.user_agent.clone(), - root_cert_store_provider: services.root_cert_store_provider.clone(), - unsafely_ignore_certificate_errors: options - .unsafely_ignore_certificate_errors - .clone(), - file_fetch_handler: Rc::new(deno_fetch::FsFetchHandler), - ..Default::default() - }, - ), + deno_fetch::deno_fetch::init(deno_fetch::Options { + user_agent: options.bootstrap.user_agent.clone(), + root_cert_store_provider: services.root_cert_store_provider.clone(), + unsafely_ignore_certificate_errors: options + .unsafely_ignore_certificate_errors + .clone(), + file_fetch_handler: Rc::new(deno_fetch::FsFetchHandler), + ..Default::default() + }), deno_cache::deno_cache::init(create_cache), deno_websocket::deno_websocket::init::(), deno_webstorage::deno_webstorage::init(None).disable(), diff --git a/runtime/worker.rs b/runtime/worker.rs index c477cc615c4a3c..c749c4a06beb69 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -538,18 +538,16 @@ impl MainWorker { options.bootstrap.location.clone(), services.broadcast_channel.clone(), ), - deno_fetch::deno_fetch::args::( - deno_fetch::Options { - user_agent: options.bootstrap.user_agent.clone(), - root_cert_store_provider: services.root_cert_store_provider.clone(), - unsafely_ignore_certificate_errors: options - .unsafely_ignore_certificate_errors - .clone(), - file_fetch_handler: Rc::new(deno_fetch::FsFetchHandler), - resolver: services.fetch_dns_resolver, - ..Default::default() - }, - ), + deno_fetch::deno_fetch::args(deno_fetch::Options { + user_agent: options.bootstrap.user_agent.clone(), + root_cert_store_provider: services.root_cert_store_provider.clone(), + unsafely_ignore_certificate_errors: options + .unsafely_ignore_certificate_errors + .clone(), + file_fetch_handler: Rc::new(deno_fetch::FsFetchHandler), + resolver: services.fetch_dns_resolver, + ..Default::default() + }), deno_cache::deno_cache::args(create_cache), deno_websocket::deno_websocket::args::(), deno_webstorage::deno_webstorage::args( @@ -1057,7 +1055,7 @@ fn common_extensions< >(), deno_webgpu::deno_webgpu::init(), deno_canvas::deno_canvas::init(), - deno_fetch::deno_fetch::lazy_init::(), + deno_fetch::deno_fetch::lazy_init(), deno_cache::deno_cache::lazy_init(), deno_websocket::deno_websocket::lazy_init::(), deno_webstorage::deno_webstorage::lazy_init(), From 4095bc2117c1f0ad65490ee8253ec217d57b349d Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Thu, 13 Nov 2025 13:24:17 -0800 Subject: [PATCH 02/13] remove permissions trait from deno_ffi --- ext/ffi/call.rs | 25 ++--- ext/ffi/callback.rs | 13 +-- ext/ffi/dlfcn.rs | 14 +-- ext/ffi/lib.rs | 80 +++++-------- ext/ffi/repr.rs | 234 ++++++++++++++------------------------- runtime/snapshot.rs | 2 +- runtime/snapshot_info.rs | 15 +-- runtime/web_worker.rs | 4 +- runtime/worker.rs | 6 +- 9 files changed, 135 insertions(+), 258 deletions(-) diff --git a/ext/ffi/call.rs b/ext/ffi/call.rs index 81f68c83865f84..3864e15b1c7093 100644 --- a/ext/ffi/call.rs +++ b/ext/ffi/call.rs @@ -13,11 +13,11 @@ use deno_core::serde_v8::BigInt as V8BigInt; use deno_core::serde_v8::ExternalPointer; use deno_core::unsync::spawn_blocking; use deno_core::v8; +use deno_permissions::PermissionsContainer; use libffi::middle::Arg; use num_bigint::BigInt; use serde::Serialize; -use crate::FfiPermissions; use crate::ForeignFunction; use crate::callback::PtrSymbol; use crate::dlfcn::DynamicLibraryResource; @@ -300,24 +300,20 @@ fn ffi_call( #[op2(async, stack_trace)] #[serde] -pub fn op_ffi_call_ptr_nonblocking( +pub fn op_ffi_call_ptr_nonblocking( scope: &mut v8::PinScope<'_, '_>, state: Rc>, pointer: *mut c_void, #[serde] def: ForeignFunction, parameters: v8::Local, out_buffer: Option>, -) -> Result< - impl Future> + use, - CallError, -> +) -> Result> + use<>, CallError> where - FP: FfiPermissions + 'static, { { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; }; let symbol = PtrSymbol::new(pointer, &def)?; @@ -399,21 +395,18 @@ pub fn op_ffi_call_nonblocking( #[op2(reentrant, stack_trace)] #[serde] -pub fn op_ffi_call_ptr( +pub fn op_ffi_call_ptr( scope: &mut v8::PinScope<'_, '_>, state: Rc>, pointer: *mut c_void, #[serde] def: ForeignFunction, parameters: v8::Local, out_buffer: Option>, -) -> Result -where - FP: FfiPermissions + 'static, -{ +) -> Result { { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; }; let symbol = PtrSymbol::new(pointer, &def)?; diff --git a/ext/ffi/callback.rs b/ext/ffi/callback.rs index 7ac10263b6c890..f3ba0fbf84dac3 100644 --- a/ext/ffi/callback.rs +++ b/ext/ffi/callback.rs @@ -21,10 +21,10 @@ use deno_core::ResourceId; use deno_core::V8CrossThreadTaskSpawner; use deno_core::op2; use deno_core::v8; +use deno_permissions::PermissionsContainer; use libffi::middle::Cif; use serde::Deserialize; -use crate::FfiPermissions; use crate::ForeignFunction; use crate::symbol::NativeType; @@ -575,17 +575,14 @@ pub struct RegisterCallbackArgs { } #[op2(stack_trace)] -pub fn op_ffi_unsafe_callback_create( +pub fn op_ffi_unsafe_callback_create<'scope>( state: &mut OpState, scope: &mut v8::PinScope<'scope, '_>, #[serde] args: RegisterCallbackArgs, cb: v8::Local, -) -> Result, CallbackError> -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result, CallbackError> { + let permissions = state.borrow_mut::(); + permissions.check_ffi_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 09e171b1ff5f5c..009ef6a7c30254 100644 --- a/ext/ffi/dlfcn.rs +++ b/ext/ffi/dlfcn.rs @@ -14,12 +14,12 @@ use deno_core::op2; use deno_core::v8; use deno_error::JsErrorBox; use deno_error::JsErrorClass; +use deno_permissions::PermissionsContainer; use denort_helper::DenoRtNativeAddonLoaderRc; use dlopen2::raw::Library; use serde::Deserialize; use serde_value::ValueDeserializer; -use crate::FfiPermissions; use crate::ir::out_buffer_as_ptr; use crate::symbol::NativeType; use crate::symbol::Symbol; @@ -143,20 +143,18 @@ impl<'de> Deserialize<'de> for ForeignSymbol { } #[op2(stack_trace)] -pub fn op_ffi_load<'scope, FP>( +pub fn op_ffi_load<'scope>( scope: &mut v8::PinScope<'scope, '_>, state: Rc>, #[string] path: &str, #[serde] symbols: HashMap, -) -> Result, DlfcnError> -where - FP: FfiPermissions + 'static, -{ +) -> Result, DlfcnError> { let (path, denort_helper) = { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::(); + let permissions = state.borrow_mut::(); ( - permissions.check_partial_with_path(Cow::Borrowed(Path::new(path)))?, + permissions + .check_ffi_partial_with_path(Cow::Borrowed(Path::new(path)))?, state.try_borrow::().cloned(), ) }; diff --git a/ext/ffi/lib.rs b/ext/ffi/lib.rs index a3368aece174da..693dadad16392f 100644 --- a/ext/ffi/lib.rs +++ b/ext/ffi/lib.rs @@ -1,10 +1,8 @@ // Copyright 2018-2025 the Deno authors. MIT license. -use std::borrow::Cow; use std::mem::size_of; use std::os::raw::c_char; use std::os::raw::c_short; -use std::path::Path; mod call; mod callback; @@ -23,7 +21,6 @@ pub use callback::CallbackError; use callback::op_ffi_unsafe_callback_close; use callback::op_ffi_unsafe_callback_create; use callback::op_ffi_unsafe_callback_ref; -use deno_permissions::PermissionCheckError; pub use denort_helper::DenoRtNativeAddonLoader; pub use denort_helper::DenoRtNativeAddonLoaderRc; pub use dlfcn::DlfcnError; @@ -49,63 +46,36 @@ const _: () = { pub const UNSTABLE_FEATURE_NAME: &str = "ffi"; -pub trait FfiPermissions { - 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<'a>( - &mut self, - path: Cow<'a, Path>, - ) -> Result, PermissionCheckError>; -} - -impl FfiPermissions for deno_permissions::PermissionsContainer { - #[inline(always)] - fn check_partial_no_path(&mut self) -> Result<(), PermissionCheckError> { - deno_permissions::PermissionsContainer::check_ffi_partial_no_path(self) - } - - #[inline(always)] - fn check_partial_with_path<'a>( - &mut self, - path: Cow<'a, Path>, - ) -> Result, PermissionCheckError> { - deno_permissions::PermissionsContainer::check_ffi_partial_with_path( - self, path, - ) - } -} - deno_core::extension!(deno_ffi, deps = [ deno_web ], - parameters = [P: FfiPermissions], ops = [ - op_ffi_load

, + op_ffi_load, op_ffi_get_static, op_ffi_call_nonblocking, - op_ffi_call_ptr

, - op_ffi_call_ptr_nonblocking

, - op_ffi_ptr_create

, - op_ffi_ptr_equals

, - op_ffi_ptr_of

, - op_ffi_ptr_of_exact

, - op_ffi_ptr_offset

, - op_ffi_ptr_value

, - op_ffi_get_buf

, - op_ffi_buf_copy_into

, - op_ffi_cstr_read

, - op_ffi_read_bool

, - op_ffi_read_u8

, - op_ffi_read_i8

, - op_ffi_read_u16

, - op_ffi_read_i16

, - op_ffi_read_u32

, - op_ffi_read_i32

, - op_ffi_read_u64

, - op_ffi_read_i64

, - op_ffi_read_f32

, - op_ffi_read_f64

, - op_ffi_read_ptr

, - op_ffi_unsafe_callback_create

, + op_ffi_call_ptr, + op_ffi_call_ptr_nonblocking, + op_ffi_ptr_create, + op_ffi_ptr_equals, + op_ffi_ptr_of, + op_ffi_ptr_of_exact, + op_ffi_ptr_offset, + op_ffi_ptr_value, + op_ffi_get_buf, + op_ffi_buf_copy_into, + op_ffi_cstr_read, + op_ffi_read_bool, + op_ffi_read_u8, + op_ffi_read_i8, + op_ffi_read_u16, + op_ffi_read_i16, + op_ffi_read_u32, + op_ffi_read_i32, + op_ffi_read_u64, + op_ffi_read_i64, + op_ffi_read_f32, + op_ffi_read_f64, + op_ffi_read_ptr, + op_ffi_unsafe_callback_create, op_ffi_unsafe_callback_close, op_ffi_unsafe_callback_ref, op_ffi_get_turbocall_target, diff --git a/ext/ffi/repr.rs b/ext/ffi/repr.rs index 02e121d389c952..ef08467c6de642 100644 --- a/ext/ffi/repr.rs +++ b/ext/ffi/repr.rs @@ -8,8 +8,7 @@ use std::ptr; use deno_core::OpState; use deno_core::op2; use deno_core::v8; - -use crate::FfiPermissions; +use deno_permissions::PermissionsContainer; #[derive(Debug, thiserror::Error, deno_error::JsError)] #[class(type)] @@ -54,58 +53,46 @@ pub enum ReprError { } #[op2(fast, stack_trace)] -pub fn op_ffi_ptr_create( +pub fn op_ffi_ptr_create( state: &mut OpState, #[bigint] ptr_number: usize, -) -> Result<*mut c_void, ReprError> -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result<*mut c_void, ReprError> { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; Ok(ptr_number as *mut c_void) } #[op2(fast, stack_trace)] -pub fn op_ffi_ptr_equals( +pub fn op_ffi_ptr_equals( state: &mut OpState, a: *const c_void, b: *const c_void, -) -> Result -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; Ok(a == b) } #[op2(stack_trace)] -pub fn op_ffi_ptr_of( +pub fn op_ffi_ptr_of( state: &mut OpState, #[anybuffer] buf: *const u8, -) -> Result<*mut c_void, ReprError> -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result<*mut c_void, ReprError> { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; Ok(buf as *mut c_void) } #[op2(fast, stack_trace)] -pub fn op_ffi_ptr_of_exact( +pub fn op_ffi_ptr_of_exact( state: &mut OpState, buf: v8::Local, -) -> Result<*mut c_void, ReprError> -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result<*mut c_void, ReprError> { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; let Some(buf) = buf.get_backing_store() else { return Ok(0 as _); @@ -117,16 +104,13 @@ where } #[op2(fast, stack_trace)] -pub fn op_ffi_ptr_offset( +pub fn op_ffi_ptr_offset( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result<*mut c_void, ReprError> -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result<*mut c_void, ReprError> { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidOffset); @@ -148,32 +132,26 @@ unsafe extern "C" fn noop_deleter_callback( #[op2(fast, stack_trace)] #[bigint] -pub fn op_ffi_ptr_value( +pub fn op_ffi_ptr_value( state: &mut OpState, ptr: *mut c_void, -) -> Result -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; Ok(ptr as usize) } #[op2(stack_trace)] -pub fn op_ffi_get_buf( +pub fn op_ffi_get_buf<'scope>( scope: &mut v8::PinScope<'scope, '_>, state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, #[number] len: usize, -) -> Result, ReprError> -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result, ReprError> { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidArrayBuffer); @@ -194,18 +172,15 @@ where } #[op2(stack_trace)] -pub fn op_ffi_buf_copy_into( +pub fn op_ffi_buf_copy_into( state: &mut OpState, src: *mut c_void, #[number] offset: isize, #[anybuffer] dst: &mut [u8], #[number] len: usize, -) -> Result<(), ReprError> -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result<(), ReprError> { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if src.is_null() { Err(ReprError::InvalidArrayBuffer) @@ -224,17 +199,14 @@ where } #[op2(stack_trace)] -pub fn op_ffi_cstr_read( +pub fn op_ffi_cstr_read<'scope>( scope: &mut v8::PinScope<'scope, '_>, state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result, ReprError> -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result, ReprError> { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidCString); @@ -250,16 +222,13 @@ where } #[op2(fast, stack_trace)] -pub fn op_ffi_read_bool( +pub fn op_ffi_read_bool( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidBool); @@ -270,16 +239,13 @@ where } #[op2(fast, stack_trace)] -pub fn op_ffi_read_u8( +pub fn op_ffi_read_u8( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidU8); @@ -292,16 +258,13 @@ where } #[op2(fast, stack_trace)] -pub fn op_ffi_read_i8( +pub fn op_ffi_read_i8( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidI8); @@ -314,16 +277,13 @@ where } #[op2(fast, stack_trace)] -pub fn op_ffi_read_u16( +pub fn op_ffi_read_u16( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidU16); @@ -336,16 +296,13 @@ where } #[op2(fast, stack_trace)] -pub fn op_ffi_read_i16( +pub fn op_ffi_read_i16( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidI16); @@ -358,16 +315,13 @@ where } #[op2(fast, stack_trace)] -pub fn op_ffi_read_u32( +pub fn op_ffi_read_u32( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidU32); @@ -378,16 +332,13 @@ where } #[op2(fast, stack_trace)] -pub fn op_ffi_read_i32( +pub fn op_ffi_read_i32( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidI32); @@ -399,18 +350,15 @@ where #[op2(fast, stack_trace)] #[bigint] -pub fn op_ffi_read_u64( +pub fn op_ffi_read_u64( state: &mut OpState, ptr: *mut c_void, // Note: The representation of 64-bit integers is function-wide. We cannot // choose to take this parameter as a number while returning a bigint. #[bigint] offset: isize, -) -> Result -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidU64); @@ -425,18 +373,15 @@ where #[op2(fast, stack_trace)] #[bigint] -pub fn op_ffi_read_i64( +pub fn op_ffi_read_i64( state: &mut OpState, ptr: *mut c_void, // Note: The representation of 64-bit integers is function-wide. We cannot // choose to take this parameter as a number while returning a bigint. #[bigint] offset: isize, -) -> Result -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidI64); @@ -450,16 +395,13 @@ where } #[op2(fast, stack_trace)] -pub fn op_ffi_read_f32( +pub fn op_ffi_read_f32( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidF32); @@ -470,16 +412,13 @@ where } #[op2(fast, stack_trace)] -pub fn op_ffi_read_f64( +pub fn op_ffi_read_f64( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidF64); @@ -490,16 +429,13 @@ where } #[op2(fast, stack_trace)] -pub fn op_ffi_read_ptr( +pub fn op_ffi_read_ptr( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result<*mut c_void, ReprError> -where - FP: FfiPermissions + 'static, -{ - let permissions = state.borrow_mut::(); - permissions.check_partial_no_path()?; +) -> Result<*mut c_void, ReprError> { + let permissions = state.borrow_mut::(); + permissions.check_ffi_partial_no_path()?; if ptr.is_null() { return Err(ReprError::InvalidPointer); diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 795163dd2be16d..55271bf612fa73 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -38,7 +38,7 @@ pub fn create_runtime_snapshot( deno_websocket::deno_websocket::lazy_init::(), deno_webstorage::deno_webstorage::lazy_init(), deno_crypto::deno_crypto::lazy_init(), - deno_ffi::deno_ffi::lazy_init::(), + deno_ffi::deno_ffi::lazy_init(), deno_net::deno_net::lazy_init::(), deno_tls::deno_tls::lazy_init(), deno_kv::deno_kv::lazy_init::>( diff --git a/runtime/snapshot_info.rs b/runtime/snapshot_info.rs index f9344c4c5d90c7..782d443457c4ed 100644 --- a/runtime/snapshot_info.rs +++ b/runtime/snapshot_info.rs @@ -33,19 +33,6 @@ impl deno_web::TimersPermission for Permissions { } } -impl deno_ffi::FfiPermissions for Permissions { - fn check_partial_no_path(&mut self) -> Result<(), PermissionCheckError> { - unreachable!("snapshotting!") - } - - fn check_partial_with_path<'a>( - &mut self, - _path: Cow<'a, Path>, - ) -> Result, PermissionCheckError> { - unreachable!("snapshotting!") - } -} - impl deno_napi::NapiPermissions for Permissions { fn check<'a>( &mut self, @@ -192,7 +179,7 @@ pub fn get_extensions_in_snapshot() -> Vec { deno_websocket::deno_websocket::init::(), deno_webstorage::deno_webstorage::init(None), deno_crypto::deno_crypto::init(None), - deno_ffi::deno_ffi::init::(None), + deno_ffi::deno_ffi::init(None), deno_net::deno_net::init::(None, None), deno_tls::deno_tls::init(), deno_kv::deno_kv::init( diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 8fb9673dc4f3e8..c49a7db6e6606c 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -542,9 +542,7 @@ impl WebWorker { deno_websocket::deno_websocket::init::(), deno_webstorage::deno_webstorage::init(None).disable(), deno_crypto::deno_crypto::init(options.seed), - deno_ffi::deno_ffi::init::( - services.deno_rt_native_addon_loader.clone(), - ), + deno_ffi::deno_ffi::init(services.deno_rt_native_addon_loader.clone()), deno_net::deno_net::init::( services.root_cert_store_provider.clone(), options.unsafely_ignore_certificate_errors.clone(), diff --git a/runtime/worker.rs b/runtime/worker.rs index c749c4a06beb69..bc179b5f9194b0 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -554,9 +554,7 @@ impl MainWorker { options.origin_storage_dir.clone(), ), deno_crypto::deno_crypto::args(options.seed), - deno_ffi::deno_ffi::args::( - services.deno_rt_native_addon_loader.clone(), - ), + deno_ffi::deno_ffi::args(services.deno_rt_native_addon_loader.clone()), deno_net::deno_net::args::( services.root_cert_store_provider.clone(), options.unsafely_ignore_certificate_errors.clone(), @@ -1060,7 +1058,7 @@ fn common_extensions< deno_websocket::deno_websocket::lazy_init::(), deno_webstorage::deno_webstorage::lazy_init(), deno_crypto::deno_crypto::lazy_init(), - deno_ffi::deno_ffi::lazy_init::(), + deno_ffi::deno_ffi::lazy_init(), deno_net::deno_net::lazy_init::(), deno_tls::deno_tls::init(), deno_kv::deno_kv::lazy_init::(), From f4ee11caf652b080b7884323732b832e3dca6198 Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Thu, 13 Nov 2025 13:29:49 -0800 Subject: [PATCH 03/13] remove permissions trait from deno_net --- Cargo.lock | 1 + ext/net/Cargo.toml | 3 + ext/net/lib.rs | 114 +++------- ext/net/ops.rs | 180 +++++----------- ext/net/ops_tls.rs | 29 +-- ext/net/ops_unix.rs | 64 ++---- ext/net/quic.rs | 38 ++-- runtime/permissions.rs | 203 +----------------- runtime/permissions/lib.rs | 2 + .../permissions/runtime_descriptor_parser.rs | 201 +++++++++++++++++ runtime/snapshot.rs | 2 +- runtime/snapshot_info.rs | 30 +-- runtime/web_worker.rs | 2 +- runtime/worker.rs | 4 +- 14 files changed, 345 insertions(+), 528 deletions(-) create mode 100644 runtime/permissions/runtime_descriptor_parser.rs diff --git a/Cargo.lock b/Cargo.lock index 50c752fdf693bf..e29957a64c49c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2434,6 +2434,7 @@ dependencies = [ "serde", "sha2", "socket2 0.5.5", + "sys_traits", "thiserror 2.0.12", "tokio", "tokio-vsock", diff --git a/ext/net/Cargo.toml b/ext/net/Cargo.toml index a412d2d14a84fe..7895c5ea0eb3b9 100644 --- a/ext/net/Cargo.toml +++ b/ext/net/Cargo.toml @@ -37,3 +37,6 @@ web-transport-proto.workspace = true [target.'cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))'.dependencies] tokio-vsock.workspace = true + +[dev-dependencies] +sys_traits = { workspace = true, features = ["real", "libc"] } diff --git a/ext/net/lib.rs b/ext/net/lib.rs index 5812c2bacc34fa..5e136c3b189d0e 100644 --- a/ext/net/lib.rs +++ b/ext/net/lib.rs @@ -11,81 +11,16 @@ pub mod resolve_addr; pub mod tcp; pub mod tunnel; -use std::borrow::Cow; -use std::path::Path; use std::sync::Arc; use deno_core::OpState; use deno_features::FeatureChecker; -use deno_permissions::CheckedPath; -use deno_permissions::OpenAccessKind; -use deno_permissions::PermissionCheckError; use deno_tls::RootCertStoreProvider; use deno_tls::rustls::RootCertStore; pub use quic::QuicError; pub const UNSTABLE_FEATURE_NAME: &str = "net"; -pub trait NetPermissions { - fn check_net>( - &mut self, - host: &(T, Option), - api_name: &str, - ) -> Result<(), PermissionCheckError>; - #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] - fn check_open<'a>( - &mut self, - path: Cow<'a, Path>, - open_access: OpenAccessKind, - api_name: &str, - ) -> Result, PermissionCheckError>; - #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] - fn check_vsock( - &mut self, - cid: u32, - port: u32, - api_name: &str, - ) -> Result<(), PermissionCheckError>; -} - -impl NetPermissions for deno_permissions::PermissionsContainer { - #[inline(always)] - fn check_net>( - &mut self, - host: &(T, Option), - api_name: &str, - ) -> Result<(), PermissionCheckError> { - deno_permissions::PermissionsContainer::check_net(self, host, api_name) - } - - #[inline(always)] - fn check_open<'a>( - &mut self, - path: Cow<'a, Path>, - open_access: OpenAccessKind, - api_name: &str, - ) -> Result, PermissionCheckError> { - deno_permissions::PermissionsContainer::check_open( - self, - path, - open_access, - Some(api_name), - ) - } - - #[inline(always)] - fn check_vsock( - &mut self, - cid: u32, - port: u32, - api_name: &str, - ) -> Result<(), PermissionCheckError> { - deno_permissions::PermissionsContainer::check_net_vsock( - self, cid, port, api_name, - ) - } -} - /// Helper for checking unstable features. Used for sync ops. fn check_unstable(state: &OpState, api_name: &str) { state @@ -117,16 +52,15 @@ pub struct UnsafelyIgnoreCertificateErrors(pub Option>); deno_core::extension!(deno_net, deps = [ deno_web ], - parameters = [ P: NetPermissions ], ops = [ ops::op_net_accept_tcp, ops::op_net_get_ips_from_perm_token, - ops::op_net_connect_tcp

, - ops::op_net_listen_tcp

, - ops::op_net_listen_udp

, - ops::op_node_unstable_net_listen_udp

, + ops::op_net_connect_tcp, + ops::op_net_listen_tcp, + ops::op_net_listen_udp, + ops::op_node_unstable_net_listen_udp, ops::op_net_recv_udp, - ops::op_net_send_udp

, + ops::op_net_send_udp, ops::op_net_join_multi_v4_udp, ops::op_net_join_multi_v6_udp, ops::op_net_leave_multi_v4_udp, @@ -135,12 +69,12 @@ deno_core::extension!(deno_net, ops::op_net_set_multi_ttl_udp, ops::op_net_set_broadcast_udp, ops::op_net_validate_multicast, - ops::op_dns_resolve

, + ops::op_dns_resolve, ops::op_set_nodelay, ops::op_set_keepalive, - ops::op_net_listen_vsock

, + ops::op_net_listen_vsock, ops::op_net_accept_vsock, - ops::op_net_connect_vsock

, + ops::op_net_connect_vsock, ops::op_net_listen_tunnel, ops::op_net_accept_tunnel, @@ -150,19 +84,19 @@ deno_core::extension!(deno_net, ops_tls::op_tls_cert_resolver_poll, ops_tls::op_tls_cert_resolver_resolve, ops_tls::op_tls_cert_resolver_resolve_error, - ops_tls::op_tls_start

, - ops_tls::op_net_connect_tls

, - ops_tls::op_net_listen_tls

, + ops_tls::op_tls_start, + ops_tls::op_net_connect_tls, + ops_tls::op_net_listen_tls, ops_tls::op_net_accept_tls, ops_tls::op_tls_handshake, ops_unix::op_net_accept_unix, - ops_unix::op_net_connect_unix

, - ops_unix::op_net_listen_unix

, - ops_unix::op_net_listen_unixpacket

, - ops_unix::op_node_unstable_net_listen_unixpacket

, + ops_unix::op_net_connect_unix, + ops_unix::op_net_listen_unix, + ops_unix::op_net_listen_unixpacket, + ops_unix::op_node_unstable_net_listen_unixpacket, ops_unix::op_net_recv_unixpacket, - ops_unix::op_net_send_unixpacket

, + ops_unix::op_net_send_unixpacket, quic::op_quic_connecting_0rtt, quic::op_quic_connecting_1rtt, @@ -180,8 +114,8 @@ deno_core::extension!(deno_net, quic::op_quic_connection_read_datagram, quic::op_quic_connection_send_datagram, quic::op_quic_endpoint_close, - quic::op_quic_endpoint_connect

, - quic::op_quic_endpoint_create

, + quic::op_quic_endpoint_connect, + quic::op_quic_endpoint_create, quic::op_quic_endpoint_get_addr, quic::op_quic_endpoint_listen, quic::op_quic_incoming_accept, @@ -237,7 +171,7 @@ mod ops_unix { )) } }; - ($name:ident

) => { + ($name:ident) => { #[op2(fast)] pub fn $name() -> Result<(), std::io::Error> { let error_msg = format!( @@ -253,10 +187,10 @@ mod ops_unix { } stub_op!(op_net_accept_unix); - stub_op!(op_net_connect_unix

); - stub_op!(op_net_listen_unix

); - stub_op!(op_net_listen_unixpacket

); - stub_op!(op_node_unstable_net_listen_unixpacket

); + stub_op!(op_net_connect_unix); + stub_op!(op_net_listen_unix); + stub_op!(op_net_listen_unixpacket); + stub_op!(op_node_unstable_net_listen_unixpacket); stub_op!(op_net_recv_unixpacket); - stub_op!(op_net_send_unixpacket

); + stub_op!(op_net_send_unixpacket); } diff --git a/ext/net/ops.rs b/ext/net/ops.rs index fde2c92a6185ae..e7b4c6727b60e7 100644 --- a/ext/net/ops.rs +++ b/ext/net/ops.rs @@ -8,6 +8,12 @@ use std::net::SocketAddr; use std::rc::Rc; use std::str::FromStr; +use crate::io::TcpStreamResource; +use crate::raw::NetworkListenerResource; +use crate::resolve_addr::resolve_addr; +use crate::resolve_addr::resolve_addr_sync; +use crate::tcp::TcpListener; +use crate::tunnel::TunnelAddr; use deno_core::AsyncRefCell; use deno_core::ByteString; use deno_core::CancelFuture; @@ -19,6 +25,7 @@ use deno_core::RcRef; use deno_core::Resource; use deno_core::ResourceId; use deno_core::op2; +use deno_permissions::PermissionsContainer; use hickory_proto::ProtoError; use hickory_proto::ProtoErrorKind; use hickory_proto::rr::record_data::RData; @@ -40,14 +47,6 @@ use socket2::Type; use tokio::net::TcpStream; use tokio::net::UdpSocket; -use crate::NetPermissions; -use crate::io::TcpStreamResource; -use crate::raw::NetworkListenerResource; -use crate::resolve_addr::resolve_addr; -use crate::resolve_addr::resolve_addr_sync; -use crate::tcp::TcpListener; -use crate::tunnel::TunnelAddr; - pub type Fd = u32; #[derive(Serialize, Clone, Debug)] @@ -248,18 +247,15 @@ pub async fn op_net_recv_udp( #[op2(async, stack_trace)] #[number] -pub async fn op_net_send_udp( +pub async fn op_net_send_udp( state: Rc>, #[smi] rid: ResourceId, #[serde] addr: IpAddr, #[buffer] zero_copy: JsBuffer, -) -> Result -where - NP: NetPermissions + 'static, -{ +) -> Result { { let mut s = state.borrow_mut(); - s.borrow_mut::().check_net( + s.borrow_mut::().check_net( &(&addr.hostname, Some(addr.port)), "Deno.DatagramConn.send()", )?; @@ -478,29 +474,22 @@ pub fn op_net_get_ips_from_perm_token( #[op2(async, stack_trace)] #[serde] -pub async fn op_net_connect_tcp( +pub async fn op_net_connect_tcp( state: Rc>, #[serde] addr: IpAddr, #[cppgc] net_perm_token: Option<&NetPermToken>, #[smi] resource_abort_id: Option, -) -> Result<(ResourceId, IpAddr, IpAddr), NetError> -where - NP: NetPermissions + 'static, -{ - op_net_connect_tcp_inner::(state, addr, net_perm_token, resource_abort_id) - .await +) -> Result<(ResourceId, IpAddr, IpAddr), NetError> { + op_net_connect_tcp_inner(state, addr, net_perm_token, resource_abort_id).await } #[inline] -pub async fn op_net_connect_tcp_inner( +pub async fn op_net_connect_tcp_inner( state: Rc>, addr: IpAddr, net_perm_token: Option<&NetPermToken>, resource_abort_id: Option, -) -> Result<(ResourceId, IpAddr, IpAddr), NetError> -where - NP: NetPermissions + 'static, -{ +) -> Result<(ResourceId, IpAddr, IpAddr), NetError> { { let mut state_ = state.borrow_mut(); // If token exists and the address matches to its resolved ips, @@ -510,7 +499,7 @@ where _ => addr.hostname.clone(), }; state_ - .borrow_mut::() + .borrow_mut::() .check_net(&(&hostname_to_check, Some(addr.port)), "Deno.connect()")?; } @@ -572,21 +561,18 @@ impl Resource for UdpSocketResource { #[op2(stack_trace)] #[serde] -pub fn op_net_listen_tcp( +pub fn op_net_listen_tcp( state: &mut OpState, #[serde] addr: IpAddr, reuse_port: bool, load_balanced: bool, tcp_backlog: i32, -) -> Result<(ResourceId, IpAddr), NetError> -where - NP: NetPermissions + 'static, -{ +) -> Result<(ResourceId, IpAddr), NetError> { if reuse_port { super::check_unstable(state, "Deno.listen({ reusePort: true })"); } state - .borrow_mut::() + .borrow_mut::() .check_net(&(&addr.hostname, Some(addr.port)), "Deno.listen()")?; let addr = resolve_addr_sync(&addr.hostname, addr.port)? .next() @@ -604,17 +590,14 @@ where Ok((rid, IpAddr::from(local_addr))) } -fn net_listen_udp( +fn net_listen_udp( state: &mut OpState, addr: IpAddr, reuse_address: bool, loopback: bool, -) -> Result<(ResourceId, IpAddr), NetError> -where - NP: NetPermissions + 'static, -{ +) -> Result<(ResourceId, IpAddr), NetError> { state - .borrow_mut::() + .borrow_mut::() .check_net(&(&addr.hostname, Some(addr.port)), "Deno.listenDatagram()")?; let addr = resolve_addr_sync(&addr.hostname, addr.port)? .next() @@ -673,44 +656,35 @@ where #[op2(stack_trace)] #[serde] -pub fn op_net_listen_udp( +pub fn op_net_listen_udp( state: &mut OpState, #[serde] addr: IpAddr, reuse_address: bool, loopback: bool, -) -> Result<(ResourceId, IpAddr), NetError> -where - NP: NetPermissions + 'static, -{ +) -> Result<(ResourceId, IpAddr), NetError> { super::check_unstable(state, "Deno.listenDatagram"); - net_listen_udp::(state, addr, reuse_address, loopback) + net_listen_udp(state, addr, reuse_address, loopback) } #[op2(stack_trace)] #[serde] -pub fn op_node_unstable_net_listen_udp( +pub fn op_node_unstable_net_listen_udp( state: &mut OpState, #[serde] addr: IpAddr, reuse_address: bool, loopback: bool, -) -> Result<(ResourceId, IpAddr), NetError> -where - NP: NetPermissions + 'static, -{ - net_listen_udp::(state, addr, reuse_address, loopback) +) -> Result<(ResourceId, IpAddr), NetError> { + net_listen_udp(state, addr, reuse_address, loopback) } #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))] #[op2(async, stack_trace)] #[serde] -pub async fn op_net_connect_vsock( +pub async fn op_net_connect_vsock( state: Rc>, #[smi] cid: u32, #[smi] port: u32, -) -> Result<(ResourceId, (u32, u32), (u32, u32)), NetError> -where - NP: NetPermissions + 'static, -{ +) -> Result<(ResourceId, (u32, u32), (u32, u32)), NetError> { use std::sync::Arc; use deno_features::FeatureChecker; @@ -722,11 +696,10 @@ where .borrow::>() .check_or_exit("vsock", "Deno.connect"); - state.borrow_mut().borrow_mut::().check_vsock( - cid, - port, - "Deno.connect()", - )?; + state + .borrow_mut() + .borrow_mut::() + .check_net_vsock(cid, port, "Deno.connect()")?; let addr = VsockAddr::new(cid, port); let vsock_stream = VsockStream::connect(addr).await?; @@ -755,24 +728,18 @@ where )))] #[op2] #[serde] -pub fn op_net_connect_vsock() -> Result<(), NetError> -where - NP: NetPermissions + 'static, -{ +pub fn op_net_connect_vsock() -> Result<(), NetError> { Err(NetError::VsockUnsupported) } #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))] #[op2(stack_trace)] #[serde] -pub fn op_net_listen_vsock( +pub fn op_net_listen_vsock( state: &mut OpState, #[smi] cid: u32, #[smi] port: u32, -) -> Result<(ResourceId, u32, u32), NetError> -where - NP: NetPermissions + 'static, -{ +) -> Result<(ResourceId, u32, u32), NetError> { use std::sync::Arc; use deno_features::FeatureChecker; @@ -783,9 +750,11 @@ where .borrow::>() .check_or_exit("vsock", "Deno.listen"); - state - .borrow_mut::() - .check_vsock(cid, port, "Deno.listen()")?; + state.borrow_mut::().check_net_vsock( + cid, + port, + "Deno.listen()", + )?; let addr = VsockAddr::new(cid, port); let listener = VsockListener::bind(addr)?; @@ -802,10 +771,7 @@ where )))] #[op2] #[serde] -pub fn op_net_listen_vsock() -> Result<(), NetError> -where - NP: NetPermissions + 'static, -{ +pub fn op_net_listen_vsock() -> Result<(), NetError> { Err(NetError::VsockUnsupported) } @@ -984,13 +950,10 @@ pub struct NameServer { #[op2(async, stack_trace)] #[serde] -pub async fn op_dns_resolve( +pub async fn op_dns_resolve( state: Rc>, #[serde] args: ResolveAddrArgs, -) -> Result, NetError> -where - NP: NetPermissions + 'static, -{ +) -> Result, NetError> { let ResolveAddrArgs { query, record_type, @@ -1016,14 +979,14 @@ where { let mut s = state.borrow_mut(); - let perm = s.borrow_mut::(); + let perm = s.borrow_mut::(); // Checks permission against the name servers which will be actually queried. for ns in config.name_servers() { 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()")?; + perm.check_net(&(&ip, Some(port)), "Deno.resolveDns()")?; } } @@ -1207,16 +1170,11 @@ mod tests { use std::net::Ipv4Addr; use std::net::Ipv6Addr; use std::net::ToSocketAddrs; - use std::path::Path; - use std::sync::Arc; use std::sync::Mutex; use deno_core::JsRuntime; use deno_core::RuntimeOptions; use deno_core::futures::FutureExt; - use deno_permissions::CheckedPath; - use deno_permissions::OpenAccessKind; - use deno_permissions::PermissionCheckError; use hickory_proto::rr::Name; use hickory_proto::rr::rdata::SOA; use hickory_proto::rr::rdata::a::A; @@ -1412,36 +1370,6 @@ mod tests { ); } - struct TestPermission {} - - impl NetPermissions for TestPermission { - fn check_net>( - &mut self, - _host: &(T, Option), - _api_name: &str, - ) -> Result<(), PermissionCheckError> { - Ok(()) - } - - fn check_open<'a>( - &mut self, - path: Cow<'a, Path>, - _access_kind: OpenAccessKind, - _api_name: &str, - ) -> Result, PermissionCheckError> { - Ok(CheckedPath::unsafe_new(path)) - } - - fn check_vsock( - &mut self, - _cid: u32, - _port: u32, - _api_name: &str, - ) -> Result<(), PermissionCheckError> { - Ok(()) - } - } - #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn tcp_set_no_delay() { let set_nodelay = Box::new(|state: &mut OpState, rid| { @@ -1483,10 +1411,16 @@ mod tests { } .boxed_local(); + use deno_permissions::RuntimePermissionDescriptorParser; + use std::sync::Arc; + deno_core::extension!( test_ext, state = |state| { - state.put(TestPermission {}); + let parser = Arc::new(RuntimePermissionDescriptorParser::new( + sys_traits::impls::RealSys, + )); + state.put(PermissionsContainer::allow_all(parser)); } ); @@ -1503,10 +1437,8 @@ mod tests { port: server_addr[1].parse().unwrap(), }; - let mut connect_fut = op_net_connect_tcp_inner::( - conn_state, ip_addr, None, None, - ) - .boxed_local(); + let mut connect_fut = + op_net_connect_tcp_inner(conn_state, ip_addr, None, None).boxed_local(); let mut rid = None; tokio::select! { diff --git a/ext/net/ops_tls.rs b/ext/net/ops_tls.rs index c7f40371dc9538..2259e47586e13d 100644 --- a/ext/net/ops_tls.rs +++ b/ext/net/ops_tls.rs @@ -26,6 +26,7 @@ use deno_core::op2; use deno_core::v8; use deno_error::JsErrorBox; use deno_permissions::OpenAccessKind; +use deno_permissions::PermissionsContainer; use deno_tls::ServerConfigProvider; use deno_tls::SocketUse; use deno_tls::TlsClientConfigOptions; @@ -49,7 +50,6 @@ use tokio::io::AsyncWriteExt; use tokio::net::TcpStream; use crate::DefaultTlsOptions; -use crate::NetPermissions; use crate::UnsafelyIgnoreCertificateErrors; use crate::io::TcpStreamResource; use crate::ops::IpAddr; @@ -312,14 +312,11 @@ pub fn op_tls_cert_resolver_resolve_error( #[op2(stack_trace)] #[serde] -pub fn op_tls_start( +pub fn op_tls_start( state: Rc>, #[serde] args: StartTlsArgs, #[cppgc] key_pair: Option<&TlsKeysHolder>, -) -> Result<(ResourceId, IpAddr, IpAddr), NetError> -where - NP: NetPermissions + 'static, -{ +) -> Result<(ResourceId, IpAddr, IpAddr), NetError> { let rid = args.rid; let reject_unauthorized = args.reject_unauthorized.unwrap_or(true); let hostname = match &*args.hostname { @@ -406,15 +403,12 @@ where #[op2(async, stack_trace)] #[serde] -pub async fn op_net_connect_tls( +pub async fn op_net_connect_tls( state: Rc>, #[serde] addr: IpAddr, #[serde] args: ConnectTlsArgs, #[cppgc] key_pair: &TlsKeysHolder, -) -> Result<(ResourceId, IpAddr, IpAddr), NetError> -where - NP: NetPermissions + 'static, -{ +) -> Result<(ResourceId, IpAddr, IpAddr), NetError> { let cert_file = args.cert_file.as_deref(); let unsafely_ignore_certificate_errors = state .borrow() @@ -425,7 +419,7 @@ where let cert_file = { let mut s = state.borrow_mut(); - let permissions = s.borrow_mut::(); + let permissions = s.borrow_mut::(); permissions .check_net(&(&addr.hostname, Some(addr.port)), "Deno.connectTls()") .map_err(NetError::Permission)?; @@ -435,7 +429,7 @@ where .check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::ReadNoFollow, - "Deno.connectTls()", + Some("Deno.connectTls()"), ) .map_err(NetError::Permission)?, ) @@ -519,21 +513,18 @@ pub struct ListenTlsArgs { #[op2(stack_trace)] #[serde] -pub fn op_net_listen_tls( +pub fn op_net_listen_tls( state: &mut OpState, #[serde] addr: IpAddr, #[serde] args: ListenTlsArgs, #[cppgc] keys: &TlsKeysHolder, -) -> Result<(ResourceId, IpAddr), NetError> -where - NP: NetPermissions + 'static, -{ +) -> Result<(ResourceId, IpAddr), NetError> { if args.reuse_port { super::check_unstable(state, "Deno.listenTls({ reusePort: true })"); } { - let permissions = state.borrow_mut::(); + let permissions = state.borrow_mut::(); permissions .check_net(&(&addr.hostname, Some(addr.port)), "Deno.listenTls()") .map_err(NetError::Permission)?; diff --git a/ext/net/ops_unix.rs b/ext/net/ops_unix.rs index dd25323c59d204..ee545678634381 100644 --- a/ext/net/ops_unix.rs +++ b/ext/net/ops_unix.rs @@ -16,13 +16,13 @@ use deno_core::Resource; use deno_core::ResourceId; use deno_core::op2; use deno_permissions::OpenAccessKind; +use deno_permissions::PermissionsContainer; use serde::Deserialize; use serde::Serialize; use tokio::net::UnixDatagram; use tokio::net::UnixListener; pub use tokio::net::UnixStream; -use crate::NetPermissions; use crate::io::UnixStreamResource; use crate::ops::NetError; use crate::raw::NetworkListenerResource; @@ -91,21 +91,18 @@ pub async fn op_net_accept_unix( #[op2(async, stack_trace)] #[serde] -pub async fn op_net_connect_unix( +pub async fn op_net_connect_unix( state: Rc>, #[string] address_path: String, -) -> Result<(ResourceId, Option, Option), NetError> -where - NP: NetPermissions + 'static, -{ +) -> Result<(ResourceId, Option, Option), NetError> { let address_path = { let mut state = state.borrow_mut(); state - .borrow_mut::() + .borrow_mut::() .check_open( Cow::Owned(PathBuf::from(address_path)), OpenAccessKind::ReadWriteNoFollow, - "Deno.connect()", + Some("Deno.connect()"), ) .map_err(NetError::Permission)? }; @@ -145,22 +142,19 @@ pub async fn op_net_recv_unixpacket( #[op2(async, stack_trace)] #[number] -pub async fn op_net_send_unixpacket( +pub async fn op_net_send_unixpacket( state: Rc>, #[smi] rid: ResourceId, #[string] address_path: String, #[buffer] zero_copy: JsBuffer, -) -> Result -where - NP: NetPermissions + 'static, -{ +) -> Result { let address_path = { let mut s = state.borrow_mut(); - s.borrow_mut::() + s.borrow_mut::() .check_open( Cow::Owned(PathBuf::from(address_path)), OpenAccessKind::WriteNoFollow, - "Deno.DatagramConn.send()", + Some("Deno.DatagramConn.send()"), ) .map_err(NetError::Permission)? }; @@ -180,21 +174,18 @@ where #[op2(stack_trace)] #[serde] -pub fn op_net_listen_unix( +pub fn op_net_listen_unix( state: &mut OpState, #[string] address_path: &str, #[string] api_name: &str, -) -> Result<(ResourceId, Option), NetError> -where - NP: NetPermissions + 'static, -{ - let permissions = state.borrow_mut::(); +) -> Result<(ResourceId, Option), NetError> { + let permissions = state.borrow_mut::(); let api_call_expr = format!("{}()", api_name); let address_path = permissions .check_open( Cow::Borrowed(Path::new(address_path)), OpenAccessKind::ReadWriteNoFollow, - &api_call_expr, + Some(&api_call_expr), ) .map_err(NetError::Permission)?; let listener = UnixListener::bind(address_path)?; @@ -205,19 +196,16 @@ where Ok((rid, pathname)) } -pub fn net_listen_unixpacket( +pub fn net_listen_unixpacket( state: &mut OpState, address_path: &str, -) -> Result<(ResourceId, Option), NetError> -where - NP: NetPermissions + 'static, -{ - let permissions = state.borrow_mut::(); +) -> Result<(ResourceId, Option), NetError> { + let permissions = state.borrow_mut::(); let address_path = permissions .check_open( Cow::Borrowed(Path::new(address_path)), OpenAccessKind::ReadWriteNoFollow, - "Deno.listenDatagram()", + Some("Deno.listenDatagram()"), ) .map_err(NetError::Permission)?; let socket = UnixDatagram::bind(address_path)?; @@ -233,27 +221,21 @@ where #[op2(stack_trace)] #[serde] -pub fn op_net_listen_unixpacket( +pub fn op_net_listen_unixpacket( state: &mut OpState, #[string] path: &str, -) -> Result<(ResourceId, Option), NetError> -where - NP: NetPermissions + 'static, -{ +) -> Result<(ResourceId, Option), NetError> { super::check_unstable(state, "Deno.listenDatagram"); - net_listen_unixpacket::(state, path) + net_listen_unixpacket(state, path) } #[op2(stack_trace)] #[serde] -pub fn op_node_unstable_net_listen_unixpacket( +pub fn op_node_unstable_net_listen_unixpacket( state: &mut OpState, #[string] path: &str, -) -> Result<(ResourceId, Option), NetError> -where - NP: NetPermissions + 'static, -{ - net_listen_unixpacket::(state, path) +) -> Result<(ResourceId, Option), NetError> { + net_listen_unixpacket(state, path) } pub fn pathstring(pathname: &Path) -> Result { diff --git a/ext/net/quic.rs b/ext/net/quic.rs index dd89933b9547bf..abde04d124a2f0 100644 --- a/ext/net/quic.rs +++ b/ext/net/quic.rs @@ -34,6 +34,7 @@ use deno_core::op2; use deno_error::JsError; use deno_error::JsErrorBox; use deno_permissions::PermissionCheckError; +use deno_permissions::PermissionsContainer; use deno_tls::SocketUse; use deno_tls::TlsClientConfigOptions; use deno_tls::TlsError; @@ -49,7 +50,6 @@ use serde::Deserialize; use serde::Serialize; use crate::DefaultTlsOptions; -use crate::NetPermissions; use crate::UnsafelyIgnoreCertificateErrors; use crate::resolve_addr::resolve_addr_sync; @@ -227,23 +227,23 @@ unsafe impl GarbageCollected for EndpointResource { #[op2] #[cppgc] -pub(crate) fn op_quic_endpoint_create( +pub(crate) fn op_quic_endpoint_create( state: Rc>, #[serde] addr: Addr, can_listen: bool, -) -> Result -where - NP: NetPermissions + 'static, -{ +) -> Result { let addr = resolve_addr_sync(&addr.hostname, addr.port)? .next() .ok_or_else(|| QuicError::UnableToResolve)?; if can_listen { - state.borrow_mut().borrow_mut::().check_net( - &(&addr.ip().to_string(), Some(addr.port())), - "new Deno.QuicEndpoint()", - )?; + state + .borrow_mut() + .borrow_mut::() + .check_net( + &(&addr.ip().to_string(), Some(addr.port())), + "new Deno.QuicEndpoint()", + )? } else { // If this is not a can-listen, assert that we will bind to an ephemeral port. assert_eq!( @@ -540,20 +540,20 @@ struct CertificateHash { #[op2] #[cppgc] -pub(crate) fn op_quic_endpoint_connect( +pub(crate) fn op_quic_endpoint_connect( state: Rc>, #[cppgc] endpoint: &EndpointResource, #[serde] args: ConnectArgs, #[serde] transport_config: TransportConfig, #[cppgc] key_pair: &TlsKeysHolder, -) -> Result -where - NP: NetPermissions + 'static, -{ - state.borrow_mut().borrow_mut::().check_net( - &(&args.addr.hostname, Some(args.addr.port)), - "Deno.connectQuic()", - )?; +) -> Result { + state + .borrow_mut() + .borrow_mut::() + .check_net( + &(&args.addr.hostname, Some(args.addr.port)), + "Deno.connectQuic()", + )?; let sock_addr = resolve_addr_sync(&args.addr.hostname, args.addr.port)? .next() diff --git a/runtime/permissions.rs b/runtime/permissions.rs index 17042cc1d99eda..faa5b2f33758c6 100644 --- a/runtime/permissions.rs +++ b/runtime/permissions.rs @@ -1,203 +1,2 @@ // Copyright 2018-2025 the Deno authors. MIT license. - -use std::borrow::Cow; -use std::path::Path; -use std::path::PathBuf; - -use deno_permissions::AllowRunDescriptor; -use deno_permissions::AllowRunDescriptorParseResult; -use deno_permissions::DenyRunDescriptor; -use deno_permissions::EnvDescriptor; -use deno_permissions::FfiDescriptor; -use deno_permissions::ImportDescriptor; -use deno_permissions::NetDescriptor; -use deno_permissions::PathDescriptor; -use deno_permissions::PathQueryDescriptor; -use deno_permissions::PathResolveError; -use deno_permissions::ReadDescriptor; -use deno_permissions::RunDescriptorParseError; -use deno_permissions::RunQueryDescriptor; -use deno_permissions::SpecialFilePathQueryDescriptor; -use deno_permissions::SysDescriptor; -use deno_permissions::SysDescriptorParseError; -use deno_permissions::WriteDescriptor; - -#[sys_traits::auto_impl] -pub trait RuntimePermissionDescriptorParserSys: - deno_permissions::which::WhichSys + sys_traits::FsCanonicalize + Send + Sync -{ -} - -#[derive(Debug)] -pub struct RuntimePermissionDescriptorParser< - TSys: RuntimePermissionDescriptorParserSys, -> { - sys: TSys, -} - -impl - RuntimePermissionDescriptorParser -{ - pub fn new(sys: TSys) -> Self { - Self { sys } - } - - fn resolve_cwd(&self) -> Result { - self - .sys - .env_current_dir() - .map_err(PathResolveError::CwdResolve) - } - - fn parse_path_descriptor( - &self, - path: Cow<'_, Path>, - ) -> Result { - PathDescriptor::new(&self.sys, path) - } -} - -impl - deno_permissions::PermissionDescriptorParser - for RuntimePermissionDescriptorParser -{ - fn parse_read_descriptor( - &self, - text: &str, - ) -> Result { - Ok(ReadDescriptor( - self.parse_path_descriptor(Cow::Borrowed(Path::new(text)))?, - )) - } - - fn parse_write_descriptor( - &self, - text: &str, - ) -> Result { - Ok(WriteDescriptor( - self.parse_path_descriptor(Cow::Borrowed(Path::new(text)))?, - )) - } - - fn parse_net_descriptor( - &self, - text: &str, - ) -> Result { - NetDescriptor::parse_for_list(text) - } - - fn parse_import_descriptor( - &self, - text: &str, - ) -> Result { - ImportDescriptor::parse_for_list(text) - } - - fn parse_env_descriptor( - &self, - text: &str, - ) -> Result { - if text.is_empty() { - Err(deno_permissions::EnvDescriptorParseError) - } else { - Ok(EnvDescriptor::new(Cow::Borrowed(text))) - } - } - - fn parse_sys_descriptor( - &self, - text: &str, - ) -> Result { - if text.is_empty() { - Err(SysDescriptorParseError::Empty) - } else { - Ok(SysDescriptor::parse(text.to_string())?) - } - } - - fn parse_allow_run_descriptor( - &self, - text: &str, - ) -> Result { - Ok(AllowRunDescriptor::parse( - text, - &self.resolve_cwd()?, - &self.sys, - )?) - } - - fn parse_deny_run_descriptor( - &self, - text: &str, - ) -> Result { - Ok(DenyRunDescriptor::parse(text, &self.resolve_cwd()?)) - } - - fn parse_ffi_descriptor( - &self, - text: &str, - ) -> Result { - Ok(FfiDescriptor( - self.parse_path_descriptor(Cow::Borrowed(Path::new(text)))?, - )) - } - - // queries - - fn parse_path_query<'a>( - &self, - path: Cow<'a, Path>, - ) -> Result, PathResolveError> { - PathQueryDescriptor::new(&self.sys, path) - } - - fn parse_special_file_descriptor<'a>( - &self, - path: PathQueryDescriptor<'a>, - ) -> Result, PathResolveError> { - SpecialFilePathQueryDescriptor::parse(&self.sys, path) - } - - fn parse_net_query( - &self, - text: &str, - ) -> Result { - NetDescriptor::parse_for_query(text) - } - - fn parse_run_query<'a>( - &self, - requested: &'a str, - ) -> Result, RunDescriptorParseError> { - if requested.is_empty() { - return Err(RunDescriptorParseError::EmptyRunQuery); - } - RunQueryDescriptor::parse(requested, &self.sys) - .map_err(RunDescriptorParseError::PathResolve) - } -} - -#[cfg(test)] -mod test { - use deno_permissions::PermissionDescriptorParser; - - use super::*; - - #[test] - fn test_handle_empty_value() { - let parser = - RuntimePermissionDescriptorParser::new(sys_traits::impls::RealSys); - assert!(parser.parse_read_descriptor("").is_err()); - assert!(parser.parse_write_descriptor("").is_err()); - assert!(parser.parse_env_descriptor("").is_err()); - assert!(parser.parse_net_descriptor("").is_err()); - assert!(parser.parse_ffi_descriptor("").is_err()); - assert!( - parser - .parse_path_query(Cow::Borrowed(Path::new(""))) - .is_err() - ); - assert!(parser.parse_net_query("").is_err()); - assert!(parser.parse_run_query("").is_err()); - } -} +pub use deno_permissions::RuntimePermissionDescriptorParser; diff --git a/runtime/permissions/lib.rs b/runtime/permissions/lib.rs index 80100338cceb52..51837607eec9e3 100644 --- a/runtime/permissions/lib.rs +++ b/runtime/permissions/lib.rs @@ -35,11 +35,13 @@ use url::Url; pub mod broker; mod ipc_pipe; pub mod prompter; +mod runtime_descriptor_parser; pub mod which; use prompter::MAYBE_CURRENT_STACKTRACE; use prompter::PERMISSION_EMOJI; use prompter::permission_prompt; +pub use runtime_descriptor_parser::RuntimePermissionDescriptorParser; use self::prompter::PromptResponse; use self::which::WhichSys; diff --git a/runtime/permissions/runtime_descriptor_parser.rs b/runtime/permissions/runtime_descriptor_parser.rs new file mode 100644 index 00000000000000..b078547d4de5e9 --- /dev/null +++ b/runtime/permissions/runtime_descriptor_parser.rs @@ -0,0 +1,201 @@ +use std::borrow::Cow; +use std::path::Path; +use std::path::PathBuf; + +use crate::AllowRunDescriptor; +use crate::AllowRunDescriptorParseResult; +use crate::DenyRunDescriptor; +use crate::EnvDescriptor; +use crate::FfiDescriptor; +use crate::ImportDescriptor; +use crate::NetDescriptor; +use crate::PathDescriptor; +use crate::PathQueryDescriptor; +use crate::PathResolveError; +use crate::ReadDescriptor; +use crate::RunDescriptorParseError; +use crate::RunQueryDescriptor; +use crate::SpecialFilePathQueryDescriptor; +use crate::SysDescriptor; +use crate::SysDescriptorParseError; +use crate::WriteDescriptor; + +#[sys_traits::auto_impl] +pub trait RuntimePermissionDescriptorParserSys: + crate::which::WhichSys + sys_traits::FsCanonicalize + Send + Sync +{ +} + +#[derive(Debug)] +pub struct RuntimePermissionDescriptorParser< + TSys: RuntimePermissionDescriptorParserSys, +> { + sys: TSys, +} + +impl + RuntimePermissionDescriptorParser +{ + pub fn new(sys: TSys) -> Self { + Self { sys } + } + + fn resolve_cwd(&self) -> Result { + self + .sys + .env_current_dir() + .map_err(PathResolveError::CwdResolve) + } + + fn parse_path_descriptor( + &self, + path: Cow<'_, Path>, + ) -> Result { + PathDescriptor::new(&self.sys, path) + } +} + +impl + crate::PermissionDescriptorParser + for RuntimePermissionDescriptorParser +{ + fn parse_read_descriptor( + &self, + text: &str, + ) -> Result { + Ok(ReadDescriptor( + self.parse_path_descriptor(Cow::Borrowed(Path::new(text)))?, + )) + } + + fn parse_write_descriptor( + &self, + text: &str, + ) -> Result { + Ok(WriteDescriptor( + self.parse_path_descriptor(Cow::Borrowed(Path::new(text)))?, + )) + } + + fn parse_net_descriptor( + &self, + text: &str, + ) -> Result { + NetDescriptor::parse_for_list(text) + } + + fn parse_import_descriptor( + &self, + text: &str, + ) -> Result { + ImportDescriptor::parse_for_list(text) + } + + fn parse_env_descriptor( + &self, + text: &str, + ) -> Result { + if text.is_empty() { + Err(crate::EnvDescriptorParseError) + } else { + Ok(EnvDescriptor::new(Cow::Borrowed(text))) + } + } + + fn parse_sys_descriptor( + &self, + text: &str, + ) -> Result { + if text.is_empty() { + Err(SysDescriptorParseError::Empty) + } else { + Ok(SysDescriptor::parse(text.to_string())?) + } + } + + fn parse_allow_run_descriptor( + &self, + text: &str, + ) -> Result { + Ok(AllowRunDescriptor::parse( + text, + &self.resolve_cwd()?, + &self.sys, + )?) + } + + fn parse_deny_run_descriptor( + &self, + text: &str, + ) -> Result { + Ok(DenyRunDescriptor::parse(text, &self.resolve_cwd()?)) + } + + fn parse_ffi_descriptor( + &self, + text: &str, + ) -> Result { + Ok(FfiDescriptor( + self.parse_path_descriptor(Cow::Borrowed(Path::new(text)))?, + )) + } + + // queries + + fn parse_path_query<'a>( + &self, + path: Cow<'a, Path>, + ) -> Result, PathResolveError> { + PathQueryDescriptor::new(&self.sys, path) + } + + fn parse_special_file_descriptor<'a>( + &self, + path: PathQueryDescriptor<'a>, + ) -> Result, PathResolveError> { + SpecialFilePathQueryDescriptor::parse(&self.sys, path) + } + + fn parse_net_query( + &self, + text: &str, + ) -> Result { + NetDescriptor::parse_for_query(text) + } + + fn parse_run_query<'a>( + &self, + requested: &'a str, + ) -> Result, RunDescriptorParseError> { + if requested.is_empty() { + return Err(RunDescriptorParseError::EmptyRunQuery); + } + RunQueryDescriptor::parse(requested, &self.sys) + .map_err(RunDescriptorParseError::PathResolve) + } +} + +#[cfg(test)] +mod test { + use crate::PermissionDescriptorParser; + + use super::*; + + #[test] + fn test_handle_empty_value() { + let parser = + RuntimePermissionDescriptorParser::new(sys_traits::impls::RealSys); + assert!(parser.parse_read_descriptor("").is_err()); + assert!(parser.parse_write_descriptor("").is_err()); + assert!(parser.parse_env_descriptor("").is_err()); + assert!(parser.parse_net_descriptor("").is_err()); + assert!(parser.parse_ffi_descriptor("").is_err()); + assert!( + parser + .parse_path_query(Cow::Borrowed(Path::new(""))) + .is_err() + ); + assert!(parser.parse_net_query("").is_err()); + assert!(parser.parse_run_query("").is_err()); + } +} diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 55271bf612fa73..9e355abcb3b9f8 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -39,7 +39,7 @@ pub fn create_runtime_snapshot( deno_webstorage::deno_webstorage::lazy_init(), deno_crypto::deno_crypto::lazy_init(), deno_ffi::deno_ffi::lazy_init(), - deno_net::deno_net::lazy_init::(), + deno_net::deno_net::lazy_init(), deno_tls::deno_tls::lazy_init(), deno_kv::deno_kv::lazy_init::>( ), diff --git a/runtime/snapshot_info.rs b/runtime/snapshot_info.rs index 782d443457c4ed..c817f0519e0cda 100644 --- a/runtime/snapshot_info.rs +++ b/runtime/snapshot_info.rs @@ -77,34 +77,6 @@ impl deno_node::NodePermissions for Permissions { } } -impl deno_net::NetPermissions for Permissions { - fn check_net>( - &mut self, - _host: &(T, Option), - _api_name: &str, - ) -> Result<(), PermissionCheckError> { - unreachable!("snapshotting!") - } - - fn check_open<'a>( - &mut self, - _path: Cow<'a, Path>, - _open_access: OpenAccessKind, - _api_name: &str, - ) -> Result, PermissionCheckError> { - unreachable!("snapshotting!") - } - - fn check_vsock( - &mut self, - _cid: u32, - _port: u32, - _api_name: &str, - ) -> Result<(), PermissionCheckError> { - unreachable!("snapshotting!") - } -} - impl deno_fs::FsPermissions for Permissions { fn check_open<'a>( &self, @@ -180,7 +152,7 @@ pub fn get_extensions_in_snapshot() -> Vec { deno_webstorage::deno_webstorage::init(None), deno_crypto::deno_crypto::init(None), deno_ffi::deno_ffi::init(None), - deno_net::deno_net::init::(None, None), + deno_net::deno_net::init(None, None), deno_tls::deno_tls::init(), deno_kv::deno_kv::init( deno_kv::sqlite::SqliteDbHandler::::new(None, None), diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index c49a7db6e6606c..8ac5ea714a6fa0 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -543,7 +543,7 @@ impl WebWorker { deno_webstorage::deno_webstorage::init(None).disable(), deno_crypto::deno_crypto::init(options.seed), deno_ffi::deno_ffi::init(services.deno_rt_native_addon_loader.clone()), - deno_net::deno_net::init::( + deno_net::deno_net::init( services.root_cert_store_provider.clone(), options.unsafely_ignore_certificate_errors.clone(), ), diff --git a/runtime/worker.rs b/runtime/worker.rs index bc179b5f9194b0..8698f1d2624826 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -555,7 +555,7 @@ impl MainWorker { ), deno_crypto::deno_crypto::args(options.seed), deno_ffi::deno_ffi::args(services.deno_rt_native_addon_loader.clone()), - deno_net::deno_net::args::( + deno_net::deno_net::args( services.root_cert_store_provider.clone(), options.unsafely_ignore_certificate_errors.clone(), ), @@ -1059,7 +1059,7 @@ fn common_extensions< deno_webstorage::deno_webstorage::lazy_init(), deno_crypto::deno_crypto::lazy_init(), deno_ffi::deno_ffi::lazy_init(), - deno_net::deno_net::lazy_init::(), + deno_net::deno_net::lazy_init(), deno_tls::deno_tls::init(), deno_kv::deno_kv::lazy_init::(), deno_cron::deno_cron::init(LocalCronHandler::new()), From 2aa78924fc21e75d2a666a1084aaa50a58887f67 Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Thu, 13 Nov 2025 13:44:48 -0800 Subject: [PATCH 04/13] remove permissions trait from deno_fs --- ext/fs/lib.rs | 181 +++++------------ ext/fs/ops.rs | 416 +++++++++++++++------------------------ runtime/snapshot.rs | 2 +- runtime/snapshot_info.rs | 45 +---- runtime/web_worker.rs | 2 +- runtime/worker.rs | 4 +- 6 files changed, 212 insertions(+), 438 deletions(-) diff --git a/ext/fs/lib.rs b/ext/fs/lib.rs index d2083e171fb2d1..0cb06cefcb9e6e 100644 --- a/ext/fs/lib.rs +++ b/ext/fs/lib.rs @@ -4,16 +4,10 @@ mod interface; mod ops; mod std_fs; -use std::borrow::Cow; -use std::path::Path; - pub use deno_io::fs::FsError; pub use deno_maybe_sync as sync; pub use deno_maybe_sync::MaybeSend; pub use deno_maybe_sync::MaybeSync; -use deno_permissions::CheckedPath; -use deno_permissions::OpenAccessKind; -use deno_permissions::PermissionCheckError; pub use crate::interface::FileSystem; pub use crate::interface::FileSystemRc; @@ -27,138 +21,57 @@ use crate::ops::*; pub use crate::std_fs::RealFs; pub use crate::std_fs::open_options_for_checked_path; -pub trait FsPermissions { - #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] - fn check_open<'a>( - &self, - path: Cow<'a, Path>, - access_kind: OpenAccessKind, - api_name: &str, - ) -> Result, PermissionCheckError>; - #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] - fn check_open_blind<'a>( - &self, - path: Cow<'a, Path>, - access_kind: OpenAccessKind, - display: &str, - api_name: &str, - ) -> Result, PermissionCheckError>; - fn check_read_all(&self, api_name: &str) -> Result<(), PermissionCheckError>; - #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] - fn check_write_partial<'a>( - &self, - path: Cow<'a, Path>, - api_name: &str, - ) -> Result, PermissionCheckError>; - fn check_write_all(&self, api_name: &str) - -> Result<(), PermissionCheckError>; -} - -impl FsPermissions for deno_permissions::PermissionsContainer { - fn check_open<'a>( - &self, - path: Cow<'a, Path>, - access_kind: OpenAccessKind, - api_name: &str, - ) -> Result, PermissionCheckError> { - deno_permissions::PermissionsContainer::check_open( - self, - path, - access_kind, - Some(api_name), - ) - } - - fn check_open_blind<'a>( - &self, - path: Cow<'a, Path>, - access_kind: OpenAccessKind, - display: &str, - api_name: &str, - ) -> Result, PermissionCheckError> { - deno_permissions::PermissionsContainer::check_open_blind( - self, - path, - access_kind, - display, - Some(api_name), - ) - } - - fn check_write_partial<'a>( - &self, - path: Cow<'a, Path>, - api_name: &str, - ) -> Result, PermissionCheckError> { - deno_permissions::PermissionsContainer::check_write_partial( - self, path, api_name, - ) - } - - fn check_read_all(&self, api_name: &str) -> Result<(), PermissionCheckError> { - deno_permissions::PermissionsContainer::check_read_all(self, api_name) - } - - fn check_write_all( - &self, - api_name: &str, - ) -> Result<(), PermissionCheckError> { - deno_permissions::PermissionsContainer::check_write_all(self, api_name) - } -} - pub const UNSTABLE_FEATURE_NAME: &str = "fs"; deno_core::extension!(deno_fs, deps = [ deno_web ], - parameters = [P: FsPermissions], ops = [ op_fs_cwd, op_fs_umask, - op_fs_chdir

, + op_fs_chdir, - op_fs_open_sync

, - op_fs_open_async

, - op_fs_mkdir_sync

, - op_fs_mkdir_async

, - op_fs_chmod_sync

, - op_fs_chmod_async

, - op_fs_chown_sync

, - op_fs_chown_async

, - op_fs_remove_sync

, - op_fs_remove_async

, - op_fs_copy_file_sync

, - op_fs_copy_file_async

, - op_fs_stat_sync

, - op_fs_stat_async

, - op_fs_lstat_sync

, - op_fs_lstat_async

, - op_fs_realpath_sync

, - op_fs_realpath_async

, - op_fs_read_dir_sync

, - op_fs_read_dir_async

, - op_fs_rename_sync

, - op_fs_rename_async

, - op_fs_link_sync

, - op_fs_link_async

, - op_fs_symlink_sync

, - op_fs_symlink_async

, - op_fs_read_link_sync

, - op_fs_read_link_async

, - op_fs_truncate_sync

, - op_fs_truncate_async

, - op_fs_utime_sync

, - op_fs_utime_async

, - op_fs_make_temp_dir_sync

, - op_fs_make_temp_dir_async

, - op_fs_make_temp_file_sync

, - op_fs_make_temp_file_async

, - op_fs_write_file_sync

, - op_fs_write_file_async

, - op_fs_read_file_sync

, - op_fs_read_file_async

, - op_fs_read_file_text_sync

, - op_fs_read_file_text_async

, + op_fs_open_sync, + op_fs_open_async, + op_fs_mkdir_sync, + op_fs_mkdir_async, + op_fs_chmod_sync, + op_fs_chmod_async, + op_fs_chown_sync, + op_fs_chown_async, + op_fs_remove_sync, + op_fs_remove_async, + op_fs_copy_file_sync, + op_fs_copy_file_async, + op_fs_stat_sync, + op_fs_stat_async, + op_fs_lstat_sync, + op_fs_lstat_async, + op_fs_realpath_sync, + op_fs_realpath_async, + op_fs_read_dir_sync, + op_fs_read_dir_async, + op_fs_rename_sync, + op_fs_rename_async, + op_fs_link_sync, + op_fs_link_async, + op_fs_symlink_sync, + op_fs_symlink_async, + op_fs_read_link_sync, + op_fs_read_link_async, + op_fs_truncate_sync, + op_fs_truncate_async, + op_fs_utime_sync, + op_fs_utime_async, + op_fs_make_temp_dir_sync, + op_fs_make_temp_dir_async, + op_fs_make_temp_file_sync, + op_fs_make_temp_file_async, + op_fs_write_file_sync, + op_fs_write_file_async, + op_fs_read_file_sync, + op_fs_read_file_async, + op_fs_read_file_text_sync, + op_fs_read_file_text_async, op_fs_seek_sync, op_fs_seek_async, @@ -166,8 +79,8 @@ deno_core::extension!(deno_fs, op_fs_file_sync_data_async, op_fs_file_sync_sync, op_fs_file_sync_async, - op_fs_file_stat_sync

, - op_fs_file_stat_async

, + op_fs_file_stat_sync, + op_fs_file_stat_async, op_fs_fchmod_async, op_fs_fchmod_sync, op_fs_fchown_async, @@ -178,8 +91,8 @@ deno_core::extension!(deno_fs, op_fs_funlock_sync, op_fs_ftruncate_sync, op_fs_file_truncate_async, - op_fs_futime_sync

, - op_fs_futime_async

, + op_fs_futime_sync, + op_fs_futime_async, ], esm = [ "30_fs.js" ], diff --git a/ext/fs/ops.rs b/ext/fs/ops.rs index a9e3fdc8072dd0..cc03b9042aaddb 100644 --- a/ext/fs/ops.rs +++ b/ext/fs/ops.rs @@ -36,7 +36,6 @@ use rand::thread_rng; use serde::Deserialize; use serde::Serialize; -use crate::FsPermissions; use crate::OpenOptions; use crate::interface::FileSystemRc; use crate::interface::FsDirEntry; @@ -120,17 +119,14 @@ pub fn op_fs_cwd(state: &mut OpState) -> Result { } #[op2(fast, stack_trace)] -pub fn op_fs_chdir

( +pub fn op_fs_chdir( state: &mut OpState, #[string] directory: &str, -) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, -{ - let d = state.borrow_mut::

().check_open( +) -> Result<(), FsOpsError> { + let d = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(directory)), OpenAccessKind::ReadNoFollow, - "Deno.chdir()", + Some("Deno.chdir()"), )?; state .borrow::() @@ -178,13 +174,11 @@ impl From for OpenOptions { #[op2(stack_trace)] #[smi] -pub fn op_fs_open_sync

( +pub fn op_fs_open_sync( state: &mut OpState, #[string] path: &str, #[serde] options: Option, ) -> Result -where - P: FsPermissions + 'static, { let options = match options { Some(options) => OpenOptions::from(options), @@ -193,10 +187,10 @@ where let path = Path::new(path); let fs = state.borrow::().clone(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Borrowed(path), open_options_to_access_kind(&options), - "Deno.openSync()", + Some("Deno.openSync()"), )?; let file = fs.open_sync(&path, options).context_path("open", &path)?; let rid = state @@ -207,13 +201,11 @@ where #[op2(async, stack_trace)] #[smi] -pub async fn op_fs_open_async

( +pub async fn op_fs_open_async( state: Rc>, #[string] path: String, #[serde] options: Option, ) -> Result -where - P: FsPermissions + 'static, { let options = match options { Some(options) => OpenOptions::from(options), @@ -225,10 +217,10 @@ where let mut state = state.borrow_mut(); ( state.borrow::().clone(), - state.borrow_mut::

().check_open( + state.borrow_mut::().check_open( Cow::Owned(path), open_options_to_access_kind(&options), - "Deno.open()", + Some("Deno.open()"), )?, ) }; @@ -245,21 +237,19 @@ where } #[op2(stack_trace)] -pub fn op_fs_mkdir_sync

( +pub fn op_fs_mkdir_sync( state: &mut OpState, #[string] path: &str, recursive: bool, mode: Option, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let mode = mode.unwrap_or(0o777) & 0o777; - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::WriteNoFollow, - "Deno.mkdirSync()", + Some("Deno.mkdirSync()"), )?; let fs = state.borrow::(); @@ -270,23 +260,21 @@ where } #[op2(async, stack_trace)] -pub async fn op_fs_mkdir_async

( +pub async fn op_fs_mkdir_async( state: Rc>, #[string] path: String, recursive: bool, mode: Option, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let mode = mode.unwrap_or(0o777) & 0o777; let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::WriteNoFollow, - "Deno.mkdir()", + Some("Deno.mkdir()"), )?; (state.borrow::().clone(), path) }; @@ -300,18 +288,16 @@ where #[cfg(unix)] #[op2(fast, stack_trace)] -pub fn op_fs_chmod_sync

( +pub fn op_fs_chmod_sync( state: &mut OpState, #[string] path: &str, mode: u32, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::WriteNoFollow, - "Deno.chmodSync()", + Some("Deno.chmodSync()"), )?; let fs = state.borrow::(); fs.chmod_sync(&path, mode).context_path("chmod", &path)?; @@ -320,18 +306,16 @@ where #[cfg(not(unix))] #[op2(fast, stack_trace)] -pub fn op_fs_chmod_sync

( +pub fn op_fs_chmod_sync( state: &mut OpState, #[string] path: &str, mode: i32, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::WriteNoFollow, - "Deno.chmodSync()", + Some("Deno.chmodSync()"), )?; let fs = state.borrow::(); fs.chmod_sync(&path, mode).context_path("chmod", &path)?; @@ -340,20 +324,18 @@ where #[cfg(unix)] #[op2(async, stack_trace)] -pub async fn op_fs_chmod_async

( +pub async fn op_fs_chmod_async( state: Rc>, #[string] path: String, mode: u32, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::WriteNoFollow, - "Deno.chmod()", + Some("Deno.chmod()"), )?; (state.borrow::().clone(), path) }; @@ -365,20 +347,18 @@ where #[cfg(not(unix))] #[op2(async, stack_trace)] -pub async fn op_fs_chmod_async

( +pub async fn op_fs_chmod_async( state: Rc>, #[string] path: String, mode: i32, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::WriteNoFollow, - "Deno.chmod()", + Some("Deno.chmod()"), )?; (state.borrow::().clone(), path) }; @@ -389,19 +369,17 @@ where } #[op2(stack_trace)] -pub fn op_fs_chown_sync

( +pub fn op_fs_chown_sync( state: &mut OpState, #[string] path: &str, uid: Option, gid: Option, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::WriteNoFollow, - "Deno.chownSync()", + Some("Deno.chownSync()"), )?; let fs = state.borrow::(); fs.chown_sync(&path, uid, gid) @@ -410,21 +388,19 @@ where } #[op2(async, stack_trace)] -pub async fn op_fs_chown_async

( +pub async fn op_fs_chown_async( state: Rc>, #[string] path: String, uid: Option, gid: Option, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::WriteNoFollow, - "Deno.chown()", + Some("Deno.chown()"), )?; (state.borrow::().clone(), path) }; @@ -485,24 +461,22 @@ pub async fn op_fs_fchown_async( } #[op2(fast, stack_trace)] -pub fn op_fs_remove_sync

( +pub fn op_fs_remove_sync( state: &mut OpState, #[string] path: &str, recursive: bool, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let path = Cow::Borrowed(Path::new(path)); let path = if recursive { - state.borrow_mut::

().check_open( + state.borrow_mut::().check_open( path, OpenAccessKind::WriteNoFollow, - "Deno.removeSync()", + Some("Deno.removeSync()"), )? } else { state - .borrow_mut::

() + .borrow_mut::() .check_write_partial(path, "Deno.removeSync()")? }; @@ -514,26 +488,24 @@ where } #[op2(async, stack_trace)] -pub async fn op_fs_remove_async

( +pub async fn op_fs_remove_async( state: Rc>, #[string] path: String, recursive: bool, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let (fs, path) = { let mut state = state.borrow_mut(); let path = Cow::Owned(PathBuf::from(path)); let path = if recursive { - state.borrow_mut::

().check_open( + state.borrow_mut::().check_open( path, OpenAccessKind::WriteNoFollow, - "Deno.remove()", + Some("Deno.remove()"), )? } else { state - .borrow_mut::

() + .borrow_mut::() .check_write_partial(path, "Deno.remove()")? }; @@ -548,24 +520,22 @@ where } #[op2(fast, stack_trace)] -pub fn op_fs_copy_file_sync

( +pub fn op_fs_copy_file_sync( state: &mut OpState, #[string] from: &str, #[string] to: &str, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); let from = permissions.check_open( Cow::Borrowed(Path::new(from)), OpenAccessKind::Read, - "Deno.copyFileSync()", + Some("Deno.copyFileSync()"), )?; let to = permissions.check_open( Cow::Borrowed(Path::new(to)), OpenAccessKind::WriteNoFollow, - "Deno.copyFileSync()", + Some("Deno.copyFileSync()"), )?; let fs = state.borrow::(); @@ -576,26 +546,24 @@ where } #[op2(async, stack_trace)] -pub async fn op_fs_copy_file_async

( +pub async fn op_fs_copy_file_async( state: Rc>, #[string] from: String, #[string] to: String, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let (fs, from, to) = { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); let from = permissions.check_open( Cow::Owned(PathBuf::from(from)), OpenAccessKind::Read, - "Deno.copyFile()", + Some("Deno.copyFile()"), )?; let to = permissions.check_open( Cow::Owned(PathBuf::from(to)), OpenAccessKind::WriteNoFollow, - "Deno.copyFile()", + Some("Deno.copyFile()"), )?; (state.borrow::().clone(), from, to) }; @@ -607,18 +575,16 @@ where } #[op2(fast, stack_trace)] -pub fn op_fs_stat_sync

( +pub fn op_fs_stat_sync( state: &mut OpState, #[string] path: &str, #[buffer] stat_out_buf: &mut [u32], ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::ReadNoFollow, - "Deno.statSync()", + Some("Deno.statSync()"), )?; let fs = state.borrow::(); let stat = fs.stat_sync(&path).context_path("stat", &path)?; @@ -629,20 +595,18 @@ where #[op2(async, stack_trace)] #[serde] -pub async fn op_fs_stat_async

( +pub async fn op_fs_stat_async( state: Rc>, #[string] path: String, ) -> Result -where - P: FsPermissions + 'static, { let (fs, path) = { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); let path = permissions.check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::ReadNoFollow, - "Deno.stat()", + Some("Deno.stat()"), )?; (state.borrow::().clone(), path) }; @@ -654,18 +618,16 @@ where } #[op2(fast, stack_trace)] -pub fn op_fs_lstat_sync

( +pub fn op_fs_lstat_sync( state: &mut OpState, #[string] path: &str, #[buffer] stat_out_buf: &mut [u32], ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::ReadNoFollow, - "Deno.lstatSync()", + Some("Deno.lstatSync()"), )?; let fs = state.borrow::(); let stat = fs.lstat_sync(&path).context_path("lstat", &path)?; @@ -676,20 +638,18 @@ where #[op2(async, stack_trace)] #[serde] -pub async fn op_fs_lstat_async

( +pub async fn op_fs_lstat_async( state: Rc>, #[string] path: String, ) -> Result -where - P: FsPermissions + 'static, { let (fs, path) = { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); let path = permissions.check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::ReadNoFollow, - "Deno.lstat()", + Some("Deno.lstat()"), )?; (state.borrow::().clone(), path) }; @@ -702,19 +662,17 @@ where #[op2(stack_trace)] #[string] -pub fn op_fs_realpath_sync

( +pub fn op_fs_realpath_sync( state: &mut OpState, #[string] path: &str, ) -> Result -where - P: FsPermissions + 'static, { let fs = state.borrow::().clone(); - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); let path = permissions.check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::ReadNoFollow, - "Deno.realPathSync()", + Some("Deno.realPathSync()"), )?; let resolved_path = fs.realpath_sync(&path).context_path("realpath", &path)?; @@ -725,21 +683,19 @@ where #[op2(async, stack_trace)] #[string] -pub async fn op_fs_realpath_async

( +pub async fn op_fs_realpath_async( state: Rc>, #[string] path: String, ) -> Result -where - P: FsPermissions + 'static, { let (fs, path) = { let mut state = state.borrow_mut(); let fs = state.borrow::().clone(); - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); let path = permissions.check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::ReadNoFollow, - "Deno.realPath()", + Some("Deno.realPath()"), )?; (fs, path) }; @@ -754,17 +710,15 @@ where #[op2(stack_trace)] #[serde] -pub fn op_fs_read_dir_sync

( +pub fn op_fs_read_dir_sync( state: &mut OpState, #[string] path: &str, ) -> Result, FsOpsError> -where - P: FsPermissions + 'static, { - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::ReadNoFollow, - "Deno.readDirSync()", + Some("Deno.readDirSync()"), )?; let fs = state.borrow::(); @@ -775,19 +729,17 @@ where #[op2(async, stack_trace)] #[serde] -pub async fn op_fs_read_dir_async

( +pub async fn op_fs_read_dir_async( state: Rc>, #[string] path: String, ) -> Result, FsOpsError> -where - P: FsPermissions + 'static, { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::ReadNoFollow, - "Deno.readDir()", + Some("Deno.readDir()"), )?; (state.borrow::().clone(), path) }; @@ -801,24 +753,22 @@ where } #[op2(fast, stack_trace)] -pub fn op_fs_rename_sync

( +pub fn op_fs_rename_sync( state: &mut OpState, #[string] oldpath: &str, #[string] newpath: &str, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); let oldpath = permissions.check_open( Cow::Borrowed(Path::new(oldpath)), OpenAccessKind::ReadWriteNoFollow, - "Deno.renameSync()", + Some("Deno.renameSync()"), )?; let newpath = permissions.check_open( Cow::Borrowed(Path::new(newpath)), OpenAccessKind::WriteNoFollow, - "Deno.renameSync()", + Some("Deno.renameSync()"), )?; let fs = state.borrow::(); @@ -829,26 +779,24 @@ where } #[op2(async, stack_trace)] -pub async fn op_fs_rename_async

( +pub async fn op_fs_rename_async( state: Rc>, #[string] oldpath: String, #[string] newpath: String, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let (fs, oldpath, newpath) = { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); let oldpath = permissions.check_open( Cow::Owned(PathBuf::from(oldpath)), OpenAccessKind::ReadWriteNoFollow, - "Deno.rename()", + Some("Deno.rename()"), )?; let newpath = permissions.check_open( Cow::Owned(PathBuf::from(newpath)), OpenAccessKind::WriteNoFollow, - "Deno.rename()", + Some("Deno.rename()"), )?; (state.borrow::().clone(), oldpath, newpath) }; @@ -861,24 +809,22 @@ where } #[op2(fast, stack_trace)] -pub fn op_fs_link_sync

( +pub fn op_fs_link_sync( state: &mut OpState, #[string] oldpath: &str, #[string] newpath: &str, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); let oldpath = permissions.check_open( Cow::Borrowed(Path::new(oldpath)), OpenAccessKind::ReadWriteNoFollow, - "Deno.linkSync()", + Some("Deno.linkSync()"), )?; let newpath = permissions.check_open( Cow::Borrowed(Path::new(newpath)), OpenAccessKind::WriteNoFollow, - "Deno.linkSync()", + Some("Deno.linkSync()"), )?; let fs = state.borrow::(); @@ -889,26 +835,24 @@ where } #[op2(async, stack_trace)] -pub async fn op_fs_link_async

( +pub async fn op_fs_link_async( state: Rc>, #[string] oldpath: String, #[string] newpath: String, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let (fs, oldpath, newpath) = { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); let oldpath = permissions.check_open( Cow::Owned(PathBuf::from(oldpath)), OpenAccessKind::ReadWriteNoFollow, - "Deno.link()", + Some("Deno.link()"), )?; let newpath = permissions.check_open( Cow::Owned(PathBuf::from(newpath)), OpenAccessKind::WriteNoFollow, - "Deno.link()", + Some("Deno.link()"), )?; (state.borrow::().clone(), oldpath, newpath) }; @@ -921,16 +865,14 @@ where } #[op2(stack_trace)] -pub fn op_fs_symlink_sync

( +pub fn op_fs_symlink_sync( state: &mut OpState, #[string] oldpath: &str, #[string] newpath: &str, #[serde] file_type: Option, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions.check_write_all("Deno.symlinkSync()")?; permissions.check_read_all("Deno.symlinkSync()")?; @@ -946,18 +888,16 @@ where } #[op2(async, stack_trace)] -pub async fn op_fs_symlink_async

( +pub async fn op_fs_symlink_async( state: Rc>, #[string] oldpath: String, #[string] newpath: String, #[serde] file_type: Option, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let fs = { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions.check_write_all("Deno.symlink()")?; permissions.check_read_all("Deno.symlink()")?; state.borrow::().clone() @@ -980,17 +920,15 @@ where #[op2(stack_trace)] #[string] -pub fn op_fs_read_link_sync

( +pub fn op_fs_read_link_sync( state: &mut OpState, #[string] path: &str, ) -> Result -where - P: FsPermissions + 'static, { - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::ReadNoFollow, - "Deno.readLink()", + Some("Deno.readLink()"), )?; let fs = state.borrow::(); @@ -1002,19 +940,17 @@ where #[op2(async, stack_trace)] #[string] -pub async fn op_fs_read_link_async

( +pub async fn op_fs_read_link_async( state: Rc>, #[string] path: String, ) -> Result -where - P: FsPermissions + 'static, { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::ReadNoFollow, - "Deno.readLink()", + Some("Deno.readLink()"), )?; (state.borrow::().clone(), path) }; @@ -1028,18 +964,16 @@ where } #[op2(fast, stack_trace)] -pub fn op_fs_truncate_sync

( +pub fn op_fs_truncate_sync( state: &mut OpState, #[string] path: &str, #[number] len: u64, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::WriteNoFollow, - "Deno.truncateSync()", + Some("Deno.truncateSync()"), )?; let fs = state.borrow::(); @@ -1050,20 +984,18 @@ where } #[op2(async, stack_trace)] -pub async fn op_fs_truncate_async

( +pub async fn op_fs_truncate_async( state: Rc>, #[string] path: String, #[number] len: u64, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::WriteNoFollow, - "Deno.truncate()", + Some("Deno.truncate()"), )?; (state.borrow::().clone(), path) }; @@ -1076,7 +1008,7 @@ where } #[op2(fast, stack_trace)] -pub fn op_fs_utime_sync

( +pub fn op_fs_utime_sync( state: &mut OpState, #[string] path: &str, #[number] atime_secs: i64, @@ -1084,13 +1016,11 @@ pub fn op_fs_utime_sync

( #[number] mtime_secs: i64, #[smi] mtime_nanos: u32, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::WriteNoFollow, - "Deno.utime()", + Some("Deno.utime()"), )?; let fs = state.borrow::(); @@ -1101,7 +1031,7 @@ where } #[op2(async, stack_trace)] -pub async fn op_fs_utime_async

( +pub async fn op_fs_utime_async( state: Rc>, #[string] path: String, #[number] atime_secs: i64, @@ -1109,15 +1039,13 @@ pub async fn op_fs_utime_async

( #[number] mtime_secs: i64, #[smi] mtime_nanos: u32, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::WriteNoFollow, - "Deno.utime()", + Some("Deno.utime()"), )?; (state.borrow::().clone(), path) }; @@ -1137,16 +1065,14 @@ where #[op2(stack_trace)] #[string] -pub fn op_fs_make_temp_dir_sync

( +pub fn op_fs_make_temp_dir_sync( state: &mut OpState, #[string] dir_arg: Option, #[string] prefix: Option, #[string] suffix: Option, ) -> Result -where - P: FsPermissions + 'static, { - let (dir, fs) = make_temp_check_sync::

( + let (dir, fs) = make_temp_check_sync( state, dir_arg.as_deref(), "Deno.makeTempDirSync()", @@ -1182,16 +1108,14 @@ where #[op2(async, stack_trace)] #[string] -pub async fn op_fs_make_temp_dir_async

( +pub async fn op_fs_make_temp_dir_async( state: Rc>, #[string] dir_arg: Option, #[string] prefix: Option, #[string] suffix: Option, ) -> Result -where - P: FsPermissions + 'static, { - let (dir, fs) = make_temp_check_async::

( + let (dir, fs) = make_temp_check_async( state, dir_arg.as_deref(), "Deno.makeTempDir()", @@ -1231,16 +1155,14 @@ where #[op2(stack_trace)] #[string] -pub fn op_fs_make_temp_file_sync

( +pub fn op_fs_make_temp_file_sync( state: &mut OpState, #[string] dir_arg: Option, #[string] prefix: Option, #[string] suffix: Option, ) -> Result -where - P: FsPermissions + 'static, { - let (dir, fs) = make_temp_check_sync::

( + let (dir, fs) = make_temp_check_sync( state, dir_arg.as_deref(), "Deno.makeTempFileSync()", @@ -1282,16 +1204,14 @@ where #[op2(async, stack_trace)] #[string] -pub async fn op_fs_make_temp_file_async

( +pub async fn op_fs_make_temp_file_async( state: Rc>, #[string] dir_arg: Option, #[string] prefix: Option, #[string] suffix: Option, ) -> Result -where - P: FsPermissions + 'static, { - let (dir, fs) = make_temp_check_async::

( + let (dir, fs) = make_temp_check_async( state, dir_arg.as_deref(), "Deno.makeTempFile()", @@ -1348,57 +1268,53 @@ fn strip_dir_prefix( } } -fn make_temp_check_sync<'a, P>( +fn make_temp_check_sync<'a>( state: &mut OpState, dir: Option<&'a str>, api_name: &str, ) -> Result<(CheckedPath<'a>, FileSystemRc), FsOpsError> -where - P: FsPermissions + 'static, { let fs = state.borrow::().clone(); let dir = match dir { - Some(dir) => state.borrow_mut::

().check_open( + Some(dir) => state.borrow_mut::().check_open( Cow::Borrowed(Path::new(dir)), OpenAccessKind::WriteNoFollow, - api_name, + Some(api_name), )?, None => { let dir = fs.tmp_dir().context("tmpdir")?; - state.borrow_mut::

().check_open_blind( + state.borrow_mut::().check_open_blind( Cow::Owned(dir), OpenAccessKind::WriteNoFollow, "TMP", - api_name, + Some(api_name), )? } }; Ok((dir, fs)) } -fn make_temp_check_async<'a, P>( +fn make_temp_check_async<'a>( state: Rc>, dir: Option<&'a str>, api_name: &str, ) -> Result<(CheckedPath<'a>, FileSystemRc), FsOpsError> -where - P: FsPermissions + 'static, { let mut state = state.borrow_mut(); let fs = state.borrow::().clone(); let dir = match dir { - Some(dir) => state.borrow_mut::

().check_open( + Some(dir) => state.borrow_mut::().check_open( Cow::Borrowed(Path::new(dir)), OpenAccessKind::WriteNoFollow, - api_name, + Some(api_name), )?, None => { let dir = fs.tmp_dir().context("tmpdir")?; - state.borrow_mut::

().check_open_blind( + state.borrow_mut::().check_open_blind( Cow::Owned(dir), OpenAccessKind::WriteNoFollow, "TMP", - api_name, + Some(api_name), )? } }; @@ -1468,7 +1384,7 @@ fn tmp_name( } #[op2(stack_trace)] -pub fn op_fs_write_file_sync

( +pub fn op_fs_write_file_sync( state: &mut OpState, #[string] path: &str, mode: Option, @@ -1477,17 +1393,15 @@ pub fn op_fs_write_file_sync

( create_new: bool, #[buffer] data: JsBuffer, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let path = Path::new(path); let options = OpenOptions::write(create, append, create_new, mode); let fs = state.borrow::().clone(); - let path = state.borrow::

().check_open( + let path = state.borrow::().check_open( Cow::Borrowed(path), OpenAccessKind::Write, - "Deno.writeFileSync()", + Some("Deno.writeFileSync()"), )?; fs.write_file_sync(&path, options, &data) @@ -1498,7 +1412,7 @@ where #[op2(async, stack_trace)] #[allow(clippy::too_many_arguments)] -pub async fn op_fs_write_file_async

( +pub async fn op_fs_write_file_async( state: Rc>, #[string] path: String, #[smi] mode: Option, @@ -1508,8 +1422,6 @@ pub async fn op_fs_write_file_async

( #[buffer] data: JsBuffer, #[smi] cancel_rid: Option, ) -> Result<(), FsOpsError> -where - P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -1519,10 +1431,10 @@ where let state = state.borrow_mut(); let cancel_handle = cancel_rid .and_then(|rid| state.resource_table.get::(rid).ok()); - let path = state.borrow::

().check_open( + let path = state.borrow::().check_open( Cow::Owned(path), OpenAccessKind::Write, - "Deno.writeFile()", + Some("Deno.writeFile()"), )?; (state.borrow::().clone(), cancel_handle, path) }; @@ -1548,13 +1460,11 @@ where #[op2(stack_trace)] #[serde] -pub fn op_fs_read_file_sync

( +pub fn op_fs_read_file_sync( state: &mut OpState, #[string] path: &str, #[smi] flags: Option, ) -> Result -where - P: FsPermissions + 'static, { let path = Path::new(path); let options = if let Some(flags) = flags { @@ -1564,10 +1474,10 @@ where }; let fs = state.borrow::().clone(); - let path = state.borrow::

().check_open( + let path = state.borrow::().check_open( Cow::Borrowed(path), open_options_to_access_kind(&options), - "Deno.readFileSync()", + Some("Deno.readFileSync()"), )?; let buf = fs @@ -1580,14 +1490,12 @@ where #[op2(async, stack_trace)] #[serde] -pub async fn op_fs_read_file_async

( +pub async fn op_fs_read_file_async( state: Rc>, #[string] path: String, #[smi] cancel_rid: Option, #[smi] flags: Option, ) -> Result -where - P: FsPermissions + 'static, { let path = PathBuf::from(path); let options = if let Some(flags) = flags { @@ -1600,10 +1508,10 @@ where let state = state.borrow(); let cancel_handle = cancel_rid .and_then(|rid| state.resource_table.get::(rid).ok()); - let path = state.borrow::

().check_open( + let path = state.borrow::().check_open( Cow::Owned(path), open_options_to_access_kind(&options), - "Deno.readFile()", + Some("Deno.readFile()"), )?; (state.borrow::().clone(), cancel_handle, path) }; @@ -1630,20 +1538,18 @@ where #[op2(stack_trace)] #[to_v8] -pub fn op_fs_read_file_text_sync

( +pub fn op_fs_read_file_text_sync( state: &mut OpState, #[string] path: &str, ) -> Result -where - P: FsPermissions + 'static, { let path = Path::new(path); let fs = state.borrow::().clone(); - let path = state.borrow::

().check_open( + let path = state.borrow::().check_open( Cow::Borrowed(path), OpenAccessKind::Read, - "Deno.readFileSync()", + Some("Deno.readFileSync()"), )?; let str = fs .read_text_file_lossy_sync(&path) @@ -1656,13 +1562,11 @@ where #[op2(async, stack_trace)] #[to_v8] -pub async fn op_fs_read_file_text_async

( +pub async fn op_fs_read_file_text_async( state: Rc>, #[string] path: String, #[smi] cancel_rid: Option, ) -> Result -where - P: FsPermissions + 'static, { let path = PathBuf::from(path); @@ -1670,10 +1574,10 @@ where let state = state.borrow_mut(); let cancel_handle = cancel_rid .and_then(|rid| state.resource_table.get::(rid).ok()); - let path = state.borrow::

().check_open( + let path = state.borrow::().check_open( Cow::Owned(path), OpenAccessKind::Read, - "Deno.readFile()", + Some("Deno.readFile()"), )?; (state.borrow::().clone(), cancel_handle, path) }; @@ -1787,7 +1691,7 @@ pub async fn op_fs_file_sync_async( } #[op2(fast)] -pub fn op_fs_file_stat_sync( +pub fn op_fs_file_stat_sync( state: &mut OpState, #[smi] rid: ResourceId, #[buffer] stat_out_buf: &mut [u32], @@ -1795,10 +1699,10 @@ pub fn op_fs_file_stat_sync( let file = FileResource::get_file(state, rid).map_err(FsOpsErrorKind::Resource)?; if let Some(path) = file.maybe_path() { - _ = state.borrow::

().check_open( + _ = state.borrow::().check_open( Cow::Borrowed(path), OpenAccessKind::Read, - "Deno.FsFile.prototype.statSync()", + Some("Deno.FsFile.prototype.statSync()"), )?; } let stat = file.stat_sync()?; @@ -1809,17 +1713,17 @@ pub fn op_fs_file_stat_sync( #[op2(async)] #[serde] -pub async fn op_fs_file_stat_async( +pub async fn op_fs_file_stat_async( state: Rc>, #[smi] rid: ResourceId, ) -> Result { let file = FileResource::get_file(&state.borrow(), rid) .map_err(FsOpsErrorKind::Resource)?; if let Some(path) = file.maybe_path() { - _ = state.borrow().borrow::

().check_open( + _ = state.borrow().borrow::().check_open( Cow::Borrowed(path), OpenAccessKind::Read, - "Deno.FsFile.prototype.stat()", + Some("Deno.FsFile.prototype.stat()"), )?; } let stat = file.stat_async().await?; @@ -1897,7 +1801,7 @@ pub async fn op_fs_file_truncate_async( } #[op2(fast)] -pub fn op_fs_futime_sync( +pub fn op_fs_futime_sync( state: &mut OpState, #[smi] rid: ResourceId, #[number] atime_secs: i64, @@ -1908,10 +1812,10 @@ pub fn op_fs_futime_sync( let file = FileResource::get_file(state, rid).map_err(FsOpsErrorKind::Resource)?; if let Some(path) = file.maybe_path() { - _ = state.borrow::

().check_open( + _ = state.borrow::().check_open( Cow::Borrowed(path), OpenAccessKind::WriteNoFollow, - "Deno.FsFile.prototype.utimeSync()", + Some("Deno.FsFile.prototype.utimeSync()"), )?; } file.utime_sync(atime_secs, atime_nanos, mtime_secs, mtime_nanos)?; @@ -1919,7 +1823,7 @@ pub fn op_fs_futime_sync( } #[op2(async)] -pub async fn op_fs_futime_async( +pub async fn op_fs_futime_async( state: Rc>, #[smi] rid: ResourceId, #[number] atime_secs: i64, @@ -1930,10 +1834,10 @@ pub async fn op_fs_futime_async( let file = FileResource::get_file(&state.borrow(), rid) .map_err(FsOpsErrorKind::Resource)?; if let Some(path) = file.maybe_path() { - _ = state.borrow().borrow::

().check_open( + _ = state.borrow().borrow::().check_open( Cow::Borrowed(path), OpenAccessKind::WriteNoFollow, - "Deno.FsFile.prototype.utime()", + Some("Deno.FsFile.prototype.utime()"), )?; } file diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 9e355abcb3b9f8..7d36f3baf2c0f4 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -47,7 +47,7 @@ pub fn create_runtime_snapshot( deno_napi::deno_napi::lazy_init::(), deno_http::deno_http::lazy_init(), deno_io::deno_io::lazy_init(), - deno_fs::deno_fs::lazy_init::(), + deno_fs::deno_fs::lazy_init(), deno_os::deno_os::lazy_init(), deno_process::deno_process::lazy_init(), deno_node::deno_node::lazy_init::< diff --git a/runtime/snapshot_info.rs b/runtime/snapshot_info.rs index c817f0519e0cda..a55f243468ea06 100644 --- a/runtime/snapshot_info.rs +++ b/runtime/snapshot_info.rs @@ -77,49 +77,6 @@ impl deno_node::NodePermissions for Permissions { } } -impl deno_fs::FsPermissions for Permissions { - fn check_open<'a>( - &self, - _path: Cow<'a, Path>, - _access_kind: OpenAccessKind, - _api_name: &str, - ) -> Result, PermissionCheckError> { - unreachable!("snapshotting!") - } - - fn check_open_blind<'a>( - &self, - _path: Cow<'a, Path>, - _access_kind: OpenAccessKind, - _display: &str, - _api_name: &str, - ) -> Result, PermissionCheckError> { - unreachable!("snapshotting!") - } - - fn check_read_all( - &self, - _api_name: &str, - ) -> Result<(), PermissionCheckError> { - unreachable!("snapshotting!") - } - - fn check_write_partial<'a>( - &self, - _path: Cow<'a, Path>, - _api_name: &str, - ) -> Result, PermissionCheckError> { - unreachable!("snapshotting!") - } - - fn check_write_all( - &self, - _api_name: &str, - ) -> Result<(), PermissionCheckError> { - unreachable!("snapshotting!") - } -} - impl deno_kv::sqlite::SqliteDbHandlerPermissions for Permissions { fn check_open<'a>( &mut self, @@ -162,7 +119,7 @@ pub fn get_extensions_in_snapshot() -> Vec { deno_napi::deno_napi::init::(None), deno_http::deno_http::init(deno_http::Options::default()), deno_io::deno_io::init(Some(Default::default())), - deno_fs::deno_fs::init::(fs.clone()), + deno_fs::deno_fs::init(fs.clone()), deno_os::deno_os::init(Default::default()), deno_process::deno_process::init(Default::default()), deno_node::deno_node::init::< diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 8ac5ea714a6fa0..7cdc89391d5aec 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -573,7 +573,7 @@ impl WebWorker { ..Default::default() }), deno_io::deno_io::init(Some(options.stdio)), - deno_fs::deno_fs::init::(services.fs.clone()), + deno_fs::deno_fs::init(services.fs.clone()), deno_os::deno_os::init(None), deno_process::deno_process::init(services.npm_process_state_provider), deno_node::deno_node::init::< diff --git a/runtime/worker.rs b/runtime/worker.rs index 8698f1d2624826..bc64ed246549f3 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -585,7 +585,7 @@ impl MainWorker { ..Default::default() }), deno_io::deno_io::args(Some(options.stdio)), - deno_fs::deno_fs::args::(services.fs.clone()), + deno_fs::deno_fs::args(services.fs.clone()), deno_os::deno_os::args(Some(exit_code.clone())), deno_process::deno_process::args(services.npm_process_state_provider), deno_node::deno_node::args::< @@ -1066,7 +1066,7 @@ fn common_extensions< deno_napi::deno_napi::lazy_init::(), deno_http::deno_http::lazy_init(), deno_io::deno_io::lazy_init(), - deno_fs::deno_fs::lazy_init::(), + deno_fs::deno_fs::lazy_init(), deno_os::deno_os::lazy_init(), deno_process::deno_process::lazy_init(), deno_node::deno_node::lazy_init::< From 9f116bbb4d8d66dcd60f7a1fd449ac5c289986cb Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Thu, 13 Nov 2025 13:49:47 -0800 Subject: [PATCH 05/13] remove permissions trait from deno_napi --- ext/napi/lib.rs | 35 ++++++----------------------------- runtime/snapshot.rs | 2 +- runtime/snapshot_info.rs | 11 +---------- runtime/web_worker.rs | 4 +--- runtime/worker.rs | 4 ++-- 5 files changed, 11 insertions(+), 45 deletions(-) diff --git a/ext/napi/lib.rs b/ext/napi/lib.rs index 5b5d45af2231ea..e39fd2aefc1671 100644 --- a/ext/napi/lib.rs +++ b/ext/napi/lib.rs @@ -505,9 +505,8 @@ impl Env { } deno_core::extension!(deno_napi, - parameters = [P: NapiPermissions], ops = [ - op_napi_open

+ op_napi_open ], options = { deno_rt_native_addon_loader: Option, @@ -522,26 +521,6 @@ 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<'a>( - &mut self, - path: Cow<'a, Path>, - ) -> Result, 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<'a>( - &mut self, - path: Cow<'a, Path>, - ) -> Result, PermissionCheckError> { - deno_permissions::PermissionsContainer::check_ffi(self, path) - } -} - unsafe impl Sync for NapiModuleHandle {} unsafe impl Send for NapiModuleHandle {} @@ -553,7 +532,7 @@ static NAPI_LOADED_MODULES: std::sync::LazyLock< > = std::sync::LazyLock::new(|| RwLock::new(HashMap::new())); #[op2(reentrant, stack_trace)] -fn op_napi_open( +fn op_napi_open<'scope>( scope: &mut v8::PinScope<'scope, '_>, isolate: &mut v8::Isolate, op_state: Rc>, @@ -561,10 +540,7 @@ fn op_napi_open( global: v8::Local<'scope, v8::Object>, create_buffer: v8::Local<'scope, v8::Function>, report_error: v8::Local<'scope, v8::Function>, -) -> Result, NApiError> -where - NP: NapiPermissions + 'static, -{ +) -> Result, NApiError> { // We must limit the OpState borrow because this function can trigger a // re-borrow through the NAPI module. let ( @@ -575,8 +551,9 @@ where path, ) = { let mut op_state = op_state.borrow_mut(); - let permissions = op_state.borrow_mut::(); - let path = permissions.check(Cow::Borrowed(Path::new(path)))?; + let permissions = + op_state.borrow_mut::(); + let path = permissions.check_ffi(Cow::Borrowed(Path::new(path)))?; let napi_state = op_state.borrow::(); ( op_state.borrow::().clone(), diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 7d36f3baf2c0f4..4e3ec57ad212b8 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -44,7 +44,7 @@ pub fn create_runtime_snapshot( deno_kv::deno_kv::lazy_init::>( ), deno_cron::deno_cron::init(deno_cron::local::LocalCronHandler::new()), - deno_napi::deno_napi::lazy_init::(), + deno_napi::deno_napi::lazy_init(), deno_http::deno_http::lazy_init(), deno_io::deno_io::lazy_init(), deno_fs::deno_fs::lazy_init(), diff --git a/runtime/snapshot_info.rs b/runtime/snapshot_info.rs index a55f243468ea06..36a5069bdaa839 100644 --- a/runtime/snapshot_info.rs +++ b/runtime/snapshot_info.rs @@ -33,15 +33,6 @@ impl deno_web::TimersPermission for Permissions { } } -impl deno_napi::NapiPermissions for Permissions { - fn check<'a>( - &mut self, - _path: Cow<'a, Path>, - ) -> Result, PermissionCheckError> { - unreachable!("snapshotting!") - } -} - impl deno_node::NodePermissions for Permissions { fn check_net_url( &mut self, @@ -116,7 +107,7 @@ pub fn get_extensions_in_snapshot() -> Vec { deno_kv::KvConfig::builder().build(), ), deno_cron::deno_cron::init(deno_cron::local::LocalCronHandler::new()), - deno_napi::deno_napi::init::(None), + deno_napi::deno_napi::init(None), deno_http::deno_http::init(deno_http::Options::default()), deno_io::deno_io::init(Some(Default::default())), deno_fs::deno_fs::init(fs.clone()), diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 7cdc89391d5aec..09447f117cc651 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -565,9 +565,7 @@ impl WebWorker { deno_kv::KvConfig::builder().build(), ), deno_cron::deno_cron::init(LocalCronHandler::new()), - deno_napi::deno_napi::init::( - services.deno_rt_native_addon_loader.clone(), - ), + deno_napi::deno_napi::init(services.deno_rt_native_addon_loader.clone()), deno_http::deno_http::init(deno_http::Options { no_legacy_abort: options.bootstrap.no_legacy_abort, ..Default::default() diff --git a/runtime/worker.rs b/runtime/worker.rs index bc64ed246549f3..b36e62502fe1a7 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -577,7 +577,7 @@ impl MainWorker { ), deno_kv::KvConfig::builder().build(), ), - deno_napi::deno_napi::args::( + deno_napi::deno_napi::args( services.deno_rt_native_addon_loader.clone(), ), deno_http::deno_http::args(deno_http::Options { @@ -1063,7 +1063,7 @@ fn common_extensions< deno_tls::deno_tls::init(), deno_kv::deno_kv::lazy_init::(), deno_cron::deno_cron::init(LocalCronHandler::new()), - deno_napi::deno_napi::lazy_init::(), + deno_napi::deno_napi::lazy_init(), deno_http::deno_http::lazy_init(), deno_io::deno_io::lazy_init(), deno_fs::deno_fs::lazy_init(), From 6167de6f45b4203e1af0b390eee061faf7cc68fc Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Thu, 13 Nov 2025 13:52:33 -0800 Subject: [PATCH 06/13] remove permissions trait from deno_web --- ext/web/benches/encoding.rs | 8 +------ ext/web/benches/timers_ops.rs | 8 +------ ext/web/benches/url_ops.rs | 11 +--------- ext/web/lib.rs | 7 +++--- ext/web/timers.rs | 40 ++++++----------------------------- runtime/snapshot.rs | 5 +---- runtime/snapshot_info.rs | 8 +------ runtime/web_worker.rs | 2 +- runtime/worker.rs | 10 ++------- 9 files changed, 17 insertions(+), 82 deletions(-) diff --git a/ext/web/benches/encoding.rs b/ext/web/benches/encoding.rs index 44a5de2ddf9a02..dc9517b26c4b45 100644 --- a/ext/web/benches/encoding.rs +++ b/ext/web/benches/encoding.rs @@ -9,12 +9,6 @@ use deno_core::Extension; #[derive(Clone)] struct Permissions; -impl deno_web::TimersPermission for Permissions { - fn allow_hrtime(&mut self) -> bool { - false - } -} - fn setup() -> Vec { deno_core::extension!( bench_setup, @@ -33,7 +27,7 @@ fn setup() -> Vec { vec![ deno_webidl::deno_webidl::init(), - deno_web::deno_web::init::( + deno_web::deno_web::init::( Default::default(), None, Default::default(), diff --git a/ext/web/benches/timers_ops.rs b/ext/web/benches/timers_ops.rs index 9a12f4b90d1177..283cad56a28232 100644 --- a/ext/web/benches/timers_ops.rs +++ b/ext/web/benches/timers_ops.rs @@ -9,12 +9,6 @@ use deno_core::Extension; #[derive(Clone)] struct Permissions; -impl deno_web::TimersPermission for Permissions { - fn allow_hrtime(&mut self) -> bool { - true - } -} - fn setup() -> Vec { deno_core::extension!( bench_setup, @@ -32,7 +26,7 @@ fn setup() -> Vec { vec![ deno_webidl::deno_webidl::init(), - deno_web::deno_web::init::( + deno_web::deno_web::init::( Default::default(), None, Default::default(), diff --git a/ext/web/benches/url_ops.rs b/ext/web/benches/url_ops.rs index 5e4a7a07ad3803..ea7517b61ae873 100644 --- a/ext/web/benches/url_ops.rs +++ b/ext/web/benches/url_ops.rs @@ -6,15 +6,6 @@ use deno_bench_util::bencher::Bencher; use deno_bench_util::bencher::benchmark_group; use deno_core::Extension; -#[derive(Clone)] -struct Permissions; - -impl deno_web::TimersPermission for Permissions { - fn allow_hrtime(&mut self) -> bool { - false - } -} - fn setup() -> Vec { deno_core::extension!( bench_setup, @@ -29,7 +20,7 @@ fn setup() -> Vec { vec![ deno_webidl::deno_webidl::init(), - deno_web::deno_web::init::( + deno_web::deno_web::init::( Default::default(), None, Default::default(), diff --git a/ext/web/lib.rs b/ext/web/lib.rs index c213dbe50add66..bbb362a3d8ad48 100644 --- a/ext/web/lib.rs +++ b/ext/web/lib.rs @@ -54,14 +54,13 @@ use crate::message_port::op_message_port_recv_message; use crate::message_port::op_message_port_recv_message_sync; pub use crate::message_port::serialize_transferables; pub use crate::timers::StartTime; -pub use crate::timers::TimersPermission; use crate::timers::op_defer; use crate::timers::op_now; use crate::timers::op_time_origin; deno_core::extension!(deno_web, deps = [ deno_webidl ], - parameters = [P: TimersPermission, BC: BroadcastChannel], + parameters = [BC: BroadcastChannel], ops = [ op_base64_decode, op_base64_encode, @@ -87,8 +86,8 @@ deno_core::extension!(deno_web, compression::op_compression_new, compression::op_compression_write, compression::op_compression_finish, - op_now

, - op_time_origin

, + op_now, + op_time_origin, op_defer, stream_resource::op_readable_stream_resource_allocate, stream_resource::op_readable_stream_resource_allocate_sized, diff --git a/ext/web/timers.rs b/ext/web/timers.rs index 28945382cdbfaf..b361f882c76c52 100644 --- a/ext/web/timers.rs +++ b/ext/web/timers.rs @@ -10,17 +10,6 @@ use std::time::UNIX_EPOCH; use deno_core::OpState; use deno_core::op2; -pub trait TimersPermission { - fn allow_hrtime(&mut self) -> bool; -} - -impl TimersPermission for deno_permissions::PermissionsContainer { - #[inline(always)] - fn allow_hrtime(&mut self) -> bool { - true - } -} - pub struct StartTime(Instant); impl Default for StartTime { @@ -37,20 +26,9 @@ impl std::ops::Deref for StartTime { } } -fn expose_time(state: &mut OpState, duration: Duration, out: &mut [u8]) -where - TP: TimersPermission + 'static, -{ +fn expose_time(duration: Duration, out: &mut [u8]) { let seconds = duration.as_secs() as u32; - let mut subsec_nanos = duration.subsec_nanos(); - - // If the permission is not enabled - // Round the nano result on 2 milliseconds - // see: https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp#Reduced_time_precision - if !state.borrow_mut::().allow_hrtime() { - let reduced_time_precision = 2_000_000; // 2ms in nanoseconds - subsec_nanos -= subsec_nanos % reduced_time_precision; - } + let subsec_nanos = duration.subsec_nanos(); if out.len() >= 8 { out[0..4].copy_from_slice(&seconds.to_ne_bytes()); @@ -59,25 +37,19 @@ where } #[op2(fast)] -pub fn op_now(state: &mut OpState, #[buffer] buf: &mut [u8]) -where - TP: TimersPermission + 'static, -{ +pub fn op_now(state: &mut OpState, #[buffer] buf: &mut [u8]) { let start_time = state.borrow::(); let elapsed = start_time.elapsed(); - expose_time::(state, elapsed, buf); + expose_time(elapsed, buf); } #[op2(fast)] -pub fn op_time_origin(state: &mut OpState, #[buffer] buf: &mut [u8]) -where - TP: TimersPermission + 'static, -{ +pub fn op_time_origin(state: &mut OpState, #[buffer] buf: &mut [u8]) { // https://w3c.github.io/hr-time/#dfn-estimated-monotonic-time-of-the-unix-epoch let wall_time = SystemTime::now(); let monotonic_time = state.borrow::().elapsed(); let epoch = wall_time.duration_since(UNIX_EPOCH).unwrap() - monotonic_time; - expose_time::(state, epoch, buf); + expose_time(epoch, buf); } #[allow(clippy::unused_async)] diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 4e3ec57ad212b8..6b642206b1aa7e 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -27,10 +27,7 @@ pub fn create_runtime_snapshot( let mut extensions: Vec = vec![ deno_telemetry::deno_telemetry::lazy_init(), deno_webidl::deno_webidl::lazy_init(), - deno_web::deno_web::lazy_init::< - Permissions, - deno_web::InMemoryBroadcastChannel, - >(), + deno_web::deno_web::lazy_init::(), deno_webgpu::deno_webgpu::lazy_init(), deno_canvas::deno_canvas::lazy_init(), deno_fetch::deno_fetch::lazy_init(), diff --git a/runtime/snapshot_info.rs b/runtime/snapshot_info.rs index 36a5069bdaa839..83866ee6df8a9b 100644 --- a/runtime/snapshot_info.rs +++ b/runtime/snapshot_info.rs @@ -27,12 +27,6 @@ impl deno_websocket::WebSocketPermissions for Permissions { } } -impl deno_web::TimersPermission for Permissions { - fn allow_hrtime(&mut self) -> bool { - unreachable!("snapshotting!") - } -} - impl deno_node::NodePermissions for Permissions { fn check_net_url( &mut self, @@ -87,7 +81,7 @@ pub fn get_extensions_in_snapshot() -> Vec { vec![ deno_telemetry::deno_telemetry::init(), deno_webidl::deno_webidl::init(), - deno_web::deno_web::init::( + deno_web::deno_web::init::( Default::default(), Default::default(), deno_web::InMemoryBroadcastChannel::default(), diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 09447f117cc651..e4c12791bc479f 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -522,7 +522,7 @@ impl WebWorker { deno_telemetry::deno_telemetry::init(), // Web APIs deno_webidl::deno_webidl::init(), - deno_web::deno_web::init::( + deno_web::deno_web::init::( services.blob_store, Some(options.main_module.clone()), services.broadcast_channel, diff --git a/runtime/worker.rs b/runtime/worker.rs index b36e62502fe1a7..ec70184bafda9a 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -530,10 +530,7 @@ impl MainWorker { js_runtime .lazy_init_extensions(vec![ - deno_web::deno_web::args::< - PermissionsContainer, - InMemoryBroadcastChannel, - >( + deno_web::deno_web::args::( services.blob_store.clone(), options.bootstrap.location.clone(), services.broadcast_channel.clone(), @@ -1047,10 +1044,7 @@ fn common_extensions< deno_telemetry::deno_telemetry::init(), // Web APIs deno_webidl::deno_webidl::init(), - deno_web::deno_web::lazy_init::< - PermissionsContainer, - InMemoryBroadcastChannel, - >(), + deno_web::deno_web::lazy_init::(), deno_webgpu::deno_webgpu::init(), deno_canvas::deno_canvas::init(), deno_fetch::deno_fetch::lazy_init(), From cce2363f057181c2f5e6b89126b3d1f7e6a0b207 Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Thu, 13 Nov 2025 13:56:51 -0800 Subject: [PATCH 07/13] remove permissions trait from deno_websocket --- ext/websocket/lib.rs | 31 +++++++++++++------------------ runtime/snapshot.rs | 2 +- runtime/snapshot_info.rs | 2 +- runtime/web_worker.rs | 2 +- runtime/worker.rs | 4 ++-- 5 files changed, 18 insertions(+), 23 deletions(-) diff --git a/ext/websocket/lib.rs b/ext/websocket/lib.rs index c95d11be03f48b..c35f1c0b9b7163 100644 --- a/ext/websocket/lib.rs +++ b/ext/websocket/lib.rs @@ -28,6 +28,7 @@ use deno_fetch::HttpClientResource; use deno_fetch::get_or_create_client_from_state; use deno_net::raw::NetworkStream; use deno_permissions::PermissionCheckError; +use deno_permissions::PermissionsContainer; use deno_tls::SocketUse; use fastwebsockets::CloseCode; use fastwebsockets::FragmentCollectorRead; @@ -137,16 +138,13 @@ impl Resource for WsCancelResource { // but actual op that connects WS is async. #[op2(stack_trace)] #[smi] -pub fn op_ws_check_permission_and_cancel_handle( +pub fn op_ws_check_permission_and_cancel_handle( state: &mut OpState, #[string] api_name: String, #[string] url: String, cancel_handle: bool, -) -> Result, WebsocketError> -where - WP: WebSocketPermissions + 'static, -{ - state.borrow_mut::().check_net_url( +) -> Result, WebsocketError> { + state.borrow_mut::().check_net_url( &url::Url::parse(&url).map_err(WebsocketError::Url)?, &api_name, )?; @@ -420,7 +418,7 @@ fn populate_common_request_headers( #[op2(async, stack_trace)] #[serde] -pub async fn op_ws_create( +pub async fn op_ws_create( state: Rc>, #[string] api_name: String, #[string] url: String, @@ -428,13 +426,10 @@ pub async fn op_ws_create( #[smi] cancel_handle: Option, #[serde] headers: Option>, #[smi] client_rid: Option, -) -> Result -where - WP: WebSocketPermissions + 'static, -{ +) -> Result { let (client, allow_host) = { let mut s = state.borrow_mut(); - s.borrow_mut::() + s.borrow_mut::() .check_net_url( &url::Url::parse(&url).map_err(WebsocketError::Url)?, &api_name, @@ -869,12 +864,12 @@ pub async fn op_ws_next_event( } } -deno_core::extension!(deno_websocket, - deps = [ deno_web, deno_webidl ], - parameters = [P: WebSocketPermissions], +deno_core::extension!( + deno_websocket, + deps = [deno_web, deno_webidl], ops = [ - op_ws_check_permission_and_cancel_handle

, - op_ws_create

, + op_ws_check_permission_and_cancel_handle, + op_ws_create, op_ws_close, op_ws_next_event, op_ws_get_buffer, @@ -888,7 +883,7 @@ deno_core::extension!(deno_websocket, op_ws_send_ping, op_ws_get_buffered_amount, ], - esm = [ "01_websocket.js", "02_websocketstream.js" ], + esm = ["01_websocket.js", "02_websocketstream.js"], ); // Needed so hyper can use non Send futures diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 6b642206b1aa7e..50124c07f5acbf 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -32,7 +32,7 @@ pub fn create_runtime_snapshot( deno_canvas::deno_canvas::lazy_init(), deno_fetch::deno_fetch::lazy_init(), deno_cache::deno_cache::lazy_init(), - deno_websocket::deno_websocket::lazy_init::(), + deno_websocket::deno_websocket::lazy_init(), deno_webstorage::deno_webstorage::lazy_init(), deno_crypto::deno_crypto::lazy_init(), deno_ffi::deno_ffi::lazy_init(), diff --git a/runtime/snapshot_info.rs b/runtime/snapshot_info.rs index 83866ee6df8a9b..e7a46207767d41 100644 --- a/runtime/snapshot_info.rs +++ b/runtime/snapshot_info.rs @@ -90,7 +90,7 @@ pub fn get_extensions_in_snapshot() -> Vec { deno_canvas::deno_canvas::init(), deno_fetch::deno_fetch::init(Default::default()), deno_cache::deno_cache::init(None), - deno_websocket::deno_websocket::init::(), + deno_websocket::deno_websocket::init(), deno_webstorage::deno_webstorage::init(None), deno_crypto::deno_crypto::init(None), deno_ffi::deno_ffi::init(None), diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index e4c12791bc479f..2df9e6e6792fbe 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -539,7 +539,7 @@ impl WebWorker { ..Default::default() }), deno_cache::deno_cache::init(create_cache), - deno_websocket::deno_websocket::init::(), + deno_websocket::deno_websocket::init(), deno_webstorage::deno_webstorage::init(None).disable(), deno_crypto::deno_crypto::init(options.seed), deno_ffi::deno_ffi::init(services.deno_rt_native_addon_loader.clone()), diff --git a/runtime/worker.rs b/runtime/worker.rs index ec70184bafda9a..319fa6a52f955d 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -546,7 +546,7 @@ impl MainWorker { ..Default::default() }), deno_cache::deno_cache::args(create_cache), - deno_websocket::deno_websocket::args::(), + deno_websocket::deno_websocket::args(), deno_webstorage::deno_webstorage::args( options.origin_storage_dir.clone(), ), @@ -1049,7 +1049,7 @@ fn common_extensions< deno_canvas::deno_canvas::init(), deno_fetch::deno_fetch::lazy_init(), deno_cache::deno_cache::lazy_init(), - deno_websocket::deno_websocket::lazy_init::(), + deno_websocket::deno_websocket::lazy_init(), deno_webstorage::deno_webstorage::lazy_init(), deno_crypto::deno_crypto::lazy_init(), deno_ffi::deno_ffi::lazy_init(), From 3a7bbe2ea2311ce7c4b05eb59fa3dd3250b61cb0 Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Thu, 13 Nov 2025 13:58:55 -0800 Subject: [PATCH 08/13] remove permissions trait from deno_node --- ext/node/lib.rs | 80 +++++++++---------- ext/node/ops/dns.rs | 12 ++- ext/node/ops/fs.rs | 140 ++++++++++++--------------------- ext/node/ops/http.rs | 10 +-- ext/node/ops/inspector.rs | 17 ++-- ext/node/ops/os/mod.rs | 58 +++++--------- ext/node/ops/process.rs | 64 +++++---------- ext/node/ops/require.rs | 49 ++++-------- ext/node/ops/sqlite/backup.rs | 10 +-- ext/node/ops/worker_threads.rs | 20 ++--- runtime/snapshot.rs | 1 - runtime/snapshot_info.rs | 1 - runtime/web_worker.rs | 1 - runtime/worker.rs | 2 - 14 files changed, 169 insertions(+), 296 deletions(-) diff --git a/ext/node/lib.rs b/ext/node/lib.rs index 764991452f66fc..91d5cd244118a1 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -215,7 +215,7 @@ pub struct NodeExtInitServices< deno_core::extension!(deno_node, deps = [ deno_io, deno_fs ], - parameters = [P: NodePermissions, TInNpmPackageChecker: InNpmPackageChecker, TNpmPackageFolderResolver: NpmPackageFolderResolver, TSys: ExtNodeSys], + parameters = [TInNpmPackageChecker: InNpmPackageChecker, TNpmPackageFolderResolver: NpmPackageFolderResolver, TSys: ExtNodeSys], ops = [ ops::blocklist::op_socket_address_parse, ops::blocklist::op_socket_address_get_serialization, @@ -335,21 +335,21 @@ deno_core::extension!(deno_node, ops::crypto::x509::op_node_x509_get_serial_number, ops::crypto::x509::op_node_x509_key_usage, ops::crypto::x509::op_node_x509_public_key, - ops::dns::op_node_getaddrinfo

, - ops::fs::op_node_fs_exists_sync

, - ops::fs::op_node_fs_exists

, - ops::fs::op_node_lchmod_sync

, - ops::fs::op_node_lchmod

, - ops::fs::op_node_lchown_sync

, - ops::fs::op_node_lchown

, - ops::fs::op_node_lutimes_sync

, - ops::fs::op_node_lutimes

, - ops::fs::op_node_mkdtemp_sync

, - ops::fs::op_node_mkdtemp

, - ops::fs::op_node_open_sync

, - ops::fs::op_node_open

, - ops::fs::op_node_statfs_sync

, - ops::fs::op_node_statfs

, + ops::dns::op_node_getaddrinfo, + ops::fs::op_node_fs_exists_sync, + ops::fs::op_node_fs_exists, + ops::fs::op_node_lchmod_sync, + ops::fs::op_node_lchmod, + ops::fs::op_node_lchown_sync, + ops::fs::op_node_lchown, + ops::fs::op_node_lutimes_sync, + ops::fs::op_node_lutimes, + ops::fs::op_node_mkdtemp_sync, + ops::fs::op_node_mkdtemp, + ops::fs::op_node_open_sync, + ops::fs::op_node_open, + ops::fs::op_node_statfs_sync, + ops::fs::op_node_statfs, ops::winerror::op_node_sys_to_uv_error, ops::v8::op_v8_cached_data_version_tag, ops::v8::op_v8_get_heap_statistics, @@ -389,7 +389,7 @@ deno_core::extension!(deno_node, ops::zlib::op_zlib_crc32_string, ops::handle_wrap::op_node_new_async_id, ops::http::op_node_http_fetch_response_upgrade, - ops::http::op_node_http_request_with_conn

, + ops::http::op_node_http_request_with_conn, ops::http::op_node_http_await_information, ops::http::op_node_http_await_response, ops::http2::op_http2_connect, @@ -404,68 +404,68 @@ deno_core::extension!(deno_node, ops::http2::op_http2_accept, ops::http2::op_http2_listen, ops::http2::op_http2_send_response, - ops::os::op_node_os_get_priority

, - ops::os::op_node_os_set_priority

, - ops::os::op_node_os_user_info

, - ops::os::op_geteuid

, - ops::os::op_getegid

, - ops::os::op_cpus

, - ops::os::op_homedir

, + ops::os::op_node_os_get_priority, + ops::os::op_node_os_set_priority, + ops::os::op_node_os_user_info, + ops::os::op_geteuid, + ops::os::op_getegid, + ops::os::op_cpus, + ops::os::op_homedir, op_node_build_os, op_node_load_env_file, ops::require::op_require_can_parse_as_esm, ops::require::op_require_init_paths, - ops::require::op_require_node_module_paths, + ops::require::op_require_node_module_paths, ops::require::op_require_proxy_path, ops::require::op_require_is_deno_dir_package, ops::require::op_require_resolve_deno_dir, ops::require::op_require_is_maybe_cjs, ops::require::op_require_is_request_relative, ops::require::op_require_resolve_lookup_paths, - ops::require::op_require_try_self, - ops::require::op_require_real_path, + ops::require::op_require_try_self, + ops::require::op_require_real_path, ops::require::op_require_path_is_absolute, ops::require::op_require_path_dirname, - ops::require::op_require_stat, + ops::require::op_require_stat, ops::require::op_require_path_resolve, ops::require::op_require_path_basename, - ops::require::op_require_read_file

, + ops::require::op_require_read_file, ops::require::op_require_as_file_path, - ops::require::op_require_resolve_exports, - ops::require::op_require_read_package_scope, - ops::require::op_require_package_imports_resolve, + ops::require::op_require_resolve_exports, + ops::require::op_require_read_package_scope, + ops::require::op_require_package_imports_resolve, ops::require::op_require_break_on_next_statement, ops::util::op_node_guess_handle_type, ops::util::op_node_view_has_buffer, ops::util::op_node_call_is_from_dependency, ops::util::op_node_in_npm_package, - ops::worker_threads::op_worker_threads_filename, + ops::worker_threads::op_worker_threads_filename, ops::ipc::op_node_child_ipc_pipe, ops::ipc::op_node_ipc_write, ops::ipc::op_node_ipc_read, ops::ipc::op_node_ipc_ref, ops::ipc::op_node_ipc_unref, ops::process::op_node_process_kill, - ops::process::op_node_process_setegid

, - ops::process::op_node_process_seteuid

, - ops::process::op_node_process_setgid

, - ops::process::op_node_process_setuid

, + ops::process::op_node_process_setegid, + ops::process::op_node_process_seteuid, + ops::process::op_node_process_setgid, + ops::process::op_node_process_setuid, ops::process::op_process_abort, ops::tls::op_get_root_certificates, ops::tls::op_tls_peer_certificate, ops::tls::op_tls_canonicalize_ipv4_address, ops::tls::op_node_tls_start, ops::tls::op_node_tls_handshake, - ops::inspector::op_inspector_open

, + ops::inspector::op_inspector_open, ops::inspector::op_inspector_close, ops::inspector::op_inspector_url, ops::inspector::op_inspector_wait, - ops::inspector::op_inspector_connect

, + ops::inspector::op_inspector_connect, ops::inspector::op_inspector_dispatch, ops::inspector::op_inspector_disconnect, ops::inspector::op_inspector_emit_protocol_event, ops::inspector::op_inspector_enabled, - ops::sqlite::op_node_database_backup

, + ops::sqlite::op_node_database_backup, ], objects = [ ops::perf_hooks::EldHistogram, diff --git a/ext/node/ops/dns.rs b/ext/node/ops/dns.rs index 2c645f41440be8..d2fed49e7ece80 100644 --- a/ext/node/ops/dns.rs +++ b/ext/node/ops/dns.rs @@ -9,6 +9,7 @@ use deno_core::op2; use deno_error::JsError; use deno_net::ops::NetPermToken; use deno_permissions::PermissionCheckError; +use deno_permissions::PermissionsContainer; use hyper_util::client::legacy::connect::dns::GaiResolver; use hyper_util::client::legacy::connect::dns::Name; use tower_service::Service; @@ -25,18 +26,15 @@ pub enum GetAddrInfoError { #[op2(async, stack_trace)] #[cppgc] -pub async fn op_node_getaddrinfo

( +pub async fn op_node_getaddrinfo( state: Rc>, #[string] hostname: String, port: Option, -) -> Result -where - P: crate::NodePermissions + 'static, -{ +) -> Result { { let mut state_ = state.borrow_mut(); - let permissions = state_.borrow_mut::

(); - permissions.check_net((hostname.as_str(), port), "node:dns.lookup()")?; + let permissions = state_.borrow_mut::(); + permissions.check_net(&(hostname.as_str(), port), "node:dns.lookup()")?; } let mut resolver = GaiResolver::new(); diff --git a/ext/node/ops/fs.rs b/ext/node/ops/fs.rs index 43e3b0312298d8..d1fa3322e039f4 100644 --- a/ext/node/ops/fs.rs +++ b/ext/node/ops/fs.rs @@ -15,6 +15,7 @@ use deno_fs::OpenOptions; use deno_io::fs::FileResource; use deno_permissions::CheckedPath; use deno_permissions::OpenAccessKind; +use deno_permissions::PermissionsContainer; use serde::Serialize; use crate::NodePermissions; @@ -49,14 +50,11 @@ pub enum FsError { } #[op2(fast, stack_trace)] -pub fn op_node_fs_exists_sync

( +pub fn op_node_fs_exists_sync( state: &mut OpState, #[string] path: &str, -) -> Result -where - P: NodePermissions + 'static, -{ - let path = state.borrow_mut::

().check_open( +) -> Result { + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::ReadNoFollow, Some("node:fs.existsSync()"), @@ -66,16 +64,13 @@ where } #[op2(async, stack_trace)] -pub async fn op_node_fs_exists

( +pub async fn op_node_fs_exists( state: Rc>, #[string] path: String, -) -> Result -where - P: NodePermissions + 'static, -{ +) -> Result { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::ReadNoFollow, Some("node:fs.exists()"), @@ -104,20 +99,17 @@ fn open_options_to_access_kind(open_options: &OpenOptions) -> OpenAccessKind { #[op2(fast, stack_trace)] #[smi] -pub fn op_node_open_sync

( +pub fn op_node_open_sync( state: &mut OpState, #[string] path: &str, #[smi] flags: i32, #[smi] mode: u32, -) -> Result -where - P: NodePermissions + 'static, -{ +) -> Result { let path = Path::new(path); let options = get_open_options(flags, Some(mode)); let fs = state.borrow::().clone(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Borrowed(path), open_options_to_access_kind(&options), Some("node:fs.openSync"), @@ -131,15 +123,12 @@ where #[op2(async, stack_trace)] #[smi] -pub async fn op_node_open

( +pub async fn op_node_open( state: Rc>, #[string] path: String, #[smi] flags: i32, #[smi] mode: u32, -) -> Result -where - P: NodePermissions + 'static, -{ +) -> Result { let path = PathBuf::from(path); let options = get_open_options(flags, Some(mode)); @@ -147,7 +136,7 @@ where let mut state = state.borrow_mut(); ( state.borrow::().clone(), - state.borrow_mut::

().check_open( + state.borrow_mut::().check_open( Cow::Owned(path), open_options_to_access_kind(&options), Some("node:fs.open"), @@ -176,21 +165,18 @@ pub struct StatFs { #[op2(stack_trace)] #[serde] -pub fn op_node_statfs_sync

( +pub fn op_node_statfs_sync( state: &mut OpState, #[string] path: &str, bigint: bool, -) -> Result -where - P: NodePermissions + 'static, -{ - let path = state.borrow_mut::

().check_open( +) -> Result { + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::ReadNoFollow, Some("node:fs.statfsSync"), )?; state - .borrow_mut::

() + .borrow_mut::() .check_sys("statfs", "node:fs.statfsSync")?; statfs(path, bigint) @@ -198,23 +184,20 @@ where #[op2(async, stack_trace)] #[serde] -pub async fn op_node_statfs

( +pub async fn op_node_statfs( state: Rc>, #[string] path: String, bigint: bool, -) -> Result -where - P: NodePermissions + 'static, -{ +) -> Result { let path = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::ReadNoFollow, Some("node:fs.statfs"), )?; state - .borrow_mut::

() + .borrow_mut::() .check_sys("statfs", "node:fs.statfs")?; path }; @@ -349,18 +332,15 @@ fn statfs(path: CheckedPath, bigint: bool) -> Result { } #[op2(fast, stack_trace)] -pub fn op_node_lutimes_sync

( +pub fn op_node_lutimes_sync( state: &mut OpState, #[string] path: &str, #[number] atime_secs: i64, #[smi] atime_nanos: u32, #[number] mtime_secs: i64, #[smi] mtime_nanos: u32, -) -> Result<(), FsError> -where - P: NodePermissions + 'static, -{ - let path = state.borrow_mut::

().check_open( +) -> Result<(), FsError> { + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::WriteNoFollow, Some("node:fs.lutimes"), @@ -372,20 +352,17 @@ where } #[op2(async, stack_trace)] -pub async fn op_node_lutimes

( +pub async fn op_node_lutimes( state: Rc>, #[string] path: String, #[number] atime_secs: i64, #[smi] atime_nanos: u32, #[number] mtime_secs: i64, #[smi] mtime_nanos: u32, -) -> Result<(), FsError> -where - P: NodePermissions + 'static, -{ +) -> Result<(), FsError> { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::WriteNoFollow, Some("node:fs.lutimesSync"), @@ -406,16 +383,13 @@ where } #[op2(stack_trace)] -pub fn op_node_lchown_sync

( +pub fn op_node_lchown_sync( state: &mut OpState, #[string] path: &str, uid: Option, gid: Option, -) -> Result<(), FsError> -where - P: NodePermissions + 'static, -{ - let path = state.borrow_mut::

().check_open( +) -> Result<(), FsError> { + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::WriteNoFollow, Some("node:fs.lchownSync"), @@ -426,18 +400,15 @@ where } #[op2(async, stack_trace)] -pub async fn op_node_lchown

( +pub async fn op_node_lchown( state: Rc>, #[string] path: String, uid: Option, gid: Option, -) -> Result<(), FsError> -where - P: NodePermissions + 'static, -{ +) -> Result<(), FsError> { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::WriteNoFollow, Some("node:fs.lchown"), @@ -449,15 +420,12 @@ where } #[op2(fast, stack_trace)] -pub fn op_node_lchmod_sync

( +pub fn op_node_lchmod_sync( state: &mut OpState, #[string] path: &str, #[smi] mode: u32, -) -> Result<(), FsError> -where - P: NodePermissions + 'static, -{ - let path = state.borrow_mut::

().check_open( +) -> Result<(), FsError> { + let path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::WriteNoFollow, Some("node:fs.lchmodSync"), @@ -468,17 +436,14 @@ where } #[op2(async, stack_trace)] -pub async fn op_node_lchmod

( +pub async fn op_node_lchmod( state: Rc>, #[string] path: String, #[smi] mode: u32, -) -> Result<(), FsError> -where - P: NodePermissions + 'static, -{ +) -> Result<(), FsError> { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::

().check_open( + let path = state.borrow_mut::().check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::WriteNoFollow, Some("node:fs.lchmod"), @@ -491,17 +456,14 @@ where #[op2(stack_trace)] #[string] -pub fn op_node_mkdtemp_sync

( +pub fn op_node_mkdtemp_sync( state: &mut OpState, #[string] path: &str, -) -> Result -where - P: NodePermissions + 'static, -{ +) -> Result { // https://github.com/nodejs/node/blob/2ea31e53c61463727c002c2d862615081940f355/deps/uv/src/unix/os390-syscalls.c#L409 for _ in 0..libc::TMP_MAX { let path = temp_path_append_suffix(path); - let checked_path = state.borrow_mut::

().check_open( + let checked_path = state.borrow_mut::().check_open( Cow::Borrowed(Path::new(&path)), OpenAccessKind::WriteNoFollow, Some("node:fs.mkdtempSync()"), @@ -525,23 +487,21 @@ where #[op2(async, stack_trace)] #[string] -pub async fn op_node_mkdtemp

( +pub async fn op_node_mkdtemp( state: Rc>, #[string] path: String, -) -> Result -where - P: NodePermissions + 'static, -{ +) -> Result { // https://github.com/nodejs/node/blob/2ea31e53c61463727c002c2d862615081940f355/deps/uv/src/unix/os390-syscalls.c#L409 for _ in 0..libc::TMP_MAX { let path = temp_path_append_suffix(&path); let (fs, checked_path) = { let mut state = state.borrow_mut(); - let checked_path = state.borrow_mut::

().check_open( - Cow::Owned(PathBuf::from(path.clone())), - OpenAccessKind::WriteNoFollow, - Some("node:fs.mkdtemp()"), - )?; + let checked_path = + state.borrow_mut::().check_open( + Cow::Owned(PathBuf::from(path.clone())), + OpenAccessKind::WriteNoFollow, + Some("node:fs.mkdtemp()"), + )?; (state.borrow::().clone(), checked_path) }; diff --git a/ext/node/ops/http.rs b/ext/node/ops/http.rs index dfe1adfd3dc506..2f2f489ced65f1 100644 --- a/ext/node/ops/http.rs +++ b/ext/node/ops/http.rs @@ -43,6 +43,7 @@ use deno_net::raw::NetworkStreamReadHalf; use deno_net::raw::NetworkStreamWriteHalf; use deno_net::raw::take_network_stream_resource; use deno_permissions::PermissionCheckError; +use deno_permissions::PermissionsContainer; use http::Method; use http::header::AUTHORIZATION; use http::header::CONTENT_LENGTH; @@ -156,7 +157,7 @@ pub enum ConnError { // This is triggering a known false positive for explicit drop(state) calls. // See https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_refcell_ref #[allow(clippy::await_holding_refcell_ref)] -pub async fn op_node_http_request_with_conn

( +pub async fn op_node_http_request_with_conn( state: Rc>, #[serde] method: ByteString, #[string] url: String, @@ -164,10 +165,7 @@ pub async fn op_node_http_request_with_conn

( #[serde] headers: Vec<(ByteString, ByteString)>, #[smi] body: Option, #[smi] conn_rid: ResourceId, -) -> Result -where - P: crate::NodePermissions + 'static, -{ +) -> Result { let stream = take_network_stream_resource( &mut state.borrow_mut().resource_table, conn_rid, @@ -184,7 +182,7 @@ where { let mut state_ = state.borrow_mut(); - let permissions = state_.borrow_mut::

(); + let permissions = state_.borrow_mut::(); permissions.check_net_url(&url_parsed, "ClientRequest")?; } diff --git a/ext/node/ops/inspector.rs b/ext/node/ops/inspector.rs index e3bf427b8211eb..4b78889d048310 100644 --- a/ext/node/ops/inspector.rs +++ b/ext/node/ops/inspector.rs @@ -11,6 +11,7 @@ use deno_core::OpState; use deno_core::op2; use deno_core::v8; use deno_error::JsErrorBox; +use deno_permissions::PermissionsContainer; use crate::NodePermissions; @@ -21,14 +22,11 @@ pub fn op_inspector_enabled() -> bool { } #[op2(stack_trace)] -pub fn op_inspector_open

( +pub fn op_inspector_open( _state: &mut OpState, _port: Option, #[string] _host: Option, -) -> Result<(), JsErrorBox> -where - P: NodePermissions + 'static, -{ +) -> Result<(), JsErrorBox> { // TODO: hook up to InspectorServer /* let server = state.borrow_mut::(); @@ -106,18 +104,15 @@ pub enum InspectorConnectError { #[op2(stack_trace)] #[cppgc] -pub fn op_inspector_connect<'s, P>( +pub fn op_inspector_connect<'s>( isolate: &v8::Isolate, scope: &mut v8::PinScope<'s, '_>, state: &mut OpState, connect_to_main_thread: bool, callback: v8::Local<'s, v8::Function>, -) -> Result -where - P: NodePermissions + 'static, -{ +) -> Result { state - .borrow_mut::

() + .borrow_mut::() .check_sys("inspector", "inspector.Session.connect")?; if connect_to_main_thread { diff --git a/ext/node/ops/os/mod.rs b/ext/node/ops/os/mod.rs index e00ef5a0544cd9..a10345f0f5cc1e 100644 --- a/ext/node/ops/os/mod.rs +++ b/ext/node/ops/os/mod.rs @@ -5,6 +5,7 @@ use std::mem::MaybeUninit; use deno_core::OpState; use deno_core::op2; use deno_permissions::PermissionCheckError; +use deno_permissions::PermissionsContainer; use sys_traits::EnvHomeDir; use crate::NodePermissions; @@ -34,15 +35,12 @@ pub enum OsError { } #[op2(fast, stack_trace)] -pub fn op_node_os_get_priority

( +pub fn op_node_os_get_priority( state: &mut OpState, pid: u32, -) -> Result -where - P: NodePermissions + 'static, -{ +) -> Result { { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions.check_sys("getPriority", "node:os.getPriority()")?; } @@ -50,16 +48,13 @@ where } #[op2(fast, stack_trace)] -pub fn op_node_os_set_priority

( +pub fn op_node_os_set_priority( state: &mut OpState, pid: u32, priority: i32, -) -> Result<(), OsError> -where - P: NodePermissions + 'static, -{ +) -> Result<(), OsError> { { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions.check_sys("setPriority", "node:os.setPriority()")?; } @@ -207,15 +202,12 @@ fn get_user_info(_uid: u32) -> Result { #[op2(stack_trace)] #[serde] -pub fn op_node_os_user_info

( +pub fn op_node_os_user_info( state: &mut OpState, #[smi] uid: u32, -) -> Result -where - P: NodePermissions + 'static, -{ +) -> Result { { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions .check_sys("userInfo", "node:os.userInfo()") .map_err(OsError::Permission)?; @@ -225,12 +217,9 @@ where } #[op2(fast, stack_trace)] -pub fn op_geteuid

(state: &mut OpState) -> Result -where - P: NodePermissions + 'static, -{ +pub fn op_geteuid(state: &mut OpState) -> Result { { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions.check_sys("uid", "node:os.geteuid()")?; } @@ -244,12 +233,9 @@ where } #[op2(fast, stack_trace)] -pub fn op_getegid

(state: &mut OpState) -> Result -where - P: NodePermissions + 'static, -{ +pub fn op_getegid(state: &mut OpState) -> Result { { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions.check_sys("getegid", "node:os.getegid()")?; } @@ -264,12 +250,9 @@ where #[op2(stack_trace)] #[serde] -pub fn op_cpus

(state: &mut OpState) -> Result, OsError> -where - P: NodePermissions + 'static, -{ +pub fn op_cpus(state: &mut OpState) -> Result, OsError> { { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions.check_sys("cpus", "node:os.cpus()")?; } @@ -278,14 +261,11 @@ where #[op2(stack_trace)] #[string] -pub fn op_homedir

( +pub fn op_homedir( state: &mut OpState, -) -> Result, PermissionCheckError> -where - P: NodePermissions + 'static, -{ +) -> Result, PermissionCheckError> { { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions.check_sys("homedir", "node:os.homedir()")?; } diff --git a/ext/node/ops/process.rs b/ext/node/ops/process.rs index 9100e2401b1e70..ca7da08565e80d 100644 --- a/ext/node/ops/process.rs +++ b/ext/node/ops/process.rs @@ -122,16 +122,13 @@ fn serialize_id<'a>( #[cfg(not(any(target_os = "android", target_os = "windows")))] #[op2(fast, stack_trace)] -pub fn op_node_process_setegid( +pub fn op_node_process_setegid<'a>( scope: &mut v8::PinScope<'a, '_>, state: &mut OpState, id: v8::Local<'a, v8::Value>, -) -> Result<(), ProcessError> -where - P: NodePermissions + 'static, -{ +) -> Result<(), ProcessError> { { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions.check_sys("setegid", "node:process.setegid")?; } @@ -147,14 +144,11 @@ where #[cfg(any(target_os = "android", target_os = "windows"))] #[op2(fast, stack_trace)] -pub fn op_node_process_setegid

( +pub fn op_node_process_setegid( _scope: &mut v8::PinScope<'_, '_>, _state: &mut OpState, _id: v8::Local<'_, v8::Value>, -) -> Result<(), ProcessError> -where - P: NodePermissions + 'static, -{ +) -> Result<(), ProcessError> { Err(ProcessError::NotSupported) } @@ -174,16 +168,13 @@ fn get_user_id(name: &str) -> Result { #[cfg(not(any(target_os = "android", target_os = "windows")))] #[op2(fast, stack_trace)] -pub fn op_node_process_seteuid( +pub fn op_node_process_seteuid<'a>( scope: &mut v8::PinScope<'a, '_>, state: &mut OpState, id: v8::Local<'a, v8::Value>, -) -> Result<(), ProcessError> -where - P: NodePermissions + 'static, -{ +) -> Result<(), ProcessError> { { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions.check_sys("seteuid", "node:process.seteuid")?; } @@ -199,29 +190,23 @@ where #[cfg(any(target_os = "android", target_os = "windows"))] #[op2(fast, stack_trace)] -pub fn op_node_process_seteuid

( +pub fn op_node_process_seteuid( _scope: &mut v8::PinScope<'_, '_>, _state: &mut OpState, _id: v8::Local<'_, v8::Value>, -) -> Result<(), ProcessError> -where - P: NodePermissions + 'static, -{ +) -> Result<(), ProcessError> { Err(ProcessError::NotSupported) } #[cfg(not(any(target_os = "android", target_os = "windows")))] #[op2(fast, stack_trace)] -pub fn op_node_process_setgid( +pub fn op_node_process_setgid<'a>( scope: &mut v8::PinScope<'a, '_>, state: &mut OpState, id: v8::Local<'a, v8::Value>, -) -> Result<(), ProcessError> -where - P: NodePermissions + 'static, -{ +) -> Result<(), ProcessError> { { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions.check_sys("setgid", "node:process.setgid")?; } @@ -237,29 +222,23 @@ where #[cfg(any(target_os = "android", target_os = "windows"))] #[op2(fast, stack_trace)] -pub fn op_node_process_setgid

( +pub fn op_node_process_setgid( _scope: &mut v8::PinScope<'_, '_>, _state: &mut OpState, _id: v8::Local<'_, v8::Value>, -) -> Result<(), ProcessError> -where - P: NodePermissions + 'static, -{ +) -> Result<(), ProcessError> { Err(ProcessError::NotSupported) } #[cfg(not(any(target_os = "android", target_os = "windows")))] #[op2(fast, stack_trace)] -pub fn op_node_process_setuid( +pub fn op_node_process_setuid<'a>( scope: &mut v8::PinScope<'a, '_>, state: &mut OpState, id: v8::Local<'a, v8::Value>, -) -> Result<(), ProcessError> -where - P: NodePermissions + 'static, -{ +) -> Result<(), ProcessError> { { - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions.check_sys("setuid", "node:process.setuid")?; } @@ -275,13 +254,10 @@ where #[cfg(any(target_os = "android", target_os = "windows"))] #[op2(fast, stack_trace)] -pub fn op_node_process_setuid

( +pub fn op_node_process_setuid( _scope: &mut v8::PinScope<'_, '_>, _state: &mut OpState, _id: v8::Local<'_, v8::Value>, -) -> Result<(), ProcessError> -where - P: NodePermissions + 'static, -{ +) -> Result<(), ProcessError> { Err(ProcessError::NotSupported) } diff --git a/ext/node/ops/require.rs b/ext/node/ops/require.rs index a03d3f3a7e981e..63d77b0add6b7d 100644 --- a/ext/node/ops/require.rs +++ b/ext/node/ops/require.rs @@ -18,6 +18,7 @@ use deno_package_json::PackageJsonRc; use deno_path_util::normalize_path; use deno_path_util::url_from_file_path; use deno_path_util::url_to_file_path; +use deno_permissions::PermissionsContainer; use node_resolver::InNpmPackageChecker; use node_resolver::NodeResolutionKind; use node_resolver::NpmPackageFolderResolver; @@ -29,21 +30,17 @@ use node_resolver::errors::PackageJsonLoadError; use sys_traits::FsMetadataValue; use crate::ExtNodeSys; -use crate::NodePermissions; use crate::NodeRequireLoaderRc; use crate::NodeResolverRc; use crate::PackageJsonResolverRc; #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] -fn ensure_read_permission<'a, P>( +fn ensure_read_permission<'a>( state: &mut OpState, file_path: Cow<'a, Path>, -) -> Result, JsErrorBox> -where - P: NodePermissions + 'static, -{ +) -> Result, JsErrorBox> { let loader = state.borrow::().clone(); - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); loader.ensure_read_permission(permissions, file_path) } @@ -170,10 +167,7 @@ pub fn op_require_init_paths() -> Vec { #[op2(stack_trace)] #[serde] -pub fn op_require_node_module_paths< - P: NodePermissions + 'static, - TSys: ExtNodeSys + 'static, ->( +pub fn op_require_node_module_paths( state: &mut OpState, #[string] from: &str, ) -> Result, RequireError> { @@ -349,10 +343,7 @@ pub fn op_require_path_is_absolute(#[string] p: &str) -> bool { } #[op2(fast, stack_trace)] -pub fn op_require_stat< - P: NodePermissions + 'static, - TSys: ExtNodeSys + 'static, ->( +pub fn op_require_stat( state: &mut OpState, #[string] path: &str, ) -> Result { @@ -362,7 +353,7 @@ pub fn op_require_stat< // because they're noisy and it's fine path } else { - ensure_read_permission::

(state, path)? + ensure_read_permission(state, path)? }; let sys = state.borrow::(); if let Ok(metadata) = sys.fs_metadata(&path) { @@ -378,15 +369,12 @@ pub fn op_require_stat< #[op2(stack_trace)] #[string] -pub fn op_require_real_path< - P: NodePermissions + 'static, - TSys: ExtNodeSys + 'static, ->( +pub fn op_require_real_path( state: &mut OpState, #[string] request: &str, ) -> Result { let path = Cow::Borrowed(Path::new(request)); - let path = ensure_read_permission::

(state, path) + let path = ensure_read_permission(state, path) .map_err(RequireErrorKind::Permission)?; let sys = state.borrow::(); let canonicalized_path = @@ -452,7 +440,6 @@ pub fn op_require_path_basename( #[op2(stack_trace)] #[string] pub fn op_require_try_self< - P: NodePermissions + 'static, TInNpmPackageChecker: InNpmPackageChecker + 'static, TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, TSys: ExtNodeSys + 'static, @@ -514,16 +501,13 @@ pub fn op_require_try_self< #[op2(stack_trace)] #[to_v8] -pub fn op_require_read_file

( +pub fn op_require_read_file( state: &mut OpState, #[string] file_path: &str, -) -> Result -where - P: NodePermissions + 'static, -{ +) -> Result { let file_path = Cow::Borrowed(Path::new(file_path)); // todo(dsherret): there's multiple borrows to NodeRequireLoaderRc here - let file_path = ensure_read_permission::

(state, file_path) + let file_path = ensure_read_permission(state, file_path) .map_err(RequireErrorKind::Permission)?; let loader = state.borrow::(); loader @@ -546,7 +530,6 @@ pub fn op_require_as_file_path(#[string] file_or_url: &str) -> Option { #[op2(stack_trace)] #[string] pub fn op_require_resolve_exports< - P: NodePermissions + 'static, TInNpmPackageChecker: InNpmPackageChecker + 'static, TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, TSys: ExtNodeSys + 'static, @@ -632,10 +615,7 @@ pub fn op_require_is_maybe_cjs( #[op2(stack_trace)] #[serde] -pub fn op_require_read_package_scope< - P: NodePermissions + 'static, - TSys: ExtNodeSys + 'static, ->( +pub fn op_require_read_package_scope( state: &mut OpState, #[string] package_json_path: &str, ) -> Option { @@ -654,7 +634,6 @@ pub fn op_require_read_package_scope< #[op2(stack_trace)] #[string] pub fn op_require_package_imports_resolve< - P: NodePermissions + 'static, TInNpmPackageChecker: InNpmPackageChecker + 'static, TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, TSys: ExtNodeSys + 'static, @@ -664,7 +643,7 @@ pub fn op_require_package_imports_resolve< #[string] request: &str, ) -> Result, RequireError> { let referrer_path = Cow::Borrowed(Path::new(referrer_filename)); - let referrer_path = ensure_read_permission::

(state, referrer_path) + let referrer_path = ensure_read_permission(state, referrer_path) .map_err(RequireErrorKind::Permission)?; let pkg_json_resolver = state.borrow::>(); let Some(pkg) = pkg_json_resolver.get_closest_package_json(&referrer_path)? diff --git a/ext/node/ops/sqlite/backup.rs b/ext/node/ops/sqlite/backup.rs index 3f3ceaf49ee9b7..c58dbbf49deb4f 100644 --- a/ext/node/ops/sqlite/backup.rs +++ b/ext/node/ops/sqlite/backup.rs @@ -7,6 +7,7 @@ use std::time; use deno_core::OpState; use deno_core::op2; use deno_permissions::OpenAccessKind; +use deno_permissions::PermissionsContainer; use rusqlite::Connection; use rusqlite::backup; use serde::Deserialize; @@ -33,19 +34,16 @@ struct BackupResult { #[op2(stack_trace)] #[serde] -pub fn op_node_database_backup

( +pub fn op_node_database_backup( state: &mut OpState, #[cppgc] source_db: &DatabaseSync, #[string] path: &str, #[serde] options: Option, -) -> Result -where - P: NodePermissions + 'static, -{ +) -> Result { let src_conn_ref = source_db.conn.borrow(); let src_conn = src_conn_ref.as_ref().ok_or(SqliteError::SessionClosed)?; let path = std::path::Path::new(path); - let checked_path = state.borrow_mut::

().check_open( + let checked_path = state.borrow_mut::().check_open( Cow::Borrowed(path), OpenAccessKind::Write, Some("node:sqlite.backup"), diff --git a/ext/node/ops/worker_threads.rs b/ext/node/ops/worker_threads.rs index 36fee525dfe8bf..900910ebfe8619 100644 --- a/ext/node/ops/worker_threads.rs +++ b/ext/node/ops/worker_threads.rs @@ -8,21 +8,18 @@ use deno_core::OpState; use deno_core::op2; use deno_core::url::Url; use deno_error::JsErrorBox; +use deno_permissions::PermissionsContainer; use crate::ExtNodeSys; -use crate::NodePermissions; use crate::NodeRequireLoaderRc; #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] -fn ensure_read_permission<'a, P>( +fn ensure_read_permission<'a>( state: &mut OpState, file_path: Cow<'a, Path>, -) -> Result, JsErrorBox> -where - P: NodePermissions + 'static, -{ +) -> Result, JsErrorBox> { let loader = state.borrow::().clone(); - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); loader.ensure_read_permission(permissions, file_path) } @@ -72,10 +69,7 @@ pub enum WorkerThreadsFilenameError { // todo(dsherret): we should remove this and do all this work inside op_create_worker #[op2(stack_trace)] #[string] -pub fn op_worker_threads_filename< - P: NodePermissions + 'static, - TSys: ExtNodeSys + 'static, ->( +pub fn op_worker_threads_filename( state: &mut OpState, #[string] specifier: &str, ) -> Result, WorkerThreadsFilenameError> { @@ -89,7 +83,7 @@ pub fn op_worker_threads_filename< if path.is_relative() && !specifier.starts_with('.') { return Err(WorkerThreadsFilenameError::InvalidRelativeUrl); } - let path = ensure_read_permission::

(state, Cow::Borrowed(path)) + let path = ensure_read_permission(state, Cow::Borrowed(path)) .map_err(WorkerThreadsFilenameError::Permission)?; let sys = state.borrow::(); let canonicalized_path = @@ -100,7 +94,7 @@ pub fn op_worker_threads_filename< let url_path = url .to_file_path() .map_err(|_| WorkerThreadsFilenameError::UrlToPathString)?; - let url_path = ensure_read_permission::

(state, Cow::Owned(url_path)) + let url_path = ensure_read_permission(state, Cow::Owned(url_path)) .map_err(WorkerThreadsFilenameError::Permission)?; let sys = state.borrow::(); if !sys.fs_exists_no_err(&url_path) { diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 50124c07f5acbf..64580bf5cea285 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -48,7 +48,6 @@ pub fn create_runtime_snapshot( deno_os::deno_os::lazy_init(), deno_process::deno_process::lazy_init(), deno_node::deno_node::lazy_init::< - Permissions, DenoInNpmPackageChecker, NpmResolver, sys_traits::impls::RealSys, diff --git a/runtime/snapshot_info.rs b/runtime/snapshot_info.rs index e7a46207767d41..241b427b1f9042 100644 --- a/runtime/snapshot_info.rs +++ b/runtime/snapshot_info.rs @@ -108,7 +108,6 @@ pub fn get_extensions_in_snapshot() -> Vec { deno_os::deno_os::init(Default::default()), deno_process::deno_process::init(Default::default()), deno_node::deno_node::init::< - Permissions, DenoInNpmPackageChecker, NpmResolver, sys_traits::impls::RealSys, diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 2df9e6e6792fbe..afca081ae71e17 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -575,7 +575,6 @@ impl WebWorker { deno_os::deno_os::init(None), deno_process::deno_process::init(services.npm_process_state_provider), deno_node::deno_node::init::< - PermissionsContainer, TInNpmPackageChecker, TNpmPackageFolderResolver, TExtNodeSys, diff --git a/runtime/worker.rs b/runtime/worker.rs index 319fa6a52f955d..fec48c24c9038c 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -586,7 +586,6 @@ impl MainWorker { deno_os::deno_os::args(Some(exit_code.clone())), deno_process::deno_process::args(services.npm_process_state_provider), deno_node::deno_node::args::< - PermissionsContainer, TInNpmPackageChecker, TNpmPackageFolderResolver, TExtNodeSys, @@ -1064,7 +1063,6 @@ fn common_extensions< deno_os::deno_os::lazy_init(), deno_process::deno_process::lazy_init(), deno_node::deno_node::lazy_init::< - PermissionsContainer, TInNpmPackageChecker, TNpmPackageFolderResolver, TExtNodeSys, From ccedf4444da4148407a75e22a716ec056975317a Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Thu, 13 Nov 2025 14:08:29 -0800 Subject: [PATCH 09/13] fmt --- ext/fs/ops.rs | 652 +++++++++--------- ext/net/ops.rs | 16 +- .../permissions/runtime_descriptor_parser.rs | 3 +- 3 files changed, 351 insertions(+), 320 deletions(-) diff --git a/ext/fs/ops.rs b/ext/fs/ops.rs index cc03b9042aaddb..4469afa46a2d34 100644 --- a/ext/fs/ops.rs +++ b/ext/fs/ops.rs @@ -123,11 +123,13 @@ pub fn op_fs_chdir( state: &mut OpState, #[string] directory: &str, ) -> Result<(), FsOpsError> { - let d = state.borrow_mut::().check_open( - Cow::Borrowed(Path::new(directory)), - OpenAccessKind::ReadNoFollow, - Some("Deno.chdir()"), - )?; + let d = state + .borrow_mut::() + .check_open( + Cow::Borrowed(Path::new(directory)), + OpenAccessKind::ReadNoFollow, + Some("Deno.chdir()"), + )?; state .borrow::() .chdir(&d) @@ -178,8 +180,7 @@ pub fn op_fs_open_sync( state: &mut OpState, #[string] path: &str, #[serde] options: Option, -) -> Result -{ +) -> Result { let options = match options { Some(options) => OpenOptions::from(options), None => OpenOptions::read(), @@ -187,11 +188,13 @@ pub fn op_fs_open_sync( let path = Path::new(path); let fs = state.borrow::().clone(); - let path = state.borrow_mut::().check_open( - Cow::Borrowed(path), - open_options_to_access_kind(&options), - Some("Deno.openSync()"), - )?; + let path = state + .borrow_mut::() + .check_open( + Cow::Borrowed(path), + open_options_to_access_kind(&options), + Some("Deno.openSync()"), + )?; let file = fs.open_sync(&path, options).context_path("open", &path)?; let rid = state .resource_table @@ -205,8 +208,7 @@ pub async fn op_fs_open_async( state: Rc>, #[string] path: String, #[serde] options: Option, -) -> Result -{ +) -> Result { let options = match options { Some(options) => OpenOptions::from(options), None => OpenOptions::read(), @@ -217,11 +219,13 @@ pub async fn op_fs_open_async( let mut state = state.borrow_mut(); ( state.borrow::().clone(), - state.borrow_mut::().check_open( - Cow::Owned(path), - open_options_to_access_kind(&options), - Some("Deno.open()"), - )?, + state + .borrow_mut::() + .check_open( + Cow::Owned(path), + open_options_to_access_kind(&options), + Some("Deno.open()"), + )?, ) }; let file = fs @@ -242,15 +246,16 @@ pub fn op_fs_mkdir_sync( #[string] path: &str, recursive: bool, mode: Option, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let mode = mode.unwrap_or(0o777) & 0o777; - let path = state.borrow_mut::().check_open( - Cow::Borrowed(Path::new(path)), - OpenAccessKind::WriteNoFollow, - Some("Deno.mkdirSync()"), - )?; + let path = state + .borrow_mut::() + .check_open( + Cow::Borrowed(Path::new(path)), + OpenAccessKind::WriteNoFollow, + Some("Deno.mkdirSync()"), + )?; let fs = state.borrow::(); fs.mkdir_sync(&path, recursive, Some(mode)) @@ -265,17 +270,18 @@ pub async fn op_fs_mkdir_async( #[string] path: String, recursive: bool, mode: Option, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let mode = mode.unwrap_or(0o777) & 0o777; let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::().check_open( - Cow::Owned(PathBuf::from(path)), - OpenAccessKind::WriteNoFollow, - Some("Deno.mkdir()"), - )?; + let path = state + .borrow_mut::() + .check_open( + Cow::Owned(PathBuf::from(path)), + OpenAccessKind::WriteNoFollow, + Some("Deno.mkdir()"), + )?; (state.borrow::().clone(), path) }; @@ -292,13 +298,14 @@ pub fn op_fs_chmod_sync( state: &mut OpState, #[string] path: &str, mode: u32, -) -> Result<(), FsOpsError> -{ - let path = state.borrow_mut::().check_open( - Cow::Borrowed(Path::new(path)), - OpenAccessKind::WriteNoFollow, - Some("Deno.chmodSync()"), - )?; +) -> Result<(), FsOpsError> { + let path = state + .borrow_mut::() + .check_open( + Cow::Borrowed(Path::new(path)), + OpenAccessKind::WriteNoFollow, + Some("Deno.chmodSync()"), + )?; let fs = state.borrow::(); fs.chmod_sync(&path, mode).context_path("chmod", &path)?; Ok(()) @@ -310,13 +317,14 @@ pub fn op_fs_chmod_sync( state: &mut OpState, #[string] path: &str, mode: i32, -) -> Result<(), FsOpsError> -{ - let path = state.borrow_mut::().check_open( - Cow::Borrowed(Path::new(path)), - OpenAccessKind::WriteNoFollow, - Some("Deno.chmodSync()"), - )?; +) -> Result<(), FsOpsError> { + let path = state + .borrow_mut::() + .check_open( + Cow::Borrowed(Path::new(path)), + OpenAccessKind::WriteNoFollow, + Some("Deno.chmodSync()"), + )?; let fs = state.borrow::(); fs.chmod_sync(&path, mode).context_path("chmod", &path)?; Ok(()) @@ -328,15 +336,16 @@ pub async fn op_fs_chmod_async( state: Rc>, #[string] path: String, mode: u32, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::().check_open( - Cow::Owned(PathBuf::from(path)), - OpenAccessKind::WriteNoFollow, - Some("Deno.chmod()"), - )?; + let path = state + .borrow_mut::() + .check_open( + Cow::Owned(PathBuf::from(path)), + OpenAccessKind::WriteNoFollow, + Some("Deno.chmod()"), + )?; (state.borrow::().clone(), path) }; fs.chmod_async(path.as_owned(), mode) @@ -351,15 +360,16 @@ pub async fn op_fs_chmod_async( state: Rc>, #[string] path: String, mode: i32, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::().check_open( - Cow::Owned(PathBuf::from(path)), - OpenAccessKind::WriteNoFollow, - Some("Deno.chmod()"), - )?; + let path = state + .borrow_mut::() + .check_open( + Cow::Owned(PathBuf::from(path)), + OpenAccessKind::WriteNoFollow, + Some("Deno.chmod()"), + )?; (state.borrow::().clone(), path) }; fs.chmod_async(path.as_owned(), mode) @@ -374,13 +384,14 @@ pub fn op_fs_chown_sync( #[string] path: &str, uid: Option, gid: Option, -) -> Result<(), FsOpsError> -{ - let path = state.borrow_mut::().check_open( - Cow::Borrowed(Path::new(path)), - OpenAccessKind::WriteNoFollow, - Some("Deno.chownSync()"), - )?; +) -> Result<(), FsOpsError> { + let path = state + .borrow_mut::() + .check_open( + Cow::Borrowed(Path::new(path)), + OpenAccessKind::WriteNoFollow, + Some("Deno.chownSync()"), + )?; let fs = state.borrow::(); fs.chown_sync(&path, uid, gid) .context_path("chown", &path)?; @@ -393,15 +404,16 @@ pub async fn op_fs_chown_async( #[string] path: String, uid: Option, gid: Option, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::().check_open( - Cow::Owned(PathBuf::from(path)), - OpenAccessKind::WriteNoFollow, - Some("Deno.chown()"), - )?; + let path = state + .borrow_mut::() + .check_open( + Cow::Owned(PathBuf::from(path)), + OpenAccessKind::WriteNoFollow, + Some("Deno.chown()"), + )?; (state.borrow::().clone(), path) }; fs.chown_async(path.as_owned(), uid, gid) @@ -465,15 +477,16 @@ pub fn op_fs_remove_sync( state: &mut OpState, #[string] path: &str, recursive: bool, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let path = Cow::Borrowed(Path::new(path)); let path = if recursive { - state.borrow_mut::().check_open( - path, - OpenAccessKind::WriteNoFollow, - Some("Deno.removeSync()"), - )? + state + .borrow_mut::() + .check_open( + path, + OpenAccessKind::WriteNoFollow, + Some("Deno.removeSync()"), + )? } else { state .borrow_mut::() @@ -492,17 +505,18 @@ pub async fn op_fs_remove_async( state: Rc>, #[string] path: String, recursive: bool, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let (fs, path) = { let mut state = state.borrow_mut(); let path = Cow::Owned(PathBuf::from(path)); let path = if recursive { - state.borrow_mut::().check_open( - path, - OpenAccessKind::WriteNoFollow, - Some("Deno.remove()"), - )? + state + .borrow_mut::() + .check_open( + path, + OpenAccessKind::WriteNoFollow, + Some("Deno.remove()"), + )? } else { state .borrow_mut::() @@ -524,9 +538,9 @@ pub fn op_fs_copy_file_sync( state: &mut OpState, #[string] from: &str, #[string] to: &str, -) -> Result<(), FsOpsError> -{ - let permissions = state.borrow_mut::(); +) -> Result<(), FsOpsError> { + let permissions = + state.borrow_mut::(); let from = permissions.check_open( Cow::Borrowed(Path::new(from)), OpenAccessKind::Read, @@ -550,11 +564,11 @@ pub async fn op_fs_copy_file_async( state: Rc>, #[string] from: String, #[string] to: String, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let (fs, from, to) = { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::(); + let permissions = + state.borrow_mut::(); let from = permissions.check_open( Cow::Owned(PathBuf::from(from)), OpenAccessKind::Read, @@ -579,13 +593,14 @@ pub fn op_fs_stat_sync( state: &mut OpState, #[string] path: &str, #[buffer] stat_out_buf: &mut [u32], -) -> Result<(), FsOpsError> -{ - let path = state.borrow_mut::().check_open( - Cow::Borrowed(Path::new(path)), - OpenAccessKind::ReadNoFollow, - Some("Deno.statSync()"), - )?; +) -> Result<(), FsOpsError> { + let path = state + .borrow_mut::() + .check_open( + Cow::Borrowed(Path::new(path)), + OpenAccessKind::ReadNoFollow, + Some("Deno.statSync()"), + )?; let fs = state.borrow::(); let stat = fs.stat_sync(&path).context_path("stat", &path)?; let serializable_stat = SerializableStat::from(stat); @@ -598,11 +613,11 @@ pub fn op_fs_stat_sync( pub async fn op_fs_stat_async( state: Rc>, #[string] path: String, -) -> Result -{ +) -> Result { let (fs, path) = { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::(); + let permissions = + state.borrow_mut::(); let path = permissions.check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::ReadNoFollow, @@ -622,13 +637,14 @@ pub fn op_fs_lstat_sync( state: &mut OpState, #[string] path: &str, #[buffer] stat_out_buf: &mut [u32], -) -> Result<(), FsOpsError> -{ - let path = state.borrow_mut::().check_open( - Cow::Borrowed(Path::new(path)), - OpenAccessKind::ReadNoFollow, - Some("Deno.lstatSync()"), - )?; +) -> Result<(), FsOpsError> { + let path = state + .borrow_mut::() + .check_open( + Cow::Borrowed(Path::new(path)), + OpenAccessKind::ReadNoFollow, + Some("Deno.lstatSync()"), + )?; let fs = state.borrow::(); let stat = fs.lstat_sync(&path).context_path("lstat", &path)?; let serializable_stat = SerializableStat::from(stat); @@ -641,11 +657,11 @@ pub fn op_fs_lstat_sync( pub async fn op_fs_lstat_async( state: Rc>, #[string] path: String, -) -> Result -{ +) -> Result { let (fs, path) = { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::(); + let permissions = + state.borrow_mut::(); let path = permissions.check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::ReadNoFollow, @@ -665,10 +681,10 @@ pub async fn op_fs_lstat_async( pub fn op_fs_realpath_sync( state: &mut OpState, #[string] path: &str, -) -> Result -{ +) -> Result { let fs = state.borrow::().clone(); - let permissions = state.borrow_mut::(); + let permissions = + state.borrow_mut::(); let path = permissions.check_open( Cow::Borrowed(Path::new(path)), OpenAccessKind::ReadNoFollow, @@ -686,12 +702,12 @@ pub fn op_fs_realpath_sync( pub async fn op_fs_realpath_async( state: Rc>, #[string] path: String, -) -> Result -{ +) -> Result { let (fs, path) = { let mut state = state.borrow_mut(); let fs = state.borrow::().clone(); - let permissions = state.borrow_mut::(); + let permissions = + state.borrow_mut::(); let path = permissions.check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::ReadNoFollow, @@ -713,13 +729,14 @@ pub async fn op_fs_realpath_async( pub fn op_fs_read_dir_sync( state: &mut OpState, #[string] path: &str, -) -> Result, FsOpsError> -{ - let path = state.borrow_mut::().check_open( - Cow::Borrowed(Path::new(path)), - OpenAccessKind::ReadNoFollow, - Some("Deno.readDirSync()"), - )?; +) -> Result, FsOpsError> { + let path = state + .borrow_mut::() + .check_open( + Cow::Borrowed(Path::new(path)), + OpenAccessKind::ReadNoFollow, + Some("Deno.readDirSync()"), + )?; let fs = state.borrow::(); let entries = fs.read_dir_sync(&path).context_path("readdir", &path)?; @@ -732,15 +749,16 @@ pub fn op_fs_read_dir_sync( pub async fn op_fs_read_dir_async( state: Rc>, #[string] path: String, -) -> Result, FsOpsError> -{ +) -> Result, FsOpsError> { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::().check_open( - Cow::Owned(PathBuf::from(path)), - OpenAccessKind::ReadNoFollow, - Some("Deno.readDir()"), - )?; + let path = state + .borrow_mut::() + .check_open( + Cow::Owned(PathBuf::from(path)), + OpenAccessKind::ReadNoFollow, + Some("Deno.readDir()"), + )?; (state.borrow::().clone(), path) }; @@ -757,9 +775,9 @@ pub fn op_fs_rename_sync( state: &mut OpState, #[string] oldpath: &str, #[string] newpath: &str, -) -> Result<(), FsOpsError> -{ - let permissions = state.borrow_mut::(); +) -> Result<(), FsOpsError> { + let permissions = + state.borrow_mut::(); let oldpath = permissions.check_open( Cow::Borrowed(Path::new(oldpath)), OpenAccessKind::ReadWriteNoFollow, @@ -783,11 +801,11 @@ pub async fn op_fs_rename_async( state: Rc>, #[string] oldpath: String, #[string] newpath: String, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let (fs, oldpath, newpath) = { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::(); + let permissions = + state.borrow_mut::(); let oldpath = permissions.check_open( Cow::Owned(PathBuf::from(oldpath)), OpenAccessKind::ReadWriteNoFollow, @@ -813,9 +831,9 @@ pub fn op_fs_link_sync( state: &mut OpState, #[string] oldpath: &str, #[string] newpath: &str, -) -> Result<(), FsOpsError> -{ - let permissions = state.borrow_mut::(); +) -> Result<(), FsOpsError> { + let permissions = + state.borrow_mut::(); let oldpath = permissions.check_open( Cow::Borrowed(Path::new(oldpath)), OpenAccessKind::ReadWriteNoFollow, @@ -839,11 +857,11 @@ pub async fn op_fs_link_async( state: Rc>, #[string] oldpath: String, #[string] newpath: String, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let (fs, oldpath, newpath) = { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::(); + let permissions = + state.borrow_mut::(); let oldpath = permissions.check_open( Cow::Owned(PathBuf::from(oldpath)), OpenAccessKind::ReadWriteNoFollow, @@ -870,9 +888,9 @@ pub fn op_fs_symlink_sync( #[string] oldpath: &str, #[string] newpath: &str, #[serde] file_type: Option, -) -> Result<(), FsOpsError> -{ - let permissions = state.borrow_mut::(); +) -> Result<(), FsOpsError> { + let permissions = + state.borrow_mut::(); permissions.check_write_all("Deno.symlinkSync()")?; permissions.check_read_all("Deno.symlinkSync()")?; @@ -893,11 +911,11 @@ pub async fn op_fs_symlink_async( #[string] oldpath: String, #[string] newpath: String, #[serde] file_type: Option, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let fs = { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::(); + let permissions = + state.borrow_mut::(); permissions.check_write_all("Deno.symlink()")?; permissions.check_read_all("Deno.symlink()")?; state.borrow::().clone() @@ -923,13 +941,14 @@ pub async fn op_fs_symlink_async( pub fn op_fs_read_link_sync( state: &mut OpState, #[string] path: &str, -) -> Result -{ - let path = state.borrow_mut::().check_open( - Cow::Borrowed(Path::new(path)), - OpenAccessKind::ReadNoFollow, - Some("Deno.readLink()"), - )?; +) -> Result { + let path = state + .borrow_mut::() + .check_open( + Cow::Borrowed(Path::new(path)), + OpenAccessKind::ReadNoFollow, + Some("Deno.readLink()"), + )?; let fs = state.borrow::(); @@ -943,15 +962,16 @@ pub fn op_fs_read_link_sync( pub async fn op_fs_read_link_async( state: Rc>, #[string] path: String, -) -> Result -{ +) -> Result { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::().check_open( - Cow::Owned(PathBuf::from(path)), - OpenAccessKind::ReadNoFollow, - Some("Deno.readLink()"), - )?; + let path = state + .borrow_mut::() + .check_open( + Cow::Owned(PathBuf::from(path)), + OpenAccessKind::ReadNoFollow, + Some("Deno.readLink()"), + )?; (state.borrow::().clone(), path) }; @@ -968,13 +988,14 @@ pub fn op_fs_truncate_sync( state: &mut OpState, #[string] path: &str, #[number] len: u64, -) -> Result<(), FsOpsError> -{ - let path = state.borrow_mut::().check_open( - Cow::Borrowed(Path::new(path)), - OpenAccessKind::WriteNoFollow, - Some("Deno.truncateSync()"), - )?; +) -> Result<(), FsOpsError> { + let path = state + .borrow_mut::() + .check_open( + Cow::Borrowed(Path::new(path)), + OpenAccessKind::WriteNoFollow, + Some("Deno.truncateSync()"), + )?; let fs = state.borrow::(); fs.truncate_sync(&path, len) @@ -988,15 +1009,16 @@ pub async fn op_fs_truncate_async( state: Rc>, #[string] path: String, #[number] len: u64, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::().check_open( - Cow::Owned(PathBuf::from(path)), - OpenAccessKind::WriteNoFollow, - Some("Deno.truncate()"), - )?; + let path = state + .borrow_mut::() + .check_open( + Cow::Owned(PathBuf::from(path)), + OpenAccessKind::WriteNoFollow, + Some("Deno.truncate()"), + )?; (state.borrow::().clone(), path) }; @@ -1015,13 +1037,14 @@ pub fn op_fs_utime_sync( #[smi] atime_nanos: u32, #[number] mtime_secs: i64, #[smi] mtime_nanos: u32, -) -> Result<(), FsOpsError> -{ - let path = state.borrow_mut::().check_open( - Cow::Borrowed(Path::new(path)), - OpenAccessKind::WriteNoFollow, - Some("Deno.utime()"), - )?; +) -> Result<(), FsOpsError> { + let path = state + .borrow_mut::() + .check_open( + Cow::Borrowed(Path::new(path)), + OpenAccessKind::WriteNoFollow, + Some("Deno.utime()"), + )?; let fs = state.borrow::(); fs.utime_sync(&path, atime_secs, atime_nanos, mtime_secs, mtime_nanos) @@ -1038,15 +1061,16 @@ pub async fn op_fs_utime_async( #[smi] atime_nanos: u32, #[number] mtime_secs: i64, #[smi] mtime_nanos: u32, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let (fs, path) = { let mut state = state.borrow_mut(); - let path = state.borrow_mut::().check_open( - Cow::Owned(PathBuf::from(path)), - OpenAccessKind::WriteNoFollow, - Some("Deno.utime()"), - )?; + let path = state + .borrow_mut::() + .check_open( + Cow::Owned(PathBuf::from(path)), + OpenAccessKind::WriteNoFollow, + Some("Deno.utime()"), + )?; (state.borrow::().clone(), path) }; @@ -1070,13 +1094,9 @@ pub fn op_fs_make_temp_dir_sync( #[string] dir_arg: Option, #[string] prefix: Option, #[string] suffix: Option, -) -> Result -{ - let (dir, fs) = make_temp_check_sync( - state, - dir_arg.as_deref(), - "Deno.makeTempDirSync()", - )?; +) -> Result { + let (dir, fs) = + make_temp_check_sync(state, dir_arg.as_deref(), "Deno.makeTempDirSync()")?; let mut rng = thread_rng(); @@ -1113,13 +1133,9 @@ pub async fn op_fs_make_temp_dir_async( #[string] dir_arg: Option, #[string] prefix: Option, #[string] suffix: Option, -) -> Result -{ - let (dir, fs) = make_temp_check_async( - state, - dir_arg.as_deref(), - "Deno.makeTempDir()", - )?; +) -> Result { + let (dir, fs) = + make_temp_check_async(state, dir_arg.as_deref(), "Deno.makeTempDir()")?; let mut rng = thread_rng(); @@ -1160,13 +1176,9 @@ pub fn op_fs_make_temp_file_sync( #[string] dir_arg: Option, #[string] prefix: Option, #[string] suffix: Option, -) -> Result -{ - let (dir, fs) = make_temp_check_sync( - state, - dir_arg.as_deref(), - "Deno.makeTempFileSync()", - )?; +) -> Result { + let (dir, fs) = + make_temp_check_sync(state, dir_arg.as_deref(), "Deno.makeTempFileSync()")?; let open_opts = OpenOptions { write: true, @@ -1209,13 +1221,9 @@ pub async fn op_fs_make_temp_file_async( #[string] dir_arg: Option, #[string] prefix: Option, #[string] suffix: Option, -) -> Result -{ - let (dir, fs) = make_temp_check_async( - state, - dir_arg.as_deref(), - "Deno.makeTempFile()", - )?; +) -> Result { + let (dir, fs) = + make_temp_check_async(state, dir_arg.as_deref(), "Deno.makeTempFile()")?; let open_opts = OpenOptions { write: true, @@ -1272,23 +1280,26 @@ fn make_temp_check_sync<'a>( state: &mut OpState, dir: Option<&'a str>, api_name: &str, -) -> Result<(CheckedPath<'a>, FileSystemRc), FsOpsError> -{ +) -> Result<(CheckedPath<'a>, FileSystemRc), FsOpsError> { let fs = state.borrow::().clone(); let dir = match dir { - Some(dir) => state.borrow_mut::().check_open( - Cow::Borrowed(Path::new(dir)), - OpenAccessKind::WriteNoFollow, - Some(api_name), - )?, - None => { - let dir = fs.tmp_dir().context("tmpdir")?; - state.borrow_mut::().check_open_blind( - Cow::Owned(dir), + Some(dir) => state + .borrow_mut::() + .check_open( + Cow::Borrowed(Path::new(dir)), OpenAccessKind::WriteNoFollow, - "TMP", Some(api_name), - )? + )?, + None => { + let dir = fs.tmp_dir().context("tmpdir")?; + state + .borrow_mut::() + .check_open_blind( + Cow::Owned(dir), + OpenAccessKind::WriteNoFollow, + "TMP", + Some(api_name), + )? } }; Ok((dir, fs)) @@ -1298,24 +1309,27 @@ fn make_temp_check_async<'a>( state: Rc>, dir: Option<&'a str>, api_name: &str, -) -> Result<(CheckedPath<'a>, FileSystemRc), FsOpsError> -{ +) -> Result<(CheckedPath<'a>, FileSystemRc), FsOpsError> { let mut state = state.borrow_mut(); let fs = state.borrow::().clone(); let dir = match dir { - Some(dir) => state.borrow_mut::().check_open( - Cow::Borrowed(Path::new(dir)), - OpenAccessKind::WriteNoFollow, - Some(api_name), - )?, - None => { - let dir = fs.tmp_dir().context("tmpdir")?; - state.borrow_mut::().check_open_blind( - Cow::Owned(dir), + Some(dir) => state + .borrow_mut::() + .check_open( + Cow::Borrowed(Path::new(dir)), OpenAccessKind::WriteNoFollow, - "TMP", Some(api_name), - )? + )?, + None => { + let dir = fs.tmp_dir().context("tmpdir")?; + state + .borrow_mut::() + .check_open_blind( + Cow::Owned(dir), + OpenAccessKind::WriteNoFollow, + "TMP", + Some(api_name), + )? } }; Ok((dir, fs)) @@ -1392,17 +1406,18 @@ pub fn op_fs_write_file_sync( create: bool, create_new: bool, #[buffer] data: JsBuffer, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let path = Path::new(path); let options = OpenOptions::write(create, append, create_new, mode); let fs = state.borrow::().clone(); - let path = state.borrow::().check_open( - Cow::Borrowed(path), - OpenAccessKind::Write, - Some("Deno.writeFileSync()"), - )?; + let path = state + .borrow::() + .check_open( + Cow::Borrowed(path), + OpenAccessKind::Write, + Some("Deno.writeFileSync()"), + )?; fs.write_file_sync(&path, options, &data) .context_path("writefile", &path)?; @@ -1421,8 +1436,7 @@ pub async fn op_fs_write_file_async( create_new: bool, #[buffer] data: JsBuffer, #[smi] cancel_rid: Option, -) -> Result<(), FsOpsError> -{ +) -> Result<(), FsOpsError> { let path = PathBuf::from(path); let options = OpenOptions::write(create, append, create_new, mode); @@ -1431,11 +1445,13 @@ pub async fn op_fs_write_file_async( let state = state.borrow_mut(); let cancel_handle = cancel_rid .and_then(|rid| state.resource_table.get::(rid).ok()); - let path = state.borrow::().check_open( - Cow::Owned(path), - OpenAccessKind::Write, - Some("Deno.writeFile()"), - )?; + let path = state + .borrow::() + .check_open( + Cow::Owned(path), + OpenAccessKind::Write, + Some("Deno.writeFile()"), + )?; (state.borrow::().clone(), cancel_handle, path) }; @@ -1464,8 +1480,7 @@ pub fn op_fs_read_file_sync( state: &mut OpState, #[string] path: &str, #[smi] flags: Option, -) -> Result -{ +) -> Result { let path = Path::new(path); let options = if let Some(flags) = flags { OpenOptions::from(flags) @@ -1474,11 +1489,13 @@ pub fn op_fs_read_file_sync( }; let fs = state.borrow::().clone(); - let path = state.borrow::().check_open( - Cow::Borrowed(path), - open_options_to_access_kind(&options), - Some("Deno.readFileSync()"), - )?; + let path = state + .borrow::() + .check_open( + Cow::Borrowed(path), + open_options_to_access_kind(&options), + Some("Deno.readFileSync()"), + )?; let buf = fs .read_file_sync(&path, options) @@ -1495,8 +1512,7 @@ pub async fn op_fs_read_file_async( #[string] path: String, #[smi] cancel_rid: Option, #[smi] flags: Option, -) -> Result -{ +) -> Result { let path = PathBuf::from(path); let options = if let Some(flags) = flags { OpenOptions::from(flags) @@ -1508,11 +1524,13 @@ pub async fn op_fs_read_file_async( let state = state.borrow(); let cancel_handle = cancel_rid .and_then(|rid| state.resource_table.get::(rid).ok()); - let path = state.borrow::().check_open( - Cow::Owned(path), - open_options_to_access_kind(&options), - Some("Deno.readFile()"), - )?; + let path = state + .borrow::() + .check_open( + Cow::Owned(path), + open_options_to_access_kind(&options), + Some("Deno.readFile()"), + )?; (state.borrow::().clone(), cancel_handle, path) }; @@ -1541,16 +1559,17 @@ pub async fn op_fs_read_file_async( pub fn op_fs_read_file_text_sync( state: &mut OpState, #[string] path: &str, -) -> Result -{ +) -> Result { let path = Path::new(path); let fs = state.borrow::().clone(); - let path = state.borrow::().check_open( - Cow::Borrowed(path), - OpenAccessKind::Read, - Some("Deno.readFileSync()"), - )?; + let path = state + .borrow::() + .check_open( + Cow::Borrowed(path), + OpenAccessKind::Read, + Some("Deno.readFileSync()"), + )?; let str = fs .read_text_file_lossy_sync(&path) .context_path("readfile", &path)?; @@ -1566,19 +1585,20 @@ pub async fn op_fs_read_file_text_async( state: Rc>, #[string] path: String, #[smi] cancel_rid: Option, -) -> Result -{ +) -> Result { let path = PathBuf::from(path); let (fs, cancel_handle, path) = { let state = state.borrow_mut(); let cancel_handle = cancel_rid .and_then(|rid| state.resource_table.get::(rid).ok()); - let path = state.borrow::().check_open( - Cow::Owned(path), - OpenAccessKind::Read, - Some("Deno.readFile()"), - )?; + let path = state + .borrow::() + .check_open( + Cow::Owned(path), + OpenAccessKind::Read, + Some("Deno.readFile()"), + )?; (state.borrow::().clone(), cancel_handle, path) }; @@ -1699,11 +1719,13 @@ pub fn op_fs_file_stat_sync( let file = FileResource::get_file(state, rid).map_err(FsOpsErrorKind::Resource)?; if let Some(path) = file.maybe_path() { - _ = state.borrow::().check_open( - Cow::Borrowed(path), - OpenAccessKind::Read, - Some("Deno.FsFile.prototype.statSync()"), - )?; + _ = state + .borrow::() + .check_open( + Cow::Borrowed(path), + OpenAccessKind::Read, + Some("Deno.FsFile.prototype.statSync()"), + )?; } let stat = file.stat_sync()?; let serializable_stat = SerializableStat::from(stat); @@ -1720,11 +1742,14 @@ pub async fn op_fs_file_stat_async( let file = FileResource::get_file(&state.borrow(), rid) .map_err(FsOpsErrorKind::Resource)?; if let Some(path) = file.maybe_path() { - _ = state.borrow().borrow::().check_open( - Cow::Borrowed(path), - OpenAccessKind::Read, - Some("Deno.FsFile.prototype.stat()"), - )?; + _ = state + .borrow() + .borrow::() + .check_open( + Cow::Borrowed(path), + OpenAccessKind::Read, + Some("Deno.FsFile.prototype.stat()"), + )?; } let stat = file.stat_async().await?; Ok(stat.into()) @@ -1812,11 +1837,13 @@ pub fn op_fs_futime_sync( let file = FileResource::get_file(state, rid).map_err(FsOpsErrorKind::Resource)?; if let Some(path) = file.maybe_path() { - _ = state.borrow::().check_open( - Cow::Borrowed(path), - OpenAccessKind::WriteNoFollow, - Some("Deno.FsFile.prototype.utimeSync()"), - )?; + _ = state + .borrow::() + .check_open( + Cow::Borrowed(path), + OpenAccessKind::WriteNoFollow, + Some("Deno.FsFile.prototype.utimeSync()"), + )?; } file.utime_sync(atime_secs, atime_nanos, mtime_secs, mtime_nanos)?; Ok(()) @@ -1834,11 +1861,14 @@ pub async fn op_fs_futime_async( let file = FileResource::get_file(&state.borrow(), rid) .map_err(FsOpsErrorKind::Resource)?; if let Some(path) = file.maybe_path() { - _ = state.borrow().borrow::().check_open( - Cow::Borrowed(path), - OpenAccessKind::WriteNoFollow, - Some("Deno.FsFile.prototype.utime()"), - )?; + _ = state + .borrow() + .borrow::() + .check_open( + Cow::Borrowed(path), + OpenAccessKind::WriteNoFollow, + Some("Deno.FsFile.prototype.utime()"), + )?; } file .utime_async(atime_secs, atime_nanos, mtime_secs, mtime_nanos) diff --git a/ext/net/ops.rs b/ext/net/ops.rs index e7b4c6727b60e7..6b6dc7658840c7 100644 --- a/ext/net/ops.rs +++ b/ext/net/ops.rs @@ -8,12 +8,6 @@ use std::net::SocketAddr; use std::rc::Rc; use std::str::FromStr; -use crate::io::TcpStreamResource; -use crate::raw::NetworkListenerResource; -use crate::resolve_addr::resolve_addr; -use crate::resolve_addr::resolve_addr_sync; -use crate::tcp::TcpListener; -use crate::tunnel::TunnelAddr; use deno_core::AsyncRefCell; use deno_core::ByteString; use deno_core::CancelFuture; @@ -47,6 +41,13 @@ use socket2::Type; use tokio::net::TcpStream; use tokio::net::UdpSocket; +use crate::io::TcpStreamResource; +use crate::raw::NetworkListenerResource; +use crate::resolve_addr::resolve_addr; +use crate::resolve_addr::resolve_addr_sync; +use crate::tcp::TcpListener; +use crate::tunnel::TunnelAddr; + pub type Fd = u32; #[derive(Serialize, Clone, Debug)] @@ -1411,9 +1412,10 @@ mod tests { } .boxed_local(); - use deno_permissions::RuntimePermissionDescriptorParser; use std::sync::Arc; + use deno_permissions::RuntimePermissionDescriptorParser; + deno_core::extension!( test_ext, state = |state| { diff --git a/runtime/permissions/runtime_descriptor_parser.rs b/runtime/permissions/runtime_descriptor_parser.rs index b078547d4de5e9..7b704fe382aa76 100644 --- a/runtime/permissions/runtime_descriptor_parser.rs +++ b/runtime/permissions/runtime_descriptor_parser.rs @@ -177,9 +177,8 @@ impl #[cfg(test)] mod test { - use crate::PermissionDescriptorParser; - use super::*; + use crate::PermissionDescriptorParser; #[test] fn test_handle_empty_value() { From dc4ef0d8a14e49ce7bdc5b98e2b79fd04c66c07a Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Thu, 13 Nov 2025 14:11:47 -0800 Subject: [PATCH 10/13] missing copyright --- runtime/permissions/runtime_descriptor_parser.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/permissions/runtime_descriptor_parser.rs b/runtime/permissions/runtime_descriptor_parser.rs index 7b704fe382aa76..ace010dd0bd1fe 100644 --- a/runtime/permissions/runtime_descriptor_parser.rs +++ b/runtime/permissions/runtime_descriptor_parser.rs @@ -1,3 +1,5 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + use std::borrow::Cow; use std::path::Path; use std::path::PathBuf; From 96604121ef2bb770dcea7465a568bafff05df0f0 Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Thu, 13 Nov 2025 14:18:46 -0800 Subject: [PATCH 11/13] fix windows --- ext/net/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ext/net/lib.rs b/ext/net/lib.rs index 5e136c3b189d0e..4a85ef26d982a2 100644 --- a/ext/net/lib.rs +++ b/ext/net/lib.rs @@ -155,8 +155,6 @@ deno_core::extension!(deno_net, mod ops_unix { use deno_core::op2; - use crate::NetPermissions; - macro_rules! stub_op { ($name:ident) => { #[op2(fast)] @@ -173,7 +171,7 @@ mod ops_unix { }; ($name:ident) => { #[op2(fast)] - pub fn $name() -> Result<(), std::io::Error> { + pub fn $name() -> Result<(), std::io::Error> { let error_msg = format!( "Operation `{:?}` not supported on non-unix platforms.", stringify!($name) From 4c1ae3a5dc5b56c0ccfbaf048237298881ba1e91 Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Thu, 13 Nov 2025 14:29:36 -0800 Subject: [PATCH 12/13] remove unused traits --- cli/lib/npm/permission_checker.rs | 4 +- cli/module_loader.rs | 2 +- cli/rt/run.rs | 2 +- ext/node/lib.rs | 74 +------------------------------ ext/node/ops/fs.rs | 2 - ext/node/ops/inspector.rs | 2 - ext/node/ops/os/mod.rs | 2 - ext/node/ops/process.rs | 2 - ext/node/ops/sqlite/backup.rs | 1 - ext/websocket/lib.rs | 19 -------- runtime/snapshot_info.rs | 45 ------------------- 11 files changed, 5 insertions(+), 150 deletions(-) diff --git a/cli/lib/npm/permission_checker.rs b/cli/lib/npm/permission_checker.rs index 51741002805185..11675da0e06634 100644 --- a/cli/lib/npm/permission_checker.rs +++ b/cli/lib/npm/permission_checker.rs @@ -7,8 +7,8 @@ use std::path::Path; use std::path::PathBuf; use deno_error::JsErrorBox; -use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_permissions::OpenAccessKind; +use deno_runtime::deno_permissions::PermissionsContainer; use parking_lot::Mutex; use crate::sys::DenoLibSys; @@ -49,7 +49,7 @@ impl NpmRegistryReadPermissionChecker { #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] pub fn ensure_read_permission<'a>( &self, - permissions: &mut dyn NodePermissions, + permissions: &mut PermissionsContainer, path: Cow<'a, Path>, ) -> Result, JsErrorBox> { if permissions.query_read_all() { diff --git a/cli/module_loader.rs b/cli/module_loader.rs index 8a586e33816ebc..f88d972f55d437 100644 --- a/cli/module_loader.rs +++ b/cli/module_loader.rs @@ -1323,7 +1323,7 @@ impl NodeRequireLoader { fn ensure_read_permission<'a>( &self, - permissions: &mut dyn deno_runtime::deno_node::NodePermissions, + permissions: &mut PermissionsContainer, path: Cow<'a, Path>, ) -> Result, JsErrorBox> { if let Ok(url) = deno_path_util::url_from_file_path(&path) { diff --git a/cli/rt/run.rs b/cli/rt/run.rs index bdba2b6775f26f..ec5997bb9e184e 100644 --- a/cli/rt/run.rs +++ b/cli/rt/run.rs @@ -610,7 +610,7 @@ impl ModuleLoader for EmbeddedModuleLoader { impl NodeRequireLoader for EmbeddedModuleLoader { fn ensure_read_permission<'a>( &self, - permissions: &mut dyn deno_runtime::deno_node::NodePermissions, + permissions: &mut PermissionsContainer, path: Cow<'a, Path>, ) -> Result, JsErrorBox> { if self.shared.modules.has_file(&path) { diff --git a/ext/node/lib.rs b/ext/node/lib.rs index 91d5cd244118a1..ce52ca0560751c 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -15,7 +15,6 @@ use deno_core::url::Url; use deno_core::v8; use deno_core::v8::ExternalReference; use deno_error::JsErrorBox; -use deno_permissions::CheckedPath; use deno_permissions::OpenAccessKind; use deno_permissions::PermissionsContainer; use node_resolver::DenoIsBuiltInNodeModuleChecker; @@ -50,77 +49,6 @@ pub fn is_builtin_node_module(module_name: &str) -> bool { DenoIsBuiltInNodeModuleChecker.is_builtin_node_module(module_name) } -pub trait NodePermissions { - fn check_net_url( - &mut self, - url: &Url, - api_name: &str, - ) -> Result<(), PermissionCheckError>; - fn check_net( - &mut self, - host: (&str, Option), - api_name: &str, - ) -> Result<(), PermissionCheckError>; - #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] - fn check_open<'a>( - &mut self, - path: Cow<'a, Path>, - open_access: OpenAccessKind, - api_name: Option<&str>, - ) -> Result, PermissionCheckError>; - fn query_read_all(&mut self) -> bool; - fn check_sys( - &mut self, - kind: &str, - api_name: &str, - ) -> Result<(), PermissionCheckError>; -} - -impl NodePermissions for deno_permissions::PermissionsContainer { - #[inline(always)] - fn check_net_url( - &mut self, - url: &Url, - api_name: &str, - ) -> Result<(), PermissionCheckError> { - deno_permissions::PermissionsContainer::check_net_url(self, url, api_name) - } - - fn check_net( - &mut self, - host: (&str, Option), - api_name: &str, - ) -> Result<(), PermissionCheckError> { - deno_permissions::PermissionsContainer::check_net(self, &host, api_name) - } - - fn check_open<'a>( - &mut self, - path: Cow<'a, Path>, - open_access: OpenAccessKind, - api_name: Option<&str>, - ) -> Result, PermissionCheckError> { - deno_permissions::PermissionsContainer::check_open( - self, - path, - open_access, - api_name, - ) - } - - fn query_read_all(&mut self) -> bool { - deno_permissions::PermissionsContainer::query_read_all(self) - } - - fn check_sys( - &mut self, - kind: &str, - api_name: &str, - ) -> Result<(), PermissionCheckError> { - deno_permissions::PermissionsContainer::check_sys(self, kind, api_name) - } -} - #[allow(clippy::disallowed_types)] pub type NodeRequireLoaderRc = std::rc::Rc; @@ -128,7 +56,7 @@ pub trait NodeRequireLoader { #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] fn ensure_read_permission<'a>( &self, - permissions: &mut dyn NodePermissions, + permissions: &mut PermissionsContainer, path: Cow<'a, Path>, ) -> Result, JsErrorBox>; diff --git a/ext/node/ops/fs.rs b/ext/node/ops/fs.rs index d1fa3322e039f4..dc16f7b885263b 100644 --- a/ext/node/ops/fs.rs +++ b/ext/node/ops/fs.rs @@ -18,8 +18,6 @@ use deno_permissions::OpenAccessKind; use deno_permissions::PermissionsContainer; use serde::Serialize; -use crate::NodePermissions; - #[derive(Debug, thiserror::Error, deno_error::JsError)] pub enum FsError { #[class(inherit)] diff --git a/ext/node/ops/inspector.rs b/ext/node/ops/inspector.rs index 4b78889d048310..03f95e319e73de 100644 --- a/ext/node/ops/inspector.rs +++ b/ext/node/ops/inspector.rs @@ -13,8 +13,6 @@ use deno_core::v8; use deno_error::JsErrorBox; use deno_permissions::PermissionsContainer; -use crate::NodePermissions; - #[op2(fast)] pub fn op_inspector_enabled() -> bool { // TODO: hook up to InspectorServer diff --git a/ext/node/ops/os/mod.rs b/ext/node/ops/os/mod.rs index a10345f0f5cc1e..819e4f50d6795a 100644 --- a/ext/node/ops/os/mod.rs +++ b/ext/node/ops/os/mod.rs @@ -8,8 +8,6 @@ use deno_permissions::PermissionCheckError; use deno_permissions::PermissionsContainer; use sys_traits::EnvHomeDir; -use crate::NodePermissions; - mod cpus; pub mod priority; diff --git a/ext/node/ops/process.rs b/ext/node/ops/process.rs index ca7da08565e80d..3f06b2ab8d79a9 100644 --- a/ext/node/ops/process.rs +++ b/ext/node/ops/process.rs @@ -14,8 +14,6 @@ use nix::unistd::Uid; #[cfg(unix)] use nix::unistd::User; -use crate::NodePermissions; - #[derive(Debug, thiserror::Error, deno_error::JsError)] pub enum ProcessError { #[class(inherit)] diff --git a/ext/node/ops/sqlite/backup.rs b/ext/node/ops/sqlite/backup.rs index c58dbbf49deb4f..f581de02eae346 100644 --- a/ext/node/ops/sqlite/backup.rs +++ b/ext/node/ops/sqlite/backup.rs @@ -15,7 +15,6 @@ use serde::Serialize; use super::DatabaseSync; use super::SqliteError; -use crate::NodePermissions; const DEFAULT_BACKUP_RATE: c_int = 5; diff --git a/ext/websocket/lib.rs b/ext/websocket/lib.rs index c35f1c0b9b7163..ecf4b9df40c139 100644 --- a/ext/websocket/lib.rs +++ b/ext/websocket/lib.rs @@ -102,25 +102,6 @@ pub enum WebsocketError { Canceled(#[from] deno_core::Canceled), } -pub trait WebSocketPermissions { - fn check_net_url( - &mut self, - _url: &url::Url, - _api_name: &str, - ) -> Result<(), PermissionCheckError>; -} - -impl WebSocketPermissions for deno_permissions::PermissionsContainer { - #[inline(always)] - fn check_net_url( - &mut self, - url: &url::Url, - api_name: &str, - ) -> Result<(), PermissionCheckError> { - deno_permissions::PermissionsContainer::check_net_url(self, url, api_name) - } -} - pub struct WsCancelResource(Rc); impl Resource for WsCancelResource { diff --git a/runtime/snapshot_info.rs b/runtime/snapshot_info.rs index 241b427b1f9042..05a3be2549f1b2 100644 --- a/runtime/snapshot_info.rs +++ b/runtime/snapshot_info.rs @@ -17,51 +17,6 @@ use crate::shared::runtime; #[derive(Clone)] pub struct Permissions; -impl deno_websocket::WebSocketPermissions for Permissions { - fn check_net_url( - &mut self, - _url: &deno_core::url::Url, - _api_name: &str, - ) -> Result<(), PermissionCheckError> { - unreachable!("snapshotting!") - } -} - -impl deno_node::NodePermissions for Permissions { - fn check_net_url( - &mut self, - _url: &deno_core::url::Url, - _api_name: &str, - ) -> Result<(), PermissionCheckError> { - unreachable!("snapshotting!") - } - fn check_net( - &mut self, - _host: (&str, Option), - _api_name: &str, - ) -> Result<(), PermissionCheckError> { - unreachable!("snapshotting!") - } - fn check_open<'a>( - &mut self, - _path: Cow<'a, Path>, - _open_access: OpenAccessKind, - _api_name: Option<&str>, - ) -> Result, PermissionCheckError> { - unreachable!("snapshotting!") - } - fn query_read_all(&mut self) -> bool { - unreachable!("snapshotting!") - } - fn check_sys( - &mut self, - _kind: &str, - _api_name: &str, - ) -> Result<(), PermissionCheckError> { - unreachable!("snapshotting!") - } -} - impl deno_kv::sqlite::SqliteDbHandlerPermissions for Permissions { fn check_open<'a>( &mut self, From 329d9facc6eff34cefe8098f7320511341d82532 Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Thu, 13 Nov 2025 14:33:41 -0800 Subject: [PATCH 13/13] remove permissions trait from deno_kv --- ext/kv/dynamic.rs | 10 ++----- ext/kv/remote.rs | 59 ++++++++-------------------------------- ext/kv/sqlite.rs | 50 ++++++---------------------------- runtime/snapshot.rs | 4 +-- runtime/snapshot_info.rs | 21 +------------- runtime/web_worker.rs | 2 +- runtime/worker.rs | 2 +- 7 files changed, 27 insertions(+), 121 deletions(-) diff --git a/ext/kv/dynamic.rs b/ext/kv/dynamic.rs index cb6bb4983c3007..1fd54e18d897bc 100644 --- a/ext/kv/dynamic.rs +++ b/ext/kv/dynamic.rs @@ -16,9 +16,7 @@ use crate::DatabaseHandler; use crate::QueueMessageHandle; use crate::ReadRange; use crate::SnapshotReadOptions; -use crate::remote::RemoteDbHandlerPermissions; use crate::sqlite::SqliteDbHandler; -use crate::sqlite::SqliteDbHandlerPermissions; pub struct MultiBackendDbHandler { backends: Vec<(&'static [&'static str], Box)>, @@ -31,9 +29,7 @@ impl MultiBackendDbHandler { Self { backends } } - pub fn remote_or_sqlite< - P: SqliteDbHandlerPermissions + RemoteDbHandlerPermissions + 'static, - >( + pub fn remote_or_sqlite( default_storage_dir: Option, versionstamp_rng_seed: Option, http_options: crate::remote::HttpOptions, @@ -41,11 +37,11 @@ impl MultiBackendDbHandler { Self::new(vec![ ( &["https://", "http://"], - Box::new(crate::remote::RemoteDbHandler::

::new(http_options)), + Box::new(crate::remote::RemoteDbHandler::new(http_options)), ), ( &[""], - Box::new(SqliteDbHandler::

::new( + Box::new(SqliteDbHandler::new( default_storage_dir, versionstamp_rng_seed, )), diff --git a/ext/kv/remote.rs b/ext/kv/remote.rs index 9744ddadcccd20..6f4dc1b480b1c6 100644 --- a/ext/kv/remote.rs +++ b/ext/kv/remote.rs @@ -1,7 +1,6 @@ // Copyright 2018-2025 the Deno authors. MIT license. use std::cell::RefCell; -use std::marker::PhantomData; use std::rc::Rc; use std::sync::Arc; @@ -13,7 +12,7 @@ use deno_core::futures::Stream; use deno_error::JsErrorBox; use deno_fetch::CreateHttpClientOptions; use deno_fetch::create_http_client; -use deno_permissions::PermissionCheckError; +use deno_permissions::PermissionsContainer; use deno_tls::Proxy; use deno_tls::RootCertStoreProvider; use deno_tls::TlsKeys; @@ -45,65 +44,32 @@ impl HttpOptions { } } -pub trait RemoteDbHandlerPermissions { - fn check_env(&mut self, var: &str) -> Result<(), PermissionCheckError>; - fn check_net_url( - &mut self, - url: &Url, - api_name: &str, - ) -> Result<(), PermissionCheckError>; -} - -impl RemoteDbHandlerPermissions for deno_permissions::PermissionsContainer { - #[inline(always)] - fn check_env(&mut self, var: &str) -> Result<(), PermissionCheckError> { - deno_permissions::PermissionsContainer::check_env(self, var) - } - - #[inline(always)] - fn check_net_url( - &mut self, - url: &Url, - api_name: &str, - ) -> Result<(), PermissionCheckError> { - deno_permissions::PermissionsContainer::check_net_url(self, url, api_name) - } -} - -pub struct RemoteDbHandler { +pub struct RemoteDbHandler { http_options: HttpOptions, - _p: std::marker::PhantomData

, } -impl RemoteDbHandler

{ +impl RemoteDbHandler { pub fn new(http_options: HttpOptions) -> Self { - Self { - http_options, - _p: PhantomData, - } + Self { http_options } } } -pub struct PermissionChecker { +pub struct PermissionChecker { state: Rc>, - _permissions: PhantomData

, } -impl Clone for PermissionChecker

{ +impl Clone for PermissionChecker { fn clone(&self) -> Self { Self { state: self.state.clone(), - _permissions: PhantomData, } } } -impl denokv_remote::RemotePermissions - for PermissionChecker

-{ +impl denokv_remote::RemotePermissions for PermissionChecker { fn check_net_url(&self, url: &Url) -> Result<(), JsErrorBox> { let mut state = self.state.borrow_mut(); - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions .check_net_url(url, "Deno.openKv") .map_err(JsErrorBox::from_err) @@ -162,10 +128,8 @@ impl RemoteResponse for FetchResponse { } #[async_trait(?Send)] -impl DatabaseHandler - for RemoteDbHandler

-{ - type DB = Remote, FetchClient>; +impl DatabaseHandler for RemoteDbHandler { + type DB = Remote; async fn open( &self, @@ -187,7 +151,7 @@ impl DatabaseHandler { let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::

(); + let permissions = state.borrow_mut::(); permissions .check_env(ENV_VAR_NAME) .map_err(JsErrorBox::from_err)?; @@ -236,7 +200,6 @@ impl DatabaseHandler let permissions = PermissionChecker { state: state.clone(), - _permissions: PhantomData, }; let remote = Remote::new(fetch_client, permissions, metadata_endpoint); diff --git a/ext/kv/sqlite.rs b/ext/kv/sqlite.rs index d5b13acaa7bbd1..e5a73f1849c8c5 100644 --- a/ext/kv/sqlite.rs +++ b/ext/kv/sqlite.rs @@ -3,8 +3,6 @@ use std::borrow::Cow; use std::cell::RefCell; use std::collections::HashMap; -use std::marker::PhantomData; -use std::path::Path; use std::path::PathBuf; use std::rc::Rc; use std::sync::Arc; @@ -15,9 +13,8 @@ use async_trait::async_trait; use deno_core::OpState; use deno_core::unsync::spawn_blocking; use deno_error::JsErrorBox; -use deno_permissions::CheckedPath; use deno_permissions::OpenAccessKind; -use deno_permissions::PermissionCheckError; +use deno_permissions::PermissionsContainer; pub use denokv_sqlite::SqliteBackendError; use denokv_sqlite::SqliteConfig; use denokv_sqlite::SqliteNotifier; @@ -29,40 +26,12 @@ use crate::DatabaseHandler; static SQLITE_NOTIFIERS_MAP: OnceLock>> = OnceLock::new(); -pub struct SqliteDbHandler { +pub struct SqliteDbHandler { pub default_storage_dir: Option, versionstamp_rng_seed: Option, - _permissions: PhantomData

, } -pub trait SqliteDbHandlerPermissions { - #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] - fn check_open<'a>( - &mut self, - p: Cow<'a, Path>, - open_access: OpenAccessKind, - api_name: &str, - ) -> Result, PermissionCheckError>; -} - -impl SqliteDbHandlerPermissions for deno_permissions::PermissionsContainer { - #[inline(always)] - fn check_open<'a>( - &mut self, - p: Cow<'a, Path>, - open_access: OpenAccessKind, - api_name: &str, - ) -> Result, PermissionCheckError> { - deno_permissions::PermissionsContainer::check_open( - self, - p, - open_access, - Some(api_name), - ) - } -} - -impl SqliteDbHandler

{ +impl SqliteDbHandler { pub fn new( default_storage_dir: Option, versionstamp_rng_seed: Option, @@ -70,7 +39,6 @@ impl SqliteDbHandler

{ Self { default_storage_dir, versionstamp_rng_seed, - _permissions: PhantomData, } } } @@ -88,7 +56,7 @@ enum Mode { } #[async_trait(?Send)] -impl DatabaseHandler for SqliteDbHandler

{ +impl DatabaseHandler for SqliteDbHandler { type DB = denokv_sqlite::Sqlite; async fn open( @@ -102,7 +70,7 @@ impl DatabaseHandler for SqliteDbHandler

{ } #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] - fn validate_path( + fn validate_path( state: &RefCell, path: Option, ) -> Result, JsErrorBox> { @@ -121,20 +89,20 @@ impl DatabaseHandler for SqliteDbHandler

{ )); } { - let mut state = state.borrow_mut(); - let permissions = state.borrow_mut::

(); + let state = state.borrow(); + let permissions = state.borrow::(); let path = permissions .check_open( Cow::Owned(PathBuf::from(path)), OpenAccessKind::ReadWriteNoFollow, - "Deno.openKv", + Some("Deno.openKv"), ) .map_err(JsErrorBox::from_err)?; Ok(Some(PathOrInMemory::Path(path.into_owned_path()))) } } - let path = validate_path::

(&state, path)?; + let path = validate_path(&state, path)?; let default_storage_dir = self.default_storage_dir.clone(); type ConnGen = Arc rusqlite::Result + Send + Sync>; diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 64580bf5cea285..2d087b77849a52 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -13,7 +13,6 @@ use deno_resolver::npm::NpmResolver; use crate::ops; use crate::ops::bootstrap::SnapshotOptions; use crate::shared::runtime; -use crate::snapshot_info::Permissions; pub fn create_runtime_snapshot( snapshot_path: PathBuf, @@ -38,8 +37,7 @@ pub fn create_runtime_snapshot( deno_ffi::deno_ffi::lazy_init(), deno_net::deno_net::lazy_init(), deno_tls::deno_tls::lazy_init(), - deno_kv::deno_kv::lazy_init::>( - ), + deno_kv::deno_kv::lazy_init::(), deno_cron::deno_cron::init(deno_cron::local::LocalCronHandler::new()), deno_napi::deno_napi::lazy_init(), deno_http::deno_http::lazy_init(), diff --git a/runtime/snapshot_info.rs b/runtime/snapshot_info.rs index 05a3be2549f1b2..86058d9de10081 100644 --- a/runtime/snapshot_info.rs +++ b/runtime/snapshot_info.rs @@ -1,33 +1,14 @@ // Copyright 2018-2025 the Deno authors. MIT license. -use std::borrow::Cow; -use std::path::Path; use std::sync::Arc; use deno_core::Extension; -use deno_permissions::CheckedPath; -use deno_permissions::OpenAccessKind; -use deno_permissions::PermissionCheckError; use deno_resolver::npm::DenoInNpmPackageChecker; use deno_resolver::npm::NpmResolver; use crate::ops; use crate::shared::runtime; -#[derive(Clone)] -pub struct Permissions; - -impl deno_kv::sqlite::SqliteDbHandlerPermissions for Permissions { - fn check_open<'a>( - &mut self, - _p: Cow<'a, Path>, - _open_access: OpenAccessKind, - _api_name: &str, - ) -> Result, PermissionCheckError> { - unreachable!("snapshotting!"); - } -} - pub fn get_extensions_in_snapshot() -> Vec { // NOTE(bartlomieju): ordering is important here, keep it in sync with // `runtime/worker.rs`, `runtime/web_worker.rs`, `runtime/snapshot_info.rs` @@ -52,7 +33,7 @@ pub fn get_extensions_in_snapshot() -> Vec { deno_net::deno_net::init(None, None), deno_tls::deno_tls::init(), deno_kv::deno_kv::init( - deno_kv::sqlite::SqliteDbHandler::::new(None, None), + deno_kv::sqlite::SqliteDbHandler::new(None, None), deno_kv::KvConfig::builder().build(), ), deno_cron::deno_cron::init(deno_cron::local::LocalCronHandler::new()), diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index afca081ae71e17..9623f4d77769e9 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -549,7 +549,7 @@ impl WebWorker { ), deno_tls::deno_tls::init(), deno_kv::deno_kv::init( - MultiBackendDbHandler::remote_or_sqlite::( + MultiBackendDbHandler::remote_or_sqlite( None, options.seed, deno_kv::remote::HttpOptions { diff --git a/runtime/worker.rs b/runtime/worker.rs index fec48c24c9038c..e30f67da0ed8b5 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -557,7 +557,7 @@ impl MainWorker { options.unsafely_ignore_certificate_errors.clone(), ), deno_kv::deno_kv::args( - MultiBackendDbHandler::remote_or_sqlite::( + MultiBackendDbHandler::remote_or_sqlite( options.origin_storage_dir.clone(), options.seed, deno_kv::remote::HttpOptions {