mirror of
https://github.com/medigor/example-native-api-rs.git
synced 2025-06-06 23:26:13 +02:00
remove ub
This commit is contained in:
parent
03e499d28b
commit
3623a66f1c
84
src/ffi.rs
84
src/ffi.rs
@ -1,7 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
ffi::{c_int, c_long, c_ulong, c_void},
|
ffi::{c_int, c_long, c_ulong, c_void},
|
||||||
mem::size_of,
|
ptr::{self, NonNull},
|
||||||
ptr,
|
|
||||||
slice::{from_raw_parts, from_raw_parts_mut},
|
slice::{from_raw_parts, from_raw_parts_mut},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,55 +63,59 @@ impl<'a> ReturnValue<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_str(self, val: &[u16]) {
|
pub fn set_str(self, val: &[u16]) {
|
||||||
let Some(data) = self.mem.alloc_memory::<u16>(val.len()) else {
|
let Some(ptr) = self.mem.alloc_str(val.len()) else {
|
||||||
*self.result = false;
|
*self.result = false;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
data.copy_from_slice(val);
|
unsafe { ptr::copy_nonoverlapping(val.as_ptr(), ptr.as_ptr(), val.len()) };
|
||||||
|
|
||||||
self.variant.vt = VariantType::PWSTR;
|
self.variant.vt = VariantType::PWSTR;
|
||||||
self.variant.value.data_str.ptr = data.as_ptr() as *mut u16;
|
self.variant.value.data_str.ptr = ptr.as_ptr();
|
||||||
self.variant.value.data_str.len = data.len() as u32;
|
self.variant.value.data_str.len = val.len() as u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_blob(self, val: &[u8]) {
|
pub fn set_blob(self, val: &[u8]) {
|
||||||
let Some(data) = self.mem.alloc_memory::<u8>(val.len()) else {
|
let Some(ptr) = self.mem.alloc_blob(val.len()) else {
|
||||||
*self.result = false;
|
*self.result = false;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
data.copy_from_slice(val);
|
unsafe { ptr::copy_nonoverlapping(val.as_ptr(), ptr.as_ptr(), val.len()) };
|
||||||
|
|
||||||
self.variant.vt = VariantType::BLOB;
|
self.variant.vt = VariantType::BLOB;
|
||||||
self.variant.value.data_blob.ptr = data.as_ptr() as *mut u8;
|
self.variant.value.data_blob.ptr = ptr.as_ptr();
|
||||||
self.variant.value.data_blob.len = data.len() as u32;
|
self.variant.value.data_blob.len = val.len() as u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_str(self, len: usize) -> Option<&'a mut [u16]> {
|
pub fn alloc_str(self, len: usize) -> Option<&'a mut [u16]> {
|
||||||
let Some(data) = self.mem.alloc_memory::<u16>(len) else {
|
let Some(ptr) = self.mem.alloc_str(len) else {
|
||||||
*self.result = false;
|
*self.result = false;
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
self.variant.vt = VariantType::PWSTR;
|
unsafe { ptr::write_bytes(ptr.as_ptr(), 0, len) };
|
||||||
self.variant.value.data_str.ptr = data.as_ptr() as *mut u16;
|
|
||||||
self.variant.value.data_str.len = data.len() as u32;
|
|
||||||
|
|
||||||
Some(data)
|
self.variant.vt = VariantType::PWSTR;
|
||||||
|
self.variant.value.data_str.ptr = ptr.as_ptr();
|
||||||
|
self.variant.value.data_str.len = len as u32;
|
||||||
|
|
||||||
|
Some(unsafe { from_raw_parts_mut(ptr.as_ptr(), len) })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_blob(self, len: usize) -> Option<&'a mut [u8]> {
|
pub fn alloc_blob(self, len: usize) -> Option<&'a mut [u8]> {
|
||||||
let Some(data) = self.mem.alloc_memory::<u8>(len) else {
|
let Some(ptr) = self.mem.alloc_blob(len) else {
|
||||||
*self.result = false;
|
*self.result = false;
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
self.variant.vt = VariantType::BLOB;
|
unsafe { ptr::write_bytes(ptr.as_ptr(), 0, len) };
|
||||||
self.variant.value.data_blob.ptr = data.as_ptr() as *mut u8;
|
|
||||||
self.variant.value.data_blob.len = data.len() as u32;
|
|
||||||
|
|
||||||
Some(data)
|
self.variant.vt = VariantType::BLOB;
|
||||||
|
self.variant.value.data_blob.ptr = ptr.as_ptr();
|
||||||
|
self.variant.value.data_blob.len = len as u32;
|
||||||
|
|
||||||
|
Some(unsafe { from_raw_parts_mut(ptr.as_ptr(), len) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,11 +341,11 @@ unsafe extern "system" fn register_extension_as<T: Addin>(
|
|||||||
|
|
||||||
let extension_name = component.addin.register_extension_as();
|
let extension_name = component.addin.register_extension_as();
|
||||||
|
|
||||||
let Some(data) = allocator.alloc_memory::<u16>(extension_name.len()) else {
|
let Some(ptr) = allocator.alloc_str(extension_name.len()) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
data.copy_from_slice(extension_name);
|
ptr::copy_nonoverlapping(extension_name.as_ptr(), ptr.as_ptr(), extension_name.len());
|
||||||
*name = data.as_mut_ptr();
|
*name = ptr.as_ptr();
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -373,12 +376,12 @@ unsafe extern "system" fn get_prop_name<T: Addin>(
|
|||||||
let Some(prop_name) = component.addin.get_prop_name(num as usize, alias as usize) else {
|
let Some(prop_name) = component.addin.get_prop_name(num as usize, alias as usize) else {
|
||||||
return ptr::null();
|
return ptr::null();
|
||||||
};
|
};
|
||||||
let Some(name) = allocator.alloc_memory::<u16>(prop_name.len()) else {
|
let Some(ptr) = allocator.alloc_str(prop_name.len()) else {
|
||||||
return ptr::null();
|
return ptr::null();
|
||||||
};
|
};
|
||||||
|
ptr::copy_nonoverlapping(prop_name.as_ptr(), ptr.as_ptr(), prop_name.len());
|
||||||
|
|
||||||
name.copy_from_slice(prop_name);
|
ptr.as_ptr()
|
||||||
name.as_ptr()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "system" fn get_prop_val<T: Addin>(
|
unsafe extern "system" fn get_prop_val<T: Addin>(
|
||||||
@ -446,12 +449,13 @@ unsafe extern "system" fn get_method_name<T: Addin>(
|
|||||||
let Some(method_name) = component.addin.get_method_name(num as usize, alias as usize) else {
|
let Some(method_name) = component.addin.get_method_name(num as usize, alias as usize) else {
|
||||||
return ptr::null();
|
return ptr::null();
|
||||||
};
|
};
|
||||||
let Some(name) = allocator.alloc_memory::<u16>(method_name.len()) else {
|
let Some(ptr) = allocator.alloc_str(method_name.len()) else {
|
||||||
return ptr::null();
|
return ptr::null();
|
||||||
};
|
};
|
||||||
|
|
||||||
name.copy_from_slice(method_name);
|
ptr::copy_nonoverlapping(method_name.as_ptr(), ptr.as_ptr(), method_name.len());
|
||||||
name.as_ptr()
|
|
||||||
|
ptr.as_ptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "system" fn get_n_params<T: Addin>(this: &mut This<1, T>, num: c_long) -> c_long {
|
unsafe extern "system" fn get_n_params<T: Addin>(this: &mut This<1, T>, num: c_long) -> c_long {
|
||||||
@ -672,16 +676,26 @@ struct MemoryManagerVTable {
|
|||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct MemoryManager {
|
struct MemoryManager {
|
||||||
vptr1: &'static MemoryManagerVTable,
|
vptr: &'static MemoryManagerVTable,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MemoryManager {
|
impl MemoryManager {
|
||||||
pub fn alloc_memory<'a, T>(&self, size: usize) -> Option<&'a mut [T]> {
|
pub fn alloc_blob(&self, size: usize) -> Option<NonNull<u8>> {
|
||||||
let mut data = ptr::null_mut::<c_void>();
|
let mut ptr = ptr::null_mut::<c_void>();
|
||||||
unsafe {
|
unsafe {
|
||||||
if (self.vptr1.alloc_memory)(self, &mut data, (size * size_of::<T>()) as c_ulong) {
|
if (self.vptr.alloc_memory)(self, &mut ptr, size as c_ulong) {
|
||||||
let d = from_raw_parts_mut(data as *mut T, size);
|
NonNull::new(ptr as *mut u8)
|
||||||
Some(d)
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc_str(&self, size: usize) -> Option<NonNull<u16>> {
|
||||||
|
let mut ptr = ptr::null_mut::<c_void>();
|
||||||
|
unsafe {
|
||||||
|
if (self.vptr.alloc_memory)(self, &mut ptr, size as c_ulong * 2) {
|
||||||
|
NonNull::new(ptr as *mut u16)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user