diff options
Diffstat (limited to 'ext/ffi/repr.rs')
-rw-r--r-- | ext/ffi/repr.rs | 211 |
1 files changed, 143 insertions, 68 deletions
diff --git a/ext/ffi/repr.rs b/ext/ffi/repr.rs index 315e6d53b..2f04f4feb 100644 --- a/ext/ffi/repr.rs +++ b/ext/ffi/repr.rs @@ -1,9 +1,6 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. use crate::FfiPermissions; -use deno_core::error::range_error; -use deno_core::error::type_error; -use deno_core::error::AnyError; use deno_core::op2; use deno_core::v8; use deno_core::OpState; @@ -12,16 +9,58 @@ use std::ffi::c_void; use std::ffi::CStr; use std::ptr; +#[derive(Debug, thiserror::Error)] +pub enum ReprError { + #[error("Invalid pointer to offset, pointer is null")] + InvalidOffset, + #[error("Invalid ArrayBuffer pointer, pointer is null")] + InvalidArrayBuffer, + #[error("Destination length is smaller than source length")] + DestinationLengthTooShort, + #[error("Invalid CString pointer, pointer is null")] + InvalidCString, + #[error("Invalid CString pointer, string exceeds max length")] + CStringTooLong, + #[error("Invalid bool pointer, pointer is null")] + InvalidBool, + #[error("Invalid u8 pointer, pointer is null")] + InvalidU8, + #[error("Invalid i8 pointer, pointer is null")] + InvalidI8, + #[error("Invalid u16 pointer, pointer is null")] + InvalidU16, + #[error("Invalid i16 pointer, pointer is null")] + InvalidI16, + #[error("Invalid u32 pointer, pointer is null")] + InvalidU32, + #[error("Invalid i32 pointer, pointer is null")] + InvalidI32, + #[error("Invalid u64 pointer, pointer is null")] + InvalidU64, + #[error("Invalid i64 pointer, pointer is null")] + InvalidI64, + #[error("Invalid f32 pointer, pointer is null")] + InvalidF32, + #[error("Invalid f64 pointer, pointer is null")] + InvalidF64, + #[error("Invalid pointer pointer, pointer is null")] + InvalidPointer, + #[error(transparent)] + Permission(deno_core::error::AnyError), +} + #[op2(fast)] pub fn op_ffi_ptr_create<FP>( state: &mut OpState, #[bigint] ptr_number: usize, -) -> Result<*mut c_void, AnyError> +) -> Result<*mut c_void, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; Ok(ptr_number as *mut c_void) } @@ -31,12 +70,14 @@ pub fn op_ffi_ptr_equals<FP>( state: &mut OpState, a: *const c_void, b: *const c_void, -) -> Result<bool, AnyError> +) -> Result<bool, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; Ok(a == b) } @@ -45,12 +86,14 @@ where pub fn op_ffi_ptr_of<FP>( state: &mut OpState, #[anybuffer] buf: *const u8, -) -> Result<*mut c_void, AnyError> +) -> Result<*mut c_void, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; Ok(buf as *mut c_void) } @@ -59,12 +102,14 @@ where pub fn op_ffi_ptr_of_exact<FP>( state: &mut OpState, buf: v8::Local<v8::ArrayBufferView>, -) -> Result<*mut c_void, AnyError> +) -> Result<*mut c_void, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; let Some(buf) = buf.get_backing_store() else { return Ok(0 as _); @@ -80,15 +125,17 @@ pub fn op_ffi_ptr_offset<FP>( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result<*mut c_void, AnyError> +) -> Result<*mut c_void, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid pointer to offset, pointer is null")); + return Err(ReprError::InvalidOffset); } // TODO(mmastrac): Create a RawPointer that can safely do pointer math. @@ -110,12 +157,14 @@ unsafe extern "C" fn noop_deleter_callback( pub fn op_ffi_ptr_value<FP>( state: &mut OpState, ptr: *mut c_void, -) -> Result<usize, AnyError> +) -> Result<usize, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; Ok(ptr as usize) } @@ -127,15 +176,17 @@ pub fn op_ffi_get_buf<FP, 'scope>( ptr: *mut c_void, #[number] offset: isize, #[number] len: usize, -) -> Result<v8::Local<'scope, v8::ArrayBuffer>, AnyError> +) -> Result<v8::Local<'scope, v8::ArrayBuffer>, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid ArrayBuffer pointer, pointer is null")); + return Err(ReprError::InvalidArrayBuffer); } // SAFETY: Trust the user to have provided a real pointer, offset, and a valid matching size to it. Since this is a foreign pointer, we should not do any deletion. @@ -144,7 +195,7 @@ where ptr.offset(offset), len, noop_deleter_callback, - std::ptr::null_mut(), + ptr::null_mut(), ) } .make_shared(); @@ -159,19 +210,19 @@ pub fn op_ffi_buf_copy_into<FP>( #[number] offset: isize, #[anybuffer] dst: &mut [u8], #[number] len: usize, -) -> Result<(), AnyError> +) -> Result<(), ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if src.is_null() { - Err(type_error("Invalid ArrayBuffer pointer, pointer is null")) + Err(ReprError::InvalidArrayBuffer) } else if dst.len() < len { - Err(range_error( - "Destination length is smaller than source length", - )) + Err(ReprError::DestinationLengthTooShort) } else { let src = src as *const c_void; @@ -190,24 +241,24 @@ pub fn op_ffi_cstr_read<FP, 'scope>( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result<v8::Local<'scope, v8::String>, AnyError> +) -> Result<v8::Local<'scope, v8::String>, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid CString pointer, pointer is null")); + return Err(ReprError::InvalidCString); } let cstr = // SAFETY: Pointer and offset are user provided. unsafe { CStr::from_ptr(ptr.offset(offset) as *const c_char) }.to_bytes(); let value = v8::String::new_from_utf8(scope, cstr, v8::NewStringType::Normal) - .ok_or_else(|| { - type_error("Invalid CString pointer, string exceeds max length") - })?; + .ok_or_else(|| ReprError::CStringTooLong)?; Ok(value) } @@ -216,15 +267,17 @@ pub fn op_ffi_read_bool<FP>( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result<bool, AnyError> +) -> Result<bool, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid bool pointer, pointer is null")); + return Err(ReprError::InvalidBool); } // SAFETY: ptr and offset are user provided. @@ -236,15 +289,17 @@ pub fn op_ffi_read_u8<FP>( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result<u32, AnyError> +) -> Result<u32, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid u8 pointer, pointer is null")); + return Err(ReprError::InvalidU8); } // SAFETY: ptr and offset are user provided. @@ -258,15 +313,17 @@ pub fn op_ffi_read_i8<FP>( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result<i32, AnyError> +) -> Result<i32, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid i8 pointer, pointer is null")); + return Err(ReprError::InvalidI8); } // SAFETY: ptr and offset are user provided. @@ -280,15 +337,17 @@ pub fn op_ffi_read_u16<FP>( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result<u32, AnyError> +) -> Result<u32, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid u16 pointer, pointer is null")); + return Err(ReprError::InvalidU16); } // SAFETY: ptr and offset are user provided. @@ -302,15 +361,17 @@ pub fn op_ffi_read_i16<FP>( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result<i32, AnyError> +) -> Result<i32, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid i16 pointer, pointer is null")); + return Err(ReprError::InvalidI16); } // SAFETY: ptr and offset are user provided. @@ -324,15 +385,17 @@ pub fn op_ffi_read_u32<FP>( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result<u32, AnyError> +) -> Result<u32, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid u32 pointer, pointer is null")); + return Err(ReprError::InvalidU32); } // SAFETY: ptr and offset are user provided. @@ -344,15 +407,17 @@ pub fn op_ffi_read_i32<FP>( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result<i32, AnyError> +) -> Result<i32, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid i32 pointer, pointer is null")); + return Err(ReprError::InvalidI32); } // SAFETY: ptr and offset are user provided. @@ -367,15 +432,17 @@ pub fn op_ffi_read_u64<FP>( // 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<u64, AnyError> +) -> Result<u64, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid u64 pointer, pointer is null")); + return Err(ReprError::InvalidU64); } let value = @@ -393,15 +460,17 @@ pub fn op_ffi_read_i64<FP>( // 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<i64, AnyError> +) -> Result<i64, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid i64 pointer, pointer is null")); + return Err(ReprError::InvalidI64); } let value = @@ -416,15 +485,17 @@ pub fn op_ffi_read_f32<FP>( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result<f32, AnyError> +) -> Result<f32, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid f32 pointer, pointer is null")); + return Err(ReprError::InvalidF32); } // SAFETY: ptr and offset are user provided. @@ -436,15 +507,17 @@ pub fn op_ffi_read_f64<FP>( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result<f64, AnyError> +) -> Result<f64, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid f64 pointer, pointer is null")); + return Err(ReprError::InvalidF64); } // SAFETY: ptr and offset are user provided. @@ -456,15 +529,17 @@ pub fn op_ffi_read_ptr<FP>( state: &mut OpState, ptr: *mut c_void, #[number] offset: isize, -) -> Result<*mut c_void, AnyError> +) -> Result<*mut c_void, ReprError> where FP: FfiPermissions + 'static, { let permissions = state.borrow_mut::<FP>(); - permissions.check_partial_no_path()?; + permissions + .check_partial_no_path() + .map_err(ReprError::Permission)?; if ptr.is_null() { - return Err(type_error("Invalid pointer pointer, pointer is null")); + return Err(ReprError::InvalidPointer); } // SAFETY: ptr and offset are user provided. |