Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

111 changes: 13 additions & 98 deletions ext/fetch/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -146,12 +146,11 @@ impl Default for Options {

deno_core::extension!(deno_fetch,
deps = [ deno_webidl, deno_web ],
parameters = [FP: FetchPermissions],
ops = [
op_fetch<FP>,
op_fetch,
op_fetch_send,
op_utf8_to_byte_string,
op_fetch_custom_client<FP>,
op_fetch_custom_client,
op_fetch_promise_is_settled,
],
esm = [
Expand Down Expand Up @@ -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<CheckedPath<'a>, 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<CheckedPath<'a>, 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<FP>(
pub fn op_fetch(
state: &mut OpState,
#[serde] method: ByteString,
#[string] url: String,
Expand All @@ -497,10 +417,7 @@ pub fn op_fetch<FP>(
has_body: bool,
#[buffer] data: Option<JsBuffer>,
#[smi] resource: Option<ResourceId>,
) -> Result<FetchReturn, FetchError>
where
FP: FetchPermissions + 'static,
{
) -> Result<FetchReturn, FetchError> {
let (client, allow_host) = if let Some(rid) = client_rid {
let r = state.resource_table.get::<HttpClientResource>(rid)?;
(r.client.clone(), r.allow_host)
Expand Down Expand Up @@ -533,7 +450,7 @@ where
(request_rid, maybe_cancel_handle_rid)
}
"http" | "https" => {
let permissions = state.borrow_mut::<FP>();
let permissions = state.borrow_mut::<PermissionsContainer>();
permissions.check_net_url(&url, "fetch()")?;

let maybe_authority = extract_authority(&mut url);
Expand Down Expand Up @@ -922,23 +839,21 @@ fn default_true() -> bool {
#[op2(stack_trace)]
#[smi]
#[allow(clippy::result_large_err)]
pub fn op_fetch_custom_client<FP>(
pub fn op_fetch_custom_client(
state: &mut OpState,
#[serde] mut args: CreateHttpClientArgs,
#[cppgc] tls_keys: &TlsKeysHolder,
) -> Result<ResourceId, FetchError>
where
FP: FetchPermissions + 'static,
{
) -> Result<ResourceId, FetchError> {
if let Some(proxy) = &mut args.proxy {
let permissions = state.borrow_mut::<FP>();
let permissions = state.borrow_mut::<PermissionsContainer>();
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,
Expand All @@ -948,15 +863,15 @@ where
.check_open(
Cow::Borrowed(path),
OpenAccessKind::ReadWriteNoFollow,
"Deno.createHttpClient()",
Some("Deno.createHttpClient()"),
)?
.into_path();
if path != resolved_path {
*original_path = resolved_path.to_string_lossy().into_owned();
}
}
Proxy::Vsock { cid, port } => {
let permissions = state.borrow_mut::<FP>();
let permissions = state.borrow_mut::<PermissionsContainer>();
permissions.check_net_vsock(*cid, *port, "Deno.createHttpClient()")?;
}
}
Expand Down
25 changes: 9 additions & 16 deletions ext/ffi/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -300,24 +300,20 @@ fn ffi_call(

#[op2(async, stack_trace)]
#[serde]
pub fn op_ffi_call_ptr_nonblocking<FP>(
pub fn op_ffi_call_ptr_nonblocking(
scope: &mut v8::PinScope<'_, '_>,
state: Rc<RefCell<OpState>>,
pointer: *mut c_void,
#[serde] def: ForeignFunction,
parameters: v8::Local<v8::Array>,
out_buffer: Option<v8::Local<v8::TypedArray>>,
) -> Result<
impl Future<Output = Result<FfiValue, CallError>> + use<FP>,
CallError,
>
) -> Result<impl Future<Output = Result<FfiValue, CallError>> + use<>, CallError>
where
FP: FfiPermissions + 'static,
{
{
let mut state = state.borrow_mut();
let permissions = state.borrow_mut::<FP>();
permissions.check_partial_no_path()?;
let permissions = state.borrow_mut::<PermissionsContainer>();
permissions.check_ffi_partial_no_path()?;
};

let symbol = PtrSymbol::new(pointer, &def)?;
Expand Down Expand Up @@ -399,21 +395,18 @@ pub fn op_ffi_call_nonblocking(

#[op2(reentrant, stack_trace)]
#[serde]
pub fn op_ffi_call_ptr<FP>(
pub fn op_ffi_call_ptr(
scope: &mut v8::PinScope<'_, '_>,
state: Rc<RefCell<OpState>>,
pointer: *mut c_void,
#[serde] def: ForeignFunction,
parameters: v8::Local<v8::Array>,
out_buffer: Option<v8::Local<v8::TypedArray>>,
) -> Result<FfiValue, CallError>
where
FP: FfiPermissions + 'static,
{
) -> Result<FfiValue, CallError> {
{
let mut state = state.borrow_mut();
let permissions = state.borrow_mut::<FP>();
permissions.check_partial_no_path()?;
let permissions = state.borrow_mut::<PermissionsContainer>();
permissions.check_ffi_partial_no_path()?;
};

let symbol = PtrSymbol::new(pointer, &def)?;
Expand Down
13 changes: 5 additions & 8 deletions ext/ffi/callback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -575,17 +575,14 @@ pub struct RegisterCallbackArgs {
}

#[op2(stack_trace)]
pub fn op_ffi_unsafe_callback_create<FP, 'scope>(
pub fn op_ffi_unsafe_callback_create<'scope>(
state: &mut OpState,
scope: &mut v8::PinScope<'scope, '_>,
#[serde] args: RegisterCallbackArgs,
cb: v8::Local<v8::Function>,
) -> Result<v8::Local<'scope, v8::Value>, CallbackError>
where
FP: FfiPermissions + 'static,
{
let permissions = state.borrow_mut::<FP>();
permissions.check_partial_no_path()?;
) -> Result<v8::Local<'scope, v8::Value>, CallbackError> {
let permissions = state.borrow_mut::<PermissionsContainer>();
permissions.check_ffi_partial_no_path()?;

let thread_id: u32 = LOCAL_THREAD_ID.with(|s| {
let value = *s.borrow();
Expand Down
14 changes: 6 additions & 8 deletions ext/ffi/dlfcn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<RefCell<OpState>>,
#[string] path: &str,
#[serde] symbols: HashMap<String, ForeignSymbol>,
) -> Result<v8::Local<'scope, v8::Value>, DlfcnError>
where
FP: FfiPermissions + 'static,
{
) -> Result<v8::Local<'scope, v8::Value>, DlfcnError> {
let (path, denort_helper) = {
let mut state = state.borrow_mut();
let permissions = state.borrow_mut::<FP>();
let permissions = state.borrow_mut::<PermissionsContainer>();
(
permissions.check_partial_with_path(Cow::Borrowed(Path::new(path)))?,
permissions
.check_ffi_partial_with_path(Cow::Borrowed(Path::new(path)))?,
state.try_borrow::<DenoRtNativeAddonLoaderRc>().cloned(),
)
};
Expand Down
Loading
Loading