diff options
| author | Mason Reed <mason@vector35.com> | 2025-05-04 19:10:56 -0400 |
|---|---|---|
| committer | Mason Reed <35282038+emesare@users.noreply.github.com> | 2025-05-12 17:45:24 -0400 |
| commit | a826c589dfc10c542deba7ca3343a462e02d6bde (patch) | |
| tree | f116254bef39f787268bbecc5eac19da310db9ce /rust/src | |
| parent | 28b3c4044af06fdc32c9c85bf8381b5058306427 (diff) | |
[Rust] Simplify `BnStrCompatible` trait
Followup to https://github.com/Vector35/binaryninja-api/pull/5897/
This simplifies usage of the trait in user code, should just be able to `to_cstr` to get the cstr repr and then call `as_ptr`.
Co-authored-by: Michael Krasnitski <michael.krasnitski@gmail.com>
Diffstat (limited to 'rust/src')
61 files changed, 1030 insertions, 1219 deletions
diff --git a/rust/src/architecture.rs b/rust/src/architecture.rs index ee8033a2..74a8dfa4 100644 --- a/rust/src/architecture.rs +++ b/rust/src/architecture.rs @@ -27,7 +27,7 @@ use crate::{ platform::Platform, rc::*, relocation::CoreRelocationHandler, - string::BnStrCompatible, + string::AsCStr, string::*, types::{NameAndType, Type}, Endianness, @@ -1404,8 +1404,7 @@ impl CoreArchitecture { } pub fn by_name(name: &str) -> Option<Self> { - let handle = - unsafe { BNGetArchitectureByName(name.into_bytes_with_nul().as_ptr() as *mut _) }; + let handle = unsafe { BNGetArchitectureByName(name.to_cstr().as_ptr() as *mut _) }; match handle.is_null() { false => Some(CoreArchitecture { handle }), true => None, @@ -1953,8 +1952,8 @@ macro_rules! cc_func { /// Contains helper methods for all types implementing 'Architecture' pub trait ArchitectureExt: Architecture { - fn register_by_name<S: BnStrCompatible>(&self, name: S) -> Option<Self::Register> { - let name = name.into_bytes_with_nul(); + fn register_by_name<S: AsCStr>(&self, name: S) -> Option<Self::Register> { + let name = name.to_cstr(); match unsafe { BNGetArchitectureRegisterByName(self.as_ref().handle, name.as_ref().as_ptr() as *mut _) @@ -2033,7 +2032,7 @@ pub trait ArchitectureExt: Architecture { fn register_relocation_handler<S, R, F>(&self, name: S, func: F) where - S: BnStrCompatible, + S: AsCStr, R: 'static + RelocationHandler<Handle = CustomRelocationHandlerHandle<R>> + Send @@ -2056,7 +2055,7 @@ impl<T: Architecture> ArchitectureExt for T {} pub fn register_architecture<S, A, F>(name: S, func: F) -> &'static A where - S: BnStrCompatible, + S: AsCStr, A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync + Sized, F: FnOnce(CustomArchitectureHandle<A>, CoreArchitecture) -> A, { @@ -3130,7 +3129,7 @@ where custom_arch.skip_and_return_value(data, addr, val) } - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let uninit_arch = ArchitectureBuilder { arch: MaybeUninit::zeroed(), diff --git a/rust/src/background_task.rs b/rust/src/background_task.rs index 5d30f27d..c9059aca 100644 --- a/rust/src/background_task.rs +++ b/rust/src/background_task.rs @@ -43,8 +43,8 @@ impl BackgroundTask { Self { handle } } - pub fn new<S: BnStrCompatible>(initial_text: S, can_cancel: bool) -> Ref<Self> { - let text = initial_text.into_bytes_with_nul(); + pub fn new<S: AsCStr>(initial_text: S, can_cancel: bool) -> Ref<Self> { + let text = initial_text.to_cstr(); let handle = unsafe { BNBeginBackgroundTask(text.as_ref().as_ptr() as *mut _, can_cancel) }; // We should always be returned a valid task. assert!(!handle.is_null()); @@ -75,8 +75,8 @@ impl BackgroundTask { unsafe { BnString::into_string(BNGetBackgroundTaskProgressText(self.handle)) } } - pub fn set_progress_text<S: BnStrCompatible>(&self, text: S) { - let progress_text = text.into_bytes_with_nul(); + pub fn set_progress_text<S: AsCStr>(&self, text: S) { + let progress_text = text.to_cstr(); unsafe { BNSetBackgroundTaskProgressText(self.handle, progress_text.as_ref().as_ptr() as *mut _) } diff --git a/rust/src/binary_view.rs b/rust/src/binary_view.rs index d8f35caf..854f58f4 100644 --- a/rust/src/binary_view.rs +++ b/rust/src/binary_view.rs @@ -266,11 +266,11 @@ pub trait BinaryViewExt: BinaryViewBase { unsafe { BNGetEndOffset(self.as_ref().handle) } } - fn add_analysis_option(&self, name: impl BnStrCompatible) { + fn add_analysis_option(&self, name: impl AsCStr) { unsafe { BNAddAnalysisOption( self.as_ref().handle, - name.into_bytes_with_nul().as_ref().as_ptr() as *mut _, + name.to_cstr().as_ref().as_ptr() as *mut _, ) } } @@ -403,8 +403,8 @@ pub trait BinaryViewExt: BinaryViewBase { } } - fn symbol_by_raw_name<S: BnStrCompatible>(&self, raw_name: S) -> Option<Ref<Symbol>> { - let raw_name = raw_name.into_bytes_with_nul(); + fn symbol_by_raw_name<S: AsCStr>(&self, raw_name: S) -> Option<Ref<Symbol>> { + let raw_name = raw_name.to_cstr(); unsafe { let raw_sym_ptr = BNGetSymbolByRawName( @@ -428,8 +428,8 @@ pub trait BinaryViewExt: BinaryViewBase { } } - fn symbols_by_name<S: BnStrCompatible>(&self, name: S) -> Array<Symbol> { - let raw_name = name.into_bytes_with_nul(); + fn symbols_by_name<S: AsCStr>(&self, name: S) -> Array<Symbol> { + let raw_name = name.to_cstr(); unsafe { let mut count = 0; @@ -589,14 +589,14 @@ pub trait BinaryViewExt: BinaryViewBase { } } - fn define_auto_type<T: Into<QualifiedName>, S: BnStrCompatible>( + fn define_auto_type<T: Into<QualifiedName>, S: AsCStr>( &self, name: T, source: S, type_obj: &Type, ) -> QualifiedName { let mut raw_name = QualifiedName::into_raw(name.into()); - let source_str = source.into_bytes_with_nul(); + let source_str = source.to_cstr(); let name_handle = unsafe { let id_str = BNGenerateAutoTypeId(source_str.as_ref().as_ptr() as *const _, &mut raw_name); @@ -606,14 +606,14 @@ pub trait BinaryViewExt: BinaryViewBase { QualifiedName::from_owned_raw(name_handle) } - fn define_auto_type_with_id<T: Into<QualifiedName>, S: BnStrCompatible>( + fn define_auto_type_with_id<T: Into<QualifiedName>, S: AsCStr>( &self, name: T, id: S, type_obj: &Type, ) -> QualifiedName { let mut raw_name = QualifiedName::into_raw(name.into()); - let id_str = id.into_bytes_with_nul(); + let id_str = id.to_cstr(); let result_raw_name = unsafe { BNDefineAnalysisType( self.as_ref().handle, @@ -716,8 +716,8 @@ pub trait BinaryViewExt: BinaryViewBase { } } - fn undefine_auto_type<S: BnStrCompatible>(&self, id: S) { - let id_str = id.into_bytes_with_nul(); + fn undefine_auto_type<S: AsCStr>(&self, id: S) { + let id_str = id.to_cstr(); unsafe { BNUndefineAnalysisType(self.as_ref().handle, id_str.as_ref().as_ptr() as *const _); } @@ -767,9 +767,9 @@ pub trait BinaryViewExt: BinaryViewBase { } } - fn type_by_id<S: BnStrCompatible>(&self, id: S) -> Option<Ref<Type>> { + fn type_by_id<S: AsCStr>(&self, id: S) -> Option<Ref<Type>> { unsafe { - let id_str = id.into_bytes_with_nul(); + let id_str = id.to_cstr(); let type_handle = BNGetAnalysisTypeById(self.as_ref().handle, id_str.as_ref().as_ptr() as *mut _); if type_handle.is_null() { @@ -779,9 +779,9 @@ pub trait BinaryViewExt: BinaryViewBase { } } - fn type_name_by_id<S: BnStrCompatible>(&self, id: S) -> Option<QualifiedName> { + fn type_name_by_id<S: AsCStr>(&self, id: S) -> Option<QualifiedName> { unsafe { - let id_str = id.into_bytes_with_nul(); + let id_str = id.to_cstr(); let name_handle = BNGetAnalysisTypeNameById(self.as_ref().handle, id_str.as_ref().as_ptr() as *mut _); let name = QualifiedName::from_owned_raw(name_handle); @@ -877,25 +877,25 @@ pub trait BinaryViewExt: BinaryViewBase { section.create(self.as_ref()); } - fn remove_auto_section<S: BnStrCompatible>(&self, name: S) { - let raw_name = name.into_bytes_with_nul(); + fn remove_auto_section<S: AsCStr>(&self, name: S) { + let raw_name = name.to_cstr(); let raw_name_ptr = raw_name.as_ref().as_ptr() as *mut _; unsafe { BNRemoveAutoSection(self.as_ref().handle, raw_name_ptr); } } - fn remove_user_section<S: BnStrCompatible>(&self, name: S) { - let raw_name = name.into_bytes_with_nul(); + fn remove_user_section<S: AsCStr>(&self, name: S) { + let raw_name = name.to_cstr(); let raw_name_ptr = raw_name.as_ref().as_ptr() as *mut _; unsafe { BNRemoveUserSection(self.as_ref().handle, raw_name_ptr); } } - fn section_by_name<S: BnStrCompatible>(&self, name: S) -> Option<Ref<Section>> { + fn section_by_name<S: AsCStr>(&self, name: S) -> Option<Ref<Section>> { unsafe { - let raw_name = name.into_bytes_with_nul(); + let raw_name = name.to_cstr(); let name_ptr = raw_name.as_ref().as_ptr() as *mut _; let raw_section_ptr = BNGetSectionByName(self.as_ref().handle, name_ptr); match raw_section_ptr.is_null() { @@ -1109,8 +1109,8 @@ pub trait BinaryViewExt: BinaryViewBase { unsafe { BNApplyDebugInfo(self.as_ref().handle, debug_info.handle) } } - fn show_graph_report<S: BnStrCompatible>(&self, raw_name: S, graph: &FlowGraph) { - let raw_name = raw_name.into_bytes_with_nul(); + fn show_graph_report<S: AsCStr>(&self, raw_name: S, graph: &FlowGraph) { + let raw_name = raw_name.to_cstr(); unsafe { BNShowGraphReport( self.as_ref().handle, @@ -1120,8 +1120,8 @@ pub trait BinaryViewExt: BinaryViewBase { } } - fn load_settings<S: BnStrCompatible>(&self, view_type_name: S) -> Result<Ref<Settings>> { - let view_type_name = view_type_name.into_bytes_with_nul(); + fn load_settings<S: AsCStr>(&self, view_type_name: S) -> Result<Ref<Settings>> { + let view_type_name = view_type_name.to_cstr(); let settings_handle = unsafe { BNBinaryViewGetLoadSettings( self.as_ref().handle, @@ -1136,8 +1136,8 @@ pub trait BinaryViewExt: BinaryViewBase { } } - fn set_load_settings<S: BnStrCompatible>(&self, view_type_name: S, settings: &Settings) { - let view_type_name = view_type_name.into_bytes_with_nul(); + fn set_load_settings<S: AsCStr>(&self, view_type_name: S, settings: &Settings) { + let view_type_name = view_type_name.to_cstr(); unsafe { BNBinaryViewSetLoadSettings( @@ -1153,11 +1153,7 @@ pub trait BinaryViewExt: BinaryViewBase { /// # Arguments /// * `name` - the name for the tag /// * `icon` - the icon (recommended 1 emoji or 2 chars) for the tag - fn create_tag_type<N: BnStrCompatible, I: BnStrCompatible>( - &self, - name: N, - icon: I, - ) -> Ref<TagType> { + fn create_tag_type<N: AsCStr, I: AsCStr>(&self, name: N, icon: I) -> Ref<TagType> { let tag_type = TagType::create(self.as_ref(), name, icon); unsafe { BNAddTagType(self.as_ref().handle, tag_type.handle); @@ -1171,8 +1167,8 @@ pub trait BinaryViewExt: BinaryViewBase { } /// Get a tag type by its name. - fn tag_type_by_name<S: BnStrCompatible>(&self, name: S) -> Option<Ref<TagType>> { - let name = name.into_bytes_with_nul(); + fn tag_type_by_name<S: AsCStr>(&self, name: S) -> Option<Ref<TagType>> { + let name = name.to_cstr(); unsafe { let handle = BNGetTagType(self.as_ref().handle, name.as_ref().as_ptr() as *mut _); if handle.is_null() { @@ -1185,8 +1181,8 @@ pub trait BinaryViewExt: BinaryViewBase { /// Get a tag by its id. /// /// Note this does not tell you anything about where it is used. - fn tag_by_id<S: BnStrCompatible>(&self, id: S) -> Option<Ref<Tag>> { - let id = id.into_bytes_with_nul(); + fn tag_by_id<S: AsCStr>(&self, id: S) -> Option<Ref<Tag>> { + let id = id.to_cstr(); unsafe { let handle = BNGetTag(self.as_ref().handle, id.as_ref().as_ptr() as *mut _); if handle.is_null() { @@ -1199,7 +1195,7 @@ pub trait BinaryViewExt: BinaryViewBase { /// Creates and adds a tag to an address /// /// User tag creations will be added to the undo buffer - fn add_tag<S: BnStrCompatible>(&self, addr: u64, t: &TagType, data: S, user: bool) { + fn add_tag<S: AsCStr>(&self, addr: u64, t: &TagType, data: S, user: bool) { let tag = Tag::new(t, data); unsafe { BNAddTag(self.as_ref().handle, tag.handle, user) } @@ -1236,8 +1232,8 @@ pub trait BinaryViewExt: BinaryViewBase { /// /// NOTE: This is different from setting a comment at the function-level. To set a comment in a /// function use [`Function::set_comment_at`] - fn set_comment_at(&self, addr: u64, comment: impl BnStrCompatible) { - let comment_raw = comment.into_bytes_with_nul(); + fn set_comment_at(&self, addr: u64, comment: impl AsCStr) { + let comment_raw = comment.to_cstr(); unsafe { BNSetGlobalCommentForAddress( self.as_ref().handle, @@ -1295,11 +1291,11 @@ pub trait BinaryViewExt: BinaryViewBase { result } - fn query_metadata<S: BnStrCompatible>(&self, key: S) -> Option<Ref<Metadata>> { + fn query_metadata<S: AsCStr>(&self, key: S) -> Option<Ref<Metadata>> { let value: *mut BNMetadata = unsafe { BNBinaryViewQueryMetadata( self.as_ref().handle, - key.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + key.to_cstr().as_ref().as_ptr() as *const c_char, ) }; if value.is_null() { @@ -1309,7 +1305,7 @@ pub trait BinaryViewExt: BinaryViewBase { } } - fn get_metadata<T, S: BnStrCompatible>(&self, key: S) -> Option<Result<T>> + fn get_metadata<T, S: AsCStr>(&self, key: S) -> Option<Result<T>> where T: for<'a> TryFrom<&'a Metadata>, { @@ -1317,7 +1313,7 @@ pub trait BinaryViewExt: BinaryViewBase { .map(|md| T::try_from(md.as_ref()).map_err(|_| ())) } - fn store_metadata<V, S: BnStrCompatible>(&self, key: S, value: V, is_auto: bool) + fn store_metadata<V, S: AsCStr>(&self, key: S, value: V, is_auto: bool) where V: Into<Ref<Metadata>>, { @@ -1325,18 +1321,18 @@ pub trait BinaryViewExt: BinaryViewBase { unsafe { BNBinaryViewStoreMetadata( self.as_ref().handle, - key.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + key.to_cstr().as_ref().as_ptr() as *const c_char, md.as_ref().handle, is_auto, ) }; } - fn remove_metadata<S: BnStrCompatible>(&self, key: S) { + fn remove_metadata<S: AsCStr>(&self, key: S) { unsafe { BNBinaryViewRemoveMetadata( self.as_ref().handle, - key.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + key.to_cstr().as_ref().as_ptr() as *const c_char, ) }; } @@ -1462,8 +1458,8 @@ pub trait BinaryViewExt: BinaryViewBase { .collect() } - fn component_by_guid<S: BnStrCompatible>(&self, guid: S) -> Option<Ref<Component>> { - let name = guid.into_bytes_with_nul(); + fn component_by_guid<S: AsCStr>(&self, guid: S) -> Option<Ref<Component>> { + let name = guid.to_cstr(); let result = unsafe { BNGetComponentByGuid( self.as_ref().handle, @@ -1478,8 +1474,8 @@ pub trait BinaryViewExt: BinaryViewBase { NonNull::new(result).map(|h| unsafe { Component::ref_from_raw(h) }) } - fn component_by_path<P: BnStrCompatible>(&self, path: P) -> Option<Ref<Component>> { - let path = path.into_bytes_with_nul(); + fn component_by_path<P: AsCStr>(&self, path: P) -> Option<Ref<Component>> { + let path = path.to_cstr(); let result = unsafe { BNGetComponentByPath( self.as_ref().handle, @@ -1493,8 +1489,8 @@ pub trait BinaryViewExt: BinaryViewBase { unsafe { BNRemoveComponent(self.as_ref().handle, component.handle.as_ptr()) } } - fn remove_component_by_guid<P: BnStrCompatible>(&self, guid: P) -> bool { - let path = guid.into_bytes_with_nul(); + fn remove_component_by_guid<P: AsCStr>(&self, guid: P) -> bool { + let path = guid.to_cstr(); unsafe { BNRemoveComponentByGuid( self.as_ref().handle, @@ -1521,8 +1517,8 @@ pub trait BinaryViewExt: BinaryViewBase { unsafe { Array::new(result, count, ()) } } - fn external_library<S: BnStrCompatible>(&self, name: S) -> Option<Ref<ExternalLibrary>> { - let name_ptr = name.into_bytes_with_nul(); + fn external_library<S: AsCStr>(&self, name: S) -> Option<Ref<ExternalLibrary>> { + let name_ptr = name.to_cstr(); let result = unsafe { BNBinaryViewGetExternalLibrary( self.as_ref().handle, @@ -1533,8 +1529,8 @@ pub trait BinaryViewExt: BinaryViewBase { Some(unsafe { ExternalLibrary::ref_from_raw(result_ptr) }) } - fn remove_external_library<S: BnStrCompatible>(&self, name: S) { - let name_ptr = name.into_bytes_with_nul(); + fn remove_external_library<S: AsCStr>(&self, name: S) { + let name_ptr = name.to_cstr(); unsafe { BNBinaryViewRemoveExternalLibrary( self.as_ref().handle, @@ -1543,13 +1539,13 @@ pub trait BinaryViewExt: BinaryViewBase { }; } - fn add_external_library<S: BnStrCompatible>( + fn add_external_library<S: AsCStr>( &self, name: S, backing_file: Option<&ProjectFile>, auto: bool, ) -> Option<Ref<ExternalLibrary>> { - let name_ptr = name.into_bytes_with_nul(); + let name_ptr = name.to_cstr(); let result = unsafe { BNBinaryViewAddExternalLibrary( self.as_ref().handle, @@ -1585,7 +1581,7 @@ pub trait BinaryViewExt: BinaryViewBase { } // TODO: This is awful, rewrite this. - fn add_external_location<S: BnStrCompatible>( + fn add_external_location<S: AsCStr>( &self, symbol: &Symbol, library: &ExternalLibrary, @@ -1593,7 +1589,7 @@ pub trait BinaryViewExt: BinaryViewBase { target_address: Option<u64>, target_is_auto: bool, ) -> Option<Ref<ExternalLocation>> { - let target_symbol_name = target_symbol_name.into_bytes_with_nul(); + let target_symbol_name = target_symbol_name.to_cstr(); let target_address_ptr = target_address .map(|a| a as *mut u64) .unwrap_or(std::ptr::null_mut()); @@ -1643,8 +1639,8 @@ pub trait BinaryViewExt: BinaryViewBase { unsafe { BNAddBinaryViewTypeLibrary(self.as_ref().handle, library.as_raw()) } } - fn type_library_by_name<S: BnStrCompatible>(&self, name: S) -> Option<TypeLibrary> { - let name = name.into_bytes_with_nul(); + fn type_library_by_name<S: AsCStr>(&self, name: S) -> Option<TypeLibrary> { + let name = name.to_cstr(); let result = unsafe { BNGetBinaryViewTypeLibrary( self.as_ref().handle, @@ -1741,8 +1737,8 @@ pub trait BinaryViewExt: BinaryViewBase { /// contain a metadata key called "type_guids" which is a map /// Dict[string_guid, string_type_name] or /// Dict[string_guid, Tuple[string_type_name, type_library_name]] - fn import_type_by_guid<S: BnStrCompatible>(&self, guid: S) -> Option<Ref<Type>> { - let guid = guid.into_bytes_with_nul(); + fn import_type_by_guid<S: AsCStr>(&self, guid: S) -> Option<Ref<Type>> { + let guid = guid.to_cstr(); let result = unsafe { BNBinaryViewImportTypeLibraryTypeByGuid( self.as_ref().handle, @@ -1889,7 +1885,7 @@ impl BinaryView { } pub fn from_path(meta: &mut FileMetadata, file_path: impl AsRef<Path>) -> Result<Ref<Self>> { - let file = file_path.as_ref().into_bytes_with_nul(); + let file = file_path.as_ref().to_cstr(); let handle = unsafe { BNCreateBinaryDataViewFromFilename(meta.handle, file.as_ptr() as *mut _) }; @@ -1931,7 +1927,7 @@ impl BinaryView { /// To avoid the above issue use [`crate::main_thread::execute_on_main_thread_and_wait`] to verify there /// are no queued up main thread actions. pub fn save_to_path(&self, file_path: impl AsRef<Path>) -> bool { - let file = file_path.as_ref().into_bytes_with_nul(); + let file = file_path.as_ref().to_cstr(); unsafe { BNSaveToFilename(self.handle, file.as_ptr() as *mut _) } } diff --git a/rust/src/binary_view/memory_map.rs b/rust/src/binary_view/memory_map.rs index 182cb16a..b1737440 100644 --- a/rust/src/binary_view/memory_map.rs +++ b/rust/src/binary_view/memory_map.rs @@ -3,7 +3,7 @@ use crate::data_buffer::DataBuffer; use crate::file_accessor::FileAccessor; use crate::rc::Ref; use crate::segment::SegmentFlags; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use binaryninjacore_sys::*; use std::ffi::c_char; @@ -43,12 +43,12 @@ impl MemoryMap { pub fn add_binary_memory_region( &mut self, - name: impl BnStrCompatible, + name: impl AsCStr, start: u64, view: &BinaryView, segment_flags: Option<SegmentFlags>, ) -> bool { - let name_raw = name.into_bytes_with_nul(); + let name_raw = name.to_cstr(); unsafe { BNAddBinaryMemoryRegion( self.view.handle, @@ -62,12 +62,12 @@ impl MemoryMap { pub fn add_data_memory_region( &mut self, - name: impl BnStrCompatible, + name: impl AsCStr, start: u64, data: &DataBuffer, segment_flags: Option<SegmentFlags>, ) -> bool { - let name_raw = name.into_bytes_with_nul(); + let name_raw = name.to_cstr(); unsafe { BNAddDataMemoryRegion( self.view.handle, @@ -81,12 +81,12 @@ impl MemoryMap { pub fn add_remote_memory_region( &mut self, - name: impl BnStrCompatible, + name: impl AsCStr, start: u64, accessor: &mut FileAccessor, segment_flags: Option<SegmentFlags>, ) -> bool { - let name_raw = name.into_bytes_with_nul(); + let name_raw = name.to_cstr(); unsafe { BNAddRemoteMemoryRegion( self.view.handle, @@ -98,8 +98,8 @@ impl MemoryMap { } } - pub fn remove_memory_region(&mut self, name: impl BnStrCompatible) -> bool { - let name_raw = name.into_bytes_with_nul(); + pub fn remove_memory_region(&mut self, name: impl AsCStr) -> bool { + let name_raw = name.to_cstr(); unsafe { BNRemoveMemoryRegion( self.view.handle, @@ -115,8 +115,8 @@ impl MemoryMap { } } - pub fn memory_region_flags(&self, name: impl BnStrCompatible) -> SegmentFlags { - let name_raw = name.into_bytes_with_nul(); + pub fn memory_region_flags(&self, name: impl AsCStr) -> SegmentFlags { + let name_raw = name.to_cstr(); let flags_raw = unsafe { BNGetMemoryRegionFlags( self.view.handle, @@ -126,12 +126,8 @@ impl MemoryMap { SegmentFlags::from_raw(flags_raw) } - pub fn set_memory_region_flags( - &mut self, - name: impl BnStrCompatible, - flags: SegmentFlags, - ) -> bool { - let name_raw = name.into_bytes_with_nul(); + pub fn set_memory_region_flags(&mut self, name: impl AsCStr, flags: SegmentFlags) -> bool { + let name_raw = name.to_cstr(); unsafe { BNSetMemoryRegionFlags( self.view.handle, @@ -141,8 +137,8 @@ impl MemoryMap { } } - pub fn is_memory_region_enabled(&self, name: impl BnStrCompatible) -> bool { - let name_raw = name.into_bytes_with_nul(); + pub fn is_memory_region_enabled(&self, name: impl AsCStr) -> bool { + let name_raw = name.to_cstr(); unsafe { BNIsMemoryRegionEnabled( self.view.handle, @@ -151,8 +147,8 @@ impl MemoryMap { } } - pub fn set_memory_region_enabled(&mut self, name: impl BnStrCompatible, enabled: bool) -> bool { - let name_raw = name.into_bytes_with_nul(); + pub fn set_memory_region_enabled(&mut self, name: impl AsCStr, enabled: bool) -> bool { + let name_raw = name.to_cstr(); unsafe { BNSetMemoryRegionEnabled( self.view.handle, @@ -163,8 +159,8 @@ impl MemoryMap { } // TODO: Should we just call this is_memory_region_relocatable? - pub fn is_memory_region_rebaseable(&self, name: impl BnStrCompatible) -> bool { - let name_raw = name.into_bytes_with_nul(); + pub fn is_memory_region_rebaseable(&self, name: impl AsCStr) -> bool { + let name_raw = name.to_cstr(); unsafe { BNIsMemoryRegionRebaseable( self.view.handle, @@ -173,12 +169,8 @@ impl MemoryMap { } } - pub fn set_memory_region_rebaseable( - &mut self, - name: impl BnStrCompatible, - enabled: bool, - ) -> bool { - let name_raw = name.into_bytes_with_nul(); + pub fn set_memory_region_rebaseable(&mut self, name: impl AsCStr, enabled: bool) -> bool { + let name_raw = name.to_cstr(); unsafe { BNSetMemoryRegionRebaseable( self.view.handle, @@ -188,8 +180,8 @@ impl MemoryMap { } } - pub fn memory_region_fill(&self, name: impl BnStrCompatible) -> u8 { - let name_raw = name.into_bytes_with_nul(); + pub fn memory_region_fill(&self, name: impl AsCStr) -> u8 { + let name_raw = name.to_cstr(); unsafe { BNGetMemoryRegionFill( self.view.handle, @@ -198,8 +190,8 @@ impl MemoryMap { } } - pub fn set_memory_region_fill(&mut self, name: impl BnStrCompatible, fill: u8) -> bool { - let name_raw = name.into_bytes_with_nul(); + pub fn set_memory_region_fill(&mut self, name: impl AsCStr, fill: u8) -> bool { + let name_raw = name.to_cstr(); unsafe { BNSetMemoryRegionFill( self.view.handle, diff --git a/rust/src/calling_convention.rs b/rust/src/calling_convention.rs index 6f2e9a1c..f0f0ba4c 100644 --- a/rust/src/calling_convention.rs +++ b/rust/src/calling_convention.rs @@ -58,7 +58,7 @@ pub trait CallingConvention: Sync { pub fn register_calling_convention<A, N, C>(arch: &A, name: N, cc: C) -> Ref<CoreCallingConvention> where A: Architecture, - N: BnStrCompatible, + N: AsCStr, C: 'static + CallingConvention, { struct CustomCallingConventionContext<C> @@ -377,7 +377,7 @@ where ) } - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let raw = Box::into_raw(Box::new(CustomCallingConventionContext { raw_handle: std::ptr::null_mut(), cc, diff --git a/rust/src/collaboration.rs b/rust/src/collaboration.rs index c9067762..1f76dc9a 100644 --- a/rust/src/collaboration.rs +++ b/rust/src/collaboration.rs @@ -30,7 +30,7 @@ pub use user::*; use binaryninjacore_sys::*; use crate::rc::{Array, Ref}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; // TODO: Should we pull metadata and information required to call a function? Or should we add documentation // TODO: on what functions need to have been called prior? I feel like we should make the user have to pull @@ -73,23 +73,23 @@ pub fn known_remotes() -> Array<Remote> { } /// Get Remote by unique `id` -pub fn get_remote_by_id<S: BnStrCompatible>(id: S) -> Option<Ref<Remote>> { - let id = id.into_bytes_with_nul(); +pub fn get_remote_by_id<S: AsCStr>(id: S) -> Option<Ref<Remote>> { + let id = id.to_cstr(); let value = unsafe { BNCollaborationGetRemoteById(id.as_ref().as_ptr() as *const c_char) }; NonNull::new(value).map(|h| unsafe { Remote::ref_from_raw(h) }) } /// Get Remote by `address` -pub fn get_remote_by_address<S: BnStrCompatible>(address: S) -> Option<Ref<Remote>> { - let address = address.into_bytes_with_nul(); +pub fn get_remote_by_address<S: AsCStr>(address: S) -> Option<Ref<Remote>> { + let address = address.to_cstr(); let value = unsafe { BNCollaborationGetRemoteByAddress(address.as_ref().as_ptr() as *const c_char) }; NonNull::new(value).map(|h| unsafe { Remote::ref_from_raw(h) }) } /// Get Remote by `name` -pub fn get_remote_by_name<S: BnStrCompatible>(name: S) -> Option<Ref<Remote>> { - let name = name.into_bytes_with_nul(); +pub fn get_remote_by_name<S: AsCStr>(name: S) -> Option<Ref<Remote>> { + let name = name.to_cstr(); let value = unsafe { BNCollaborationGetRemoteByName(name.as_ref().as_ptr() as *const c_char) }; NonNull::new(value).map(|h| unsafe { Remote::ref_from_raw(h) }) } @@ -106,15 +106,15 @@ pub fn save_remotes() { pub fn store_data_in_keychain<K, I, DK, DV>(key: K, data: I) -> bool where - K: BnStrCompatible, + K: AsCStr, I: IntoIterator<Item = (DK, DV)>, - DK: BnStrCompatible, - DV: BnStrCompatible, + DK: AsCStr, + DV: AsCStr, { - let key = key.into_bytes_with_nul(); + let key = key.to_cstr(); let (data_keys, data_values): (Vec<DK::Result>, Vec<DV::Result>) = data .into_iter() - .map(|(k, v)| (k.into_bytes_with_nul(), v.into_bytes_with_nul())) + .map(|(k, v)| (k.to_cstr(), v.to_cstr())) .unzip(); let data_keys_ptr: Box<[*const c_char]> = data_keys .iter() @@ -134,15 +134,13 @@ where } } -pub fn has_data_in_keychain<K: BnStrCompatible>(key: K) -> bool { - let key = key.into_bytes_with_nul(); +pub fn has_data_in_keychain<K: AsCStr>(key: K) -> bool { + let key = key.to_cstr(); unsafe { BNCollaborationHasDataInKeychain(key.as_ref().as_ptr() as *const c_char) } } -pub fn get_data_from_keychain<K: BnStrCompatible>( - key: K, -) -> Option<(Array<BnString>, Array<BnString>)> { - let key = key.into_bytes_with_nul(); +pub fn get_data_from_keychain<K: AsCStr>(key: K) -> Option<(Array<BnString>, Array<BnString>)> { + let key = key.to_cstr(); let mut keys = std::ptr::null_mut(); let mut values = std::ptr::null_mut(); let count = unsafe { @@ -157,7 +155,7 @@ pub fn get_data_from_keychain<K: BnStrCompatible>( keys.zip(values) } -pub fn delete_data_from_keychain<K: BnStrCompatible>(key: K) -> bool { - let key = key.into_bytes_with_nul(); +pub fn delete_data_from_keychain<K: AsCStr>(key: K) -> bool { + let key = key.to_cstr(); unsafe { BNCollaborationDeleteDataFromKeychain(key.as_ref().as_ptr() as *const c_char) } } diff --git a/rust/src/collaboration/changeset.rs b/rust/src/collaboration/changeset.rs index fd862df6..1cc30d76 100644 --- a/rust/src/collaboration/changeset.rs +++ b/rust/src/collaboration/changeset.rs @@ -7,7 +7,7 @@ use super::{RemoteFile, RemoteUser}; use crate::database::snapshot::SnapshotId; use crate::database::Database; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; /// A collection of snapshots in a local database #[repr(transparent)] @@ -66,8 +66,8 @@ impl Changeset { } /// Set the name of the changeset, e.g. in a name changeset function. - pub fn set_name<S: BnStrCompatible>(&self, value: S) -> bool { - let value = value.into_bytes_with_nul(); + pub fn set_name<S: AsCStr>(&self, value: S) -> bool { + let value = value.to_cstr(); unsafe { BNCollaborationChangesetSetName( self.handle.as_ptr(), diff --git a/rust/src/collaboration/file.rs b/rust/src/collaboration/file.rs index 678c0c15..2089fbb7 100644 --- a/rust/src/collaboration/file.rs +++ b/rust/src/collaboration/file.rs @@ -16,7 +16,7 @@ use crate::file_metadata::FileMetadata; use crate::progress::{NoProgressCallback, ProgressCallback, SplitProgressBuilder}; use crate::project::file::ProjectFile; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; pub type RemoteFileType = BNRemoteFileType; @@ -94,8 +94,8 @@ impl RemoteFile { success.then_some(()).ok_or(()) } - pub fn set_metadata<S: BnStrCompatible>(&self, folder: S) -> Result<(), ()> { - let folder_raw = folder.into_bytes_with_nul(); + pub fn set_metadata<S: AsCStr>(&self, folder: S) -> Result<(), ()> { + let folder_raw = folder.to_cstr(); let success = unsafe { BNRemoteFileSetMetadata( self.handle.as_ptr(), @@ -190,8 +190,8 @@ impl RemoteFile { } /// Set the description of the file. You will need to push the file to update the remote version. - pub fn set_name<S: BnStrCompatible>(&self, name: S) -> Result<(), ()> { - let name = name.into_bytes_with_nul(); + pub fn set_name<S: AsCStr>(&self, name: S) -> Result<(), ()> { + let name = name.to_cstr(); let success = unsafe { BNRemoteFileSetName( self.handle.as_ptr(), @@ -209,8 +209,8 @@ impl RemoteFile { } /// Set the description of the file. You will need to push the file to update the remote version. - pub fn set_description<S: BnStrCompatible>(&self, description: S) -> Result<(), ()> { - let description = description.into_bytes_with_nul(); + pub fn set_description<S: AsCStr>(&self, description: S) -> Result<(), ()> { + let description = description.to_cstr(); let success = unsafe { BNRemoteFileSetDescription( self.handle.as_ptr(), @@ -263,15 +263,12 @@ impl RemoteFile { /// Get a specific Snapshot in the File by its id /// /// NOTE: If snapshots have not been pulled, they will be pulled upon calling this. - pub fn snapshot_by_id<S: BnStrCompatible>( - &self, - id: S, - ) -> Result<Option<Ref<RemoteSnapshot>>, ()> { + pub fn snapshot_by_id<S: AsCStr>(&self, id: S) -> Result<Option<Ref<RemoteSnapshot>>, ()> { // TODO: This sync should be removed? if !self.has_pulled_snapshots() { self.pull_snapshots()?; } - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let result = unsafe { BNRemoteFileGetSnapshotById(self.handle.as_ptr(), id.as_ref().as_ptr() as *const c_char) }; @@ -314,9 +311,9 @@ impl RemoteFile { parent_ids: I, ) -> Result<Ref<RemoteSnapshot>, ()> where - S: BnStrCompatible, + S: AsCStr, I: IntoIterator, - I::Item: BnStrCompatible, + I::Item: AsCStr, { self.create_snapshot_with_progress( name, @@ -346,16 +343,13 @@ impl RemoteFile { mut progress: P, ) -> Result<Ref<RemoteSnapshot>, ()> where - S: BnStrCompatible, + S: AsCStr, P: ProgressCallback, I: IntoIterator, - I::Item: BnStrCompatible, + I::Item: AsCStr, { - let name = name.into_bytes_with_nul(); - let parent_ids: Vec<_> = parent_ids - .into_iter() - .map(|id| id.into_bytes_with_nul()) - .collect(); + let name = name.to_cstr(); + let parent_ids: Vec<_> = parent_ids.into_iter().map(|id| id.to_cstr()).collect(); let mut parent_ids_raw: Vec<_> = parent_ids .iter() .map(|x| x.as_ref().as_ptr() as *const c_char) @@ -430,7 +424,7 @@ impl RemoteFile { /// * `progress_function` - Function to call for progress updates pub fn download<S>(&self, db_path: S) -> Result<Ref<FileMetadata>, ()> where - S: BnStrCompatible, + S: AsCStr, { sync::download_file(self, db_path) } @@ -447,14 +441,14 @@ impl RemoteFile { progress_function: F, ) -> Result<Ref<FileMetadata>, ()> where - S: BnStrCompatible, + S: AsCStr, F: ProgressCallback, { sync::download_file_with_progress(self, db_path, progress_function) } /// Download a remote file and save it to a BNDB at the given `path`, returning the associated [`FileMetadata`]. - pub fn download_database<S: BnStrCompatible>(&self, path: S) -> Result<Ref<FileMetadata>, ()> { + pub fn download_database<S: AsCStr>(&self, path: S) -> Result<Ref<FileMetadata>, ()> { let file = self.download(path)?; let database = file.database().ok_or(())?; self.sync(&database, DatabaseConflictHandlerFail, NoNameChangeset)?; @@ -464,7 +458,7 @@ impl RemoteFile { // TODO: This might be a bad helper... maybe remove... // TODO: AsRef<Path> /// Download a remote file and save it to a BNDB at the given `path`. - pub fn download_database_with_progress<S: BnStrCompatible>( + pub fn download_database_with_progress<S: AsCStr>( &self, path: S, progress: impl ProgressCallback, diff --git a/rust/src/collaboration/folder.rs b/rust/src/collaboration/folder.rs index eb4fd9f8..0fd2bf87 100644 --- a/rust/src/collaboration/folder.rs +++ b/rust/src/collaboration/folder.rs @@ -5,7 +5,7 @@ use std::ptr::NonNull; use crate::project::folder::ProjectFolder; use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; #[repr(transparent)] pub struct RemoteFolder { @@ -104,8 +104,8 @@ impl RemoteFolder { } /// Set the display name of the folder. You will need to push the folder to update the remote version. - pub fn set_name<S: BnStrCompatible>(&self, name: S) -> Result<(), ()> { - let name = name.into_bytes_with_nul(); + pub fn set_name<S: AsCStr>(&self, name: S) -> Result<(), ()> { + let name = name.to_cstr(); let success = unsafe { BNRemoteFolderSetName( self.handle.as_ptr(), @@ -123,8 +123,8 @@ impl RemoteFolder { } /// Set the description of the folder. You will need to push the folder to update the remote version. - pub fn set_description<S: BnStrCompatible>(&self, description: S) -> Result<(), ()> { - let description = description.into_bytes_with_nul(); + pub fn set_description<S: AsCStr>(&self, description: S) -> Result<(), ()> { + let description = description.to_cstr(); let success = unsafe { BNRemoteFolderSetDescription( self.handle.as_ptr(), diff --git a/rust/src/collaboration/group.rs b/rust/src/collaboration/group.rs index 9fb287a7..94253519 100644 --- a/rust/src/collaboration/group.rs +++ b/rust/src/collaboration/group.rs @@ -1,6 +1,6 @@ use super::Remote; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use binaryninjacore_sys::*; use std::ffi::c_char; use std::fmt; @@ -50,8 +50,8 @@ impl RemoteGroup { /// Set group name /// You will need to push the group to update the Remote. - pub fn set_name<U: BnStrCompatible>(&self, name: U) { - let name = name.into_bytes_with_nul(); + pub fn set_name<U: AsCStr>(&self, name: U) { + let name = name.to_cstr(); unsafe { BNCollaborationGroupSetName( self.handle.as_ptr(), @@ -90,12 +90,9 @@ impl RemoteGroup { pub fn set_users<I>(&self, usernames: I) -> Result<(), ()> where I: IntoIterator, - I::Item: BnStrCompatible, + I::Item: AsCStr, { - let usernames: Vec<_> = usernames - .into_iter() - .map(|u| u.into_bytes_with_nul()) - .collect(); + let usernames: Vec<_> = usernames.into_iter().map(|u| u.to_cstr()).collect(); let mut usernames_raw: Vec<_> = usernames .iter() .map(|s| s.as_ref().as_ptr() as *const c_char) @@ -114,8 +111,8 @@ impl RemoteGroup { } /// Test if a group has a user with the given username - pub fn contains_user<U: BnStrCompatible>(&self, username: U) -> bool { - let username = username.into_bytes_with_nul(); + pub fn contains_user<U: AsCStr>(&self, username: U) -> bool { + let username = username.to_cstr(); unsafe { BNCollaborationGroupContainsUser( self.handle.as_ptr(), diff --git a/rust/src/collaboration/merge.rs b/rust/src/collaboration/merge.rs index 68bfdc02..84aa6192 100644 --- a/rust/src/collaboration/merge.rs +++ b/rust/src/collaboration/merge.rs @@ -5,7 +5,7 @@ use std::ptr::NonNull; use crate::database::{snapshot::Snapshot, Database}; use crate::file_metadata::FileMetadata; use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; pub type MergeConflictDataType = BNMergeConflictDataType; @@ -49,8 +49,8 @@ impl MergeConflict { NonNull::new(result).map(|handle| unsafe { Snapshot::from_raw(handle) }) } - pub fn path_item_string<S: BnStrCompatible>(&self, path: S) -> Result<BnString, ()> { - let path = path.into_bytes_with_nul(); + pub fn path_item_string<S: AsCStr>(&self, path: S) -> Result<BnString, ()> { + let path = path.to_cstr(); let result = unsafe { BNAnalysisMergeConflictGetPathItemString( self.handle.as_ptr(), @@ -123,8 +123,8 @@ impl MergeConflict { } /// Call this when you've resolved the conflict to save the result - pub fn success<S: BnStrCompatible>(&self, value: S) -> Result<(), ()> { - let value = value.into_bytes_with_nul(); + pub fn success<S: AsCStr>(&self, value: S) -> Result<(), ()> { + let value = value.to_cstr(); let success = unsafe { BNAnalysisMergeConflictSuccess( self.handle.as_ptr(), @@ -135,8 +135,8 @@ impl MergeConflict { } // TODO: Make a safe version of this that checks the path and if it holds a number - pub unsafe fn get_path_item_number<S: BnStrCompatible>(&self, path_key: S) -> Option<u64> { - let path_key = path_key.into_bytes_with_nul(); + pub unsafe fn get_path_item_number<S: AsCStr>(&self, path_key: S) -> Option<u64> { + let path_key = path_key.to_cstr(); let value = unsafe { BNAnalysisMergeConflictGetPathItem( self.handle.as_ptr(), @@ -150,8 +150,8 @@ impl MergeConflict { } } - pub unsafe fn get_path_item_string<S: BnStrCompatible>(&self, path_key: S) -> Option<BnString> { - let path_key = path_key.into_bytes_with_nul(); + pub unsafe fn get_path_item_string<S: AsCStr>(&self, path_key: S) -> Option<BnString> { + let path_key = path_key.to_cstr(); let value = unsafe { BNAnalysisMergeConflictGetPathItemString( self.handle.as_ptr(), diff --git a/rust/src/collaboration/project.rs b/rust/src/collaboration/project.rs index b3c6513d..8c04080b 100644 --- a/rust/src/collaboration/project.rs +++ b/rust/src/collaboration/project.rs @@ -15,7 +15,7 @@ use crate::file_metadata::FileMetadata; use crate::progress::{NoProgressCallback, ProgressCallback}; use crate::project::Project; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; #[repr(transparent)] pub struct RemoteProject { @@ -136,8 +136,8 @@ impl RemoteProject { } /// Set the description of the file. You will need to push the file to update the remote version. - pub fn set_name<S: BnStrCompatible>(&self, name: S) -> Result<(), ()> { - let name = name.into_bytes_with_nul(); + pub fn set_name<S: AsCStr>(&self, name: S) -> Result<(), ()> { + let name = name.to_cstr(); let success = unsafe { BNRemoteProjectSetName( self.handle.as_ptr(), @@ -155,8 +155,8 @@ impl RemoteProject { } /// Set the description of the file. You will need to push the file to update the remote version. - pub fn set_description<S: BnStrCompatible>(&self, description: S) -> Result<(), ()> { - let description = description.into_bytes_with_nul(); + pub fn set_description<S: AsCStr>(&self, description: S) -> Result<(), ()> { + let description = description.to_cstr(); let success = unsafe { BNRemoteProjectSetDescription( self.handle.as_ptr(), @@ -230,12 +230,12 @@ impl RemoteProject { /// /// NOTE: If the project has not been opened, it will be opened upon calling this. /// NOTE: If files have not been pulled, they will be pulled upon calling this. - pub fn get_file_by_id<S: BnStrCompatible>(&self, id: S) -> Result<Option<Ref<RemoteFile>>, ()> { + pub fn get_file_by_id<S: AsCStr>(&self, id: S) -> Result<Option<Ref<RemoteFile>>, ()> { // TODO: This sync should be removed? if !self.has_pulled_files() { self.pull_files()?; } - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let result = unsafe { BNRemoteProjectGetFileById(self.handle.as_ptr(), id.as_ref().as_ptr() as *const c_char) }; @@ -246,15 +246,12 @@ impl RemoteProject { /// /// NOTE: If the project has not been opened, it will be opened upon calling this. /// NOTE: If files have not been pulled, they will be pulled upon calling this. - pub fn get_file_by_name<S: BnStrCompatible>( - &self, - name: S, - ) -> Result<Option<Ref<RemoteFile>>, ()> { + pub fn get_file_by_name<S: AsCStr>(&self, name: S) -> Result<Option<Ref<RemoteFile>>, ()> { // TODO: This sync should be removed? if !self.has_pulled_files() { self.pull_files()?; } - let id = name.into_bytes_with_nul(); + let id = name.to_cstr(); let result = unsafe { BNRemoteProjectGetFileByName( self.handle.as_ptr(), @@ -311,9 +308,9 @@ impl RemoteProject { file_type: RemoteFileType, ) -> Result<Ref<RemoteFile>, ()> where - F: BnStrCompatible, - N: BnStrCompatible, - D: BnStrCompatible, + F: AsCStr, + N: AsCStr, + D: AsCStr, { self.create_file_with_progress( filename, @@ -348,17 +345,17 @@ impl RemoteProject { mut progress: P, ) -> Result<Ref<RemoteFile>, ()> where - F: BnStrCompatible, - N: BnStrCompatible, - D: BnStrCompatible, + F: AsCStr, + N: AsCStr, + D: AsCStr, P: ProgressCallback, { // TODO: This sync should be removed? self.open()?; - let filename = filename.into_bytes_with_nul(); - let name = name.into_bytes_with_nul(); - let description = description.into_bytes_with_nul(); + let filename = filename.to_cstr(); + let name = name.to_cstr(); + let description = description.to_cstr(); let folder_handle = parent_folder.map_or(std::ptr::null_mut(), |f| f.handle.as_ptr()); let file_ptr = unsafe { BNRemoteProjectCreateFile( @@ -386,15 +383,15 @@ impl RemoteProject { pub fn push_file<I, K, V>(&self, file: &RemoteFile, extra_fields: I) -> Result<(), ()> where I: Iterator<Item = (K, V)>, - K: BnStrCompatible, - V: BnStrCompatible, + K: AsCStr, + V: AsCStr, { // TODO: This sync should be removed? self.open()?; let (keys, values): (Vec<_>, Vec<_>) = extra_fields .into_iter() - .map(|(k, v)| (k.into_bytes_with_nul(), v.into_bytes_with_nul())) + .map(|(k, v)| (k.to_cstr(), v.to_cstr())) .unzip(); let mut keys_raw = keys .iter() @@ -446,15 +443,12 @@ impl RemoteProject { /// /// NOTE: If the project has not been opened, it will be opened upon calling this. /// NOTE: If folders have not been pulled, they will be pulled upon calling this. - pub fn get_folder_by_id<S: BnStrCompatible>( - &self, - id: S, - ) -> Result<Option<Ref<RemoteFolder>>, ()> { + pub fn get_folder_by_id<S: AsCStr>(&self, id: S) -> Result<Option<Ref<RemoteFolder>>, ()> { // TODO: This sync should be removed? if !self.has_pulled_folders() { self.pull_folders()?; } - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let result = unsafe { BNRemoteProjectGetFolderById( self.handle.as_ptr(), @@ -505,8 +499,8 @@ impl RemoteProject { parent_folder: Option<&RemoteFolder>, ) -> Result<Ref<RemoteFolder>, ()> where - N: BnStrCompatible, - D: BnStrCompatible, + N: AsCStr, + D: AsCStr, { self.create_folder_with_progress(name, description, parent_folder, NoProgressCallback) } @@ -527,15 +521,15 @@ impl RemoteProject { mut progress: P, ) -> Result<Ref<RemoteFolder>, ()> where - N: BnStrCompatible, - D: BnStrCompatible, + N: AsCStr, + D: AsCStr, P: ProgressCallback, { // TODO: This sync should be removed? self.open()?; - let name = name.into_bytes_with_nul(); - let description = description.into_bytes_with_nul(); + let name = name.to_cstr(); + let description = description.to_cstr(); let folder_handle = parent_folder.map_or(std::ptr::null_mut(), |f| f.handle.as_ptr()); let file_ptr = unsafe { BNRemoteProjectCreateFolder( @@ -562,15 +556,15 @@ impl RemoteProject { pub fn push_folder<I, K, V>(&self, folder: &RemoteFolder, extra_fields: I) -> Result<(), ()> where I: Iterator<Item = (K, V)>, - K: BnStrCompatible, - V: BnStrCompatible, + K: AsCStr, + V: AsCStr, { // TODO: This sync should be removed? self.open()?; let (keys, values): (Vec<_>, Vec<_>) = extra_fields .into_iter() - .map(|(k, v)| (k.into_bytes_with_nul(), v.into_bytes_with_nul())) + .map(|(k, v)| (k.to_cstr(), v.to_cstr())) .unzip(); let mut keys_raw = keys .iter() @@ -637,10 +631,7 @@ impl RemoteProject { /// Get a specific permission in the Project by its id. /// /// NOTE: If group or user permissions have not been pulled, they will be pulled upon calling this. - pub fn get_permission_by_id<S: BnStrCompatible>( - &self, - id: S, - ) -> Result<Option<Ref<Permission>>, ()> { + pub fn get_permission_by_id<S: AsCStr>(&self, id: S) -> Result<Option<Ref<Permission>>, ()> { // TODO: This sync should be removed? if !self.has_pulled_user_permissions() { self.pull_user_permissions()?; @@ -650,7 +641,7 @@ impl RemoteProject { self.pull_group_permissions()?; } - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let value = unsafe { BNRemoteProjectGetPermissionById(self.handle.as_ptr(), id.as_ref().as_ptr() as *const _) }; @@ -745,7 +736,7 @@ impl RemoteProject { /// /// * `user_id` - User id /// * `level` - Permission level - pub fn create_user_permission<S: BnStrCompatible>( + pub fn create_user_permission<S: AsCStr>( &self, user_id: S, level: CollaborationPermissionLevel, @@ -760,13 +751,13 @@ impl RemoteProject { /// * `user_id` - User id /// * `level` - Permission level /// * `progress` - The progress callback to call - pub fn create_user_permission_with_progress<S: BnStrCompatible, F: ProgressCallback>( + pub fn create_user_permission_with_progress<S: AsCStr, F: ProgressCallback>( &self, user_id: S, level: CollaborationPermissionLevel, mut progress: F, ) -> Result<Ref<Permission>, ()> { - let user_id = user_id.into_bytes_with_nul(); + let user_id = user_id.to_cstr(); let value = unsafe { BNRemoteProjectCreateUserPermission( self.handle.as_ptr(), @@ -795,12 +786,12 @@ impl RemoteProject { ) -> Result<(), ()> where I: Iterator<Item = (K, V)>, - K: BnStrCompatible, - V: BnStrCompatible, + K: AsCStr, + V: AsCStr, { let (keys, values): (Vec<_>, Vec<_>) = extra_fields .into_iter() - .map(|(k, v)| (k.into_bytes_with_nul(), v.into_bytes_with_nul())) + .map(|(k, v)| (k.to_cstr(), v.to_cstr())) .unzip(); let mut keys_raw = keys .iter() @@ -836,8 +827,8 @@ impl RemoteProject { /// # Arguments /// /// * `username` - Username of user to check - pub fn can_user_view<S: BnStrCompatible>(&self, username: S) -> bool { - let username = username.into_bytes_with_nul(); + pub fn can_user_view<S: AsCStr>(&self, username: S) -> bool { + let username = username.to_cstr(); unsafe { BNRemoteProjectCanUserView( self.handle.as_ptr(), @@ -851,8 +842,8 @@ impl RemoteProject { /// # Arguments /// /// * `username` - Username of user to check - pub fn can_user_edit<S: BnStrCompatible>(&self, username: S) -> bool { - let username = username.into_bytes_with_nul(); + pub fn can_user_edit<S: AsCStr>(&self, username: S) -> bool { + let username = username.to_cstr(); unsafe { BNRemoteProjectCanUserEdit( self.handle.as_ptr(), @@ -866,8 +857,8 @@ impl RemoteProject { /// # Arguments /// /// * `username` - Username of user to check - pub fn can_user_admin<S: BnStrCompatible>(&self, username: S) -> bool { - let username = username.into_bytes_with_nul(); + pub fn can_user_admin<S: AsCStr>(&self, username: S) -> bool { + let username = username.to_cstr(); unsafe { BNRemoteProjectCanUserAdmin( self.handle.as_ptr(), diff --git a/rust/src/collaboration/remote.rs b/rust/src/collaboration/remote.rs index 98784ddb..3a1f021c 100644 --- a/rust/src/collaboration/remote.rs +++ b/rust/src/collaboration/remote.rs @@ -10,7 +10,7 @@ use crate::enterprise; use crate::progress::{NoProgressCallback, ProgressCallback}; use crate::project::Project; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; #[repr(transparent)] pub struct Remote { @@ -27,9 +27,9 @@ impl Remote { } /// Create a Remote and add it to the list of known remotes (saved to Settings) - pub fn new<N: BnStrCompatible, A: BnStrCompatible>(name: N, address: A) -> Ref<Self> { - let name = name.into_bytes_with_nul(); - let address = address.into_bytes_with_nul(); + pub fn new<N: AsCStr, A: AsCStr>(name: N, address: A) -> Ref<Self> { + let name = name.to_cstr(); + let address = address.to_cstr(); let result = unsafe { BNCollaborationCreateRemote( name.as_ref().as_ptr() as *const c_char, @@ -168,13 +168,13 @@ impl Remote { } /// Requests an authentication token using a username and password. - pub fn request_authentication_token<U: BnStrCompatible, P: BnStrCompatible>( + pub fn request_authentication_token<U: AsCStr, P: AsCStr>( &self, username: U, password: P, ) -> Option<BnString> { - let username = username.into_bytes_with_nul(); - let password = password.into_bytes_with_nul(); + let username = username.to_cstr(); + let password = password.to_cstr(); let token = unsafe { BNRemoteRequestAuthenticationToken( self.handle.as_ptr(), @@ -229,9 +229,9 @@ impl Remote { token.unwrap().to_string() } }; - let username = options.username.into_bytes_with_nul(); + let username = options.username.to_cstr(); let username_ptr = username.as_ptr() as *const c_char; - let token = token.into_bytes_with_nul(); + let token = token.to_cstr(); let token_ptr = token.as_ptr() as *const c_char; let success = unsafe { BNRemoteConnect(self.handle.as_ptr(), username_ptr, token_ptr) }; success.then_some(()).ok_or(()) @@ -281,15 +281,12 @@ impl Remote { /// Gets a specific project in the Remote by its id. /// /// NOTE: If projects have not been pulled, they will be pulled upon calling this. - pub fn get_project_by_id<S: BnStrCompatible>( - &self, - id: S, - ) -> Result<Option<Ref<RemoteProject>>, ()> { + pub fn get_project_by_id<S: AsCStr>(&self, id: S) -> Result<Option<Ref<RemoteProject>>, ()> { if !self.has_pulled_projects() { self.pull_projects()?; } - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let value = unsafe { BNRemoteGetProjectById(self.handle.as_ptr(), id.as_ref().as_ptr() as *const c_char) }; @@ -299,7 +296,7 @@ impl Remote { /// Gets a specific project in the Remote by its name. /// /// NOTE: If projects have not been pulled, they will be pulled upon calling this. - pub fn get_project_by_name<S: BnStrCompatible>( + pub fn get_project_by_name<S: AsCStr>( &self, name: S, ) -> Result<Option<Ref<RemoteProject>>, ()> { @@ -307,7 +304,7 @@ impl Remote { self.pull_projects()?; } - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let value = unsafe { BNRemoteGetProjectByName( self.handle.as_ptr(), @@ -347,7 +344,7 @@ impl Remote { /// /// * `name` - Project name /// * `description` - Project description - pub fn create_project<N: BnStrCompatible, D: BnStrCompatible>( + pub fn create_project<N: AsCStr, D: AsCStr>( &self, name: N, description: D, @@ -358,8 +355,8 @@ impl Remote { if !self.has_pulled_projects() { self.pull_projects()?; } - let name = name.into_bytes_with_nul(); - let description = description.into_bytes_with_nul(); + let name = name.to_cstr(); + let description = description.to_cstr(); let value = unsafe { BNRemoteCreateProject( self.handle.as_ptr(), @@ -403,12 +400,12 @@ impl Remote { pub fn push_project<I, K, V>(&self, project: &RemoteProject, extra_fields: I) -> Result<(), ()> where I: Iterator<Item = (K, V)>, - K: BnStrCompatible, - V: BnStrCompatible, + K: AsCStr, + V: AsCStr, { let (keys, values): (Vec<_>, Vec<_>) = extra_fields .into_iter() - .map(|(k, v)| (k.into_bytes_with_nul(), v.into_bytes_with_nul())) + .map(|(k, v)| (k.to_cstr(), v.to_cstr())) .unzip(); let mut keys_raw = keys .iter() @@ -472,15 +469,12 @@ impl Remote { /// /// If groups have not been pulled, they will be pulled upon calling this. /// This function is only available to accounts with admin status on the Remote. - pub fn get_group_by_name<S: BnStrCompatible>( - &self, - name: S, - ) -> Result<Option<Ref<RemoteGroup>>, ()> { + pub fn get_group_by_name<S: AsCStr>(&self, name: S) -> Result<Option<Ref<RemoteGroup>>, ()> { if !self.has_pulled_groups() { self.pull_groups()?; } - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let value = unsafe { BNRemoteGetGroupByName( self.handle.as_ptr(), @@ -496,11 +490,11 @@ impl Remote { /// # Arguments /// /// * `prefix` - Prefix of name for groups - pub fn search_groups<S: BnStrCompatible>( + pub fn search_groups<S: AsCStr>( &self, prefix: S, ) -> Result<(Array<GroupId>, Array<BnString>), ()> { - let prefix = prefix.into_bytes_with_nul(); + let prefix = prefix.to_cstr(); let mut count = 0; let mut group_ids = std::ptr::null_mut(); let mut group_names = std::ptr::null_mut(); @@ -560,15 +554,12 @@ impl Remote { /// * `usernames` - List of usernames of users in the group pub fn create_group<N, I>(&self, name: N, usernames: I) -> Result<Ref<RemoteGroup>, ()> where - N: BnStrCompatible, + N: AsCStr, I: IntoIterator, - I::Item: BnStrCompatible, + I::Item: AsCStr, { - let name = name.into_bytes_with_nul(); - let usernames: Vec<_> = usernames - .into_iter() - .map(|s| s.into_bytes_with_nul()) - .collect(); + let name = name.to_cstr(); + let usernames: Vec<_> = usernames.into_iter().map(|s| s.to_cstr()).collect(); let mut username_ptrs: Vec<_> = usernames .iter() .map(|s| s.as_ref().as_ptr() as *const c_char) @@ -597,12 +588,12 @@ impl Remote { pub fn push_group<I, K, V>(&self, group: &RemoteGroup, extra_fields: I) -> Result<(), ()> where I: IntoIterator<Item = (K, V)>, - K: BnStrCompatible, - V: BnStrCompatible, + K: AsCStr, + V: AsCStr, { let (keys, values): (Vec<_>, Vec<_>) = extra_fields .into_iter() - .map(|(k, v)| (k.into_bytes_with_nul(), v.into_bytes_with_nul())) + .map(|(k, v)| (k.to_cstr(), v.to_cstr())) .unzip(); let mut keys_raw: Vec<_> = keys .iter() @@ -663,11 +654,11 @@ impl Remote { /// # Arguments /// /// * `id` - The identifier of the user to retrieve. - pub fn get_user_by_id<S: BnStrCompatible>(&self, id: S) -> Result<Option<Ref<RemoteUser>>, ()> { + pub fn get_user_by_id<S: AsCStr>(&self, id: S) -> Result<Option<Ref<RemoteUser>>, ()> { if !self.has_pulled_users() { self.pull_users()?; } - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let value = unsafe { BNRemoteGetUserById(self.handle.as_ptr(), id.as_ref().as_ptr() as *const c_char) }; @@ -683,14 +674,14 @@ impl Remote { /// # Arguments /// /// * `username` - The username of the user to retrieve. - pub fn get_user_by_username<S: BnStrCompatible>( + pub fn get_user_by_username<S: AsCStr>( &self, username: S, ) -> Result<Option<Ref<RemoteUser>>, ()> { if !self.has_pulled_users() { self.pull_users()?; } - let username = username.into_bytes_with_nul(); + let username = username.to_cstr(); let value = unsafe { BNRemoteGetUserByUsername( self.handle.as_ptr(), @@ -718,11 +709,11 @@ impl Remote { /// # Arguments /// /// * `prefix` - The prefix to search for in usernames. - pub fn search_users<S: BnStrCompatible>( + pub fn search_users<S: AsCStr>( &self, prefix: S, ) -> Result<(Array<BnString>, Array<BnString>), ()> { - let prefix = prefix.into_bytes_with_nul(); + let prefix = prefix.to_cstr(); let mut count = 0; let mut user_ids = std::ptr::null_mut(); let mut usernames = std::ptr::null_mut(); @@ -783,7 +774,7 @@ impl Remote { /// # Arguments /// /// * Various details about the new user to be created. - pub fn create_user<U: BnStrCompatible, E: BnStrCompatible, P: BnStrCompatible>( + pub fn create_user<U: AsCStr, E: AsCStr, P: AsCStr>( &self, username: U, email: E, @@ -792,9 +783,9 @@ impl Remote { group_ids: &[u64], user_permission_ids: &[u64], ) -> Result<Ref<RemoteUser>, ()> { - let username = username.into_bytes_with_nul(); - let email = email.into_bytes_with_nul(); - let password = password.into_bytes_with_nul(); + let username = username.to_cstr(); + let email = email.to_cstr(); + let password = password.to_cstr(); let value = unsafe { BNRemoteCreateUser( @@ -825,12 +816,12 @@ impl Remote { pub fn push_user<I, K, V>(&self, user: &RemoteUser, extra_fields: I) -> Result<(), ()> where I: Iterator<Item = (K, V)>, - K: BnStrCompatible, - V: BnStrCompatible, + K: AsCStr, + V: AsCStr, { let (keys, values): (Vec<_>, Vec<_>) = extra_fields .into_iter() - .map(|(k, v)| (k.into_bytes_with_nul(), v.into_bytes_with_nul())) + .map(|(k, v)| (k.to_cstr(), v.to_cstr())) .unzip(); let mut keys_raw: Vec<_> = keys .iter() diff --git a/rust/src/collaboration/snapshot.rs b/rust/src/collaboration/snapshot.rs index 935b1c2f..465ae46a 100644 --- a/rust/src/collaboration/snapshot.rs +++ b/rust/src/collaboration/snapshot.rs @@ -8,7 +8,7 @@ use crate::collaboration::undo::{RemoteUndoEntry, RemoteUndoEntryId}; use crate::database::snapshot::Snapshot; use crate::progress::{NoProgressCallback, ProgressCallback}; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use binaryninjacore_sys::*; // TODO: RemoteSnapshotId ? @@ -226,12 +226,12 @@ impl RemoteSnapshot { } /// Create a new Undo Entry in this snapshot. - pub fn create_undo_entry<S: BnStrCompatible>( + pub fn create_undo_entry<S: AsCStr>( &self, parent: Option<u64>, data: S, ) -> Result<Ref<RemoteUndoEntry>, ()> { - let data = data.into_bytes_with_nul(); + let data = data.to_cstr(); let value = unsafe { BNCollaborationSnapshotCreateUndoEntry( self.handle.as_ptr(), diff --git a/rust/src/collaboration/sync.rs b/rust/src/collaboration/sync.rs index 6fc85d31..4c112336 100644 --- a/rust/src/collaboration/sync.rs +++ b/rust/src/collaboration/sync.rs @@ -11,7 +11,7 @@ use crate::file_metadata::FileMetadata; use crate::progress::{NoProgressCallback, ProgressCallback}; use crate::project::file::ProjectFile; use crate::rc::Ref; -use crate::string::{raw_to_string, BnStrCompatible, BnString}; +use crate::string::{raw_to_string, AsCStr, BnString}; use crate::type_archive::{TypeArchive, TypeArchiveMergeConflict}; // TODO: PathBuf @@ -43,10 +43,7 @@ pub fn default_file_path(file: &RemoteFile) -> Result<BnString, ()> { /// /// * `file` - Remote File to download and open /// * `db_path` - File path for saved database -pub fn download_file<S: BnStrCompatible>( - file: &RemoteFile, - db_path: S, -) -> Result<Ref<FileMetadata>, ()> { +pub fn download_file<S: AsCStr>(file: &RemoteFile, db_path: S) -> Result<Ref<FileMetadata>, ()> { download_file_with_progress(file, db_path, NoProgressCallback) } @@ -57,12 +54,12 @@ pub fn download_file<S: BnStrCompatible>( /// * `file` - Remote File to download and open /// * `db_path` - File path for saved database /// * `progress` - Function to call for progress updates -pub fn download_file_with_progress<S: BnStrCompatible, F: ProgressCallback>( +pub fn download_file_with_progress<S: AsCStr, F: ProgressCallback>( file: &RemoteFile, db_path: S, mut progress: F, ) -> Result<Ref<FileMetadata>, ()> { - let db_path = db_path.into_bytes_with_nul(); + let db_path = db_path.to_cstr(); let result = unsafe { BNCollaborationDownloadFile( file.handle.as_ptr(), @@ -223,7 +220,7 @@ pub fn get_local_snapshot_for_remote( pub fn download_database<S>(file: &RemoteFile, location: S, force: bool) -> Result<(), ()> where - S: BnStrCompatible, + S: AsCStr, { download_database_with_progress(file, location, force, NoProgressCallback) } @@ -235,10 +232,10 @@ pub fn download_database_with_progress<S, F>( mut progress: F, ) -> Result<(), ()> where - S: BnStrCompatible, + S: AsCStr, F: ProgressCallback, { - let db_path = location.into_bytes_with_nul(); + let db_path = location.to_cstr(); let success = unsafe { BNCollaborationDownloadDatabaseForFile( file.handle.as_ptr(), @@ -478,12 +475,12 @@ pub fn get_snapshot_author( /// * `database` - Parent database /// * `snapshot` - Snapshot to edit /// * `author` - Target author -pub fn set_snapshot_author<S: BnStrCompatible>( +pub fn set_snapshot_author<S: AsCStr>( database: &Database, snapshot: &Snapshot, author: S, ) -> Result<(), ()> { - let author = author.into_bytes_with_nul(); + let author = author.to_cstr(); let success = unsafe { BNCollaborationSetSnapshotAuthor( database.handle.as_ptr(), @@ -653,11 +650,11 @@ pub fn get_remote_file_for_local_type_archive(database: &TypeArchive) -> Option< } /// Get the remote snapshot associated with a local snapshot (if it exists) in a Type Archive -pub fn get_remote_snapshot_from_local_type_archive<S: BnStrCompatible>( +pub fn get_remote_snapshot_from_local_type_archive<S: AsCStr>( type_archive: &TypeArchive, snapshot_id: S, ) -> Option<Ref<RemoteSnapshot>> { - let snapshot_id = snapshot_id.into_bytes_with_nul(); + let snapshot_id = snapshot_id.to_cstr(); let value = unsafe { BNCollaborationGetRemoteSnapshotFromLocalTypeArchive( type_archive.handle.as_ptr(), @@ -682,11 +679,11 @@ pub fn get_local_snapshot_from_remote_type_archive( } /// Test if a snapshot is ignored from the archive -pub fn is_type_archive_snapshot_ignored<S: BnStrCompatible>( +pub fn is_type_archive_snapshot_ignored<S: AsCStr>( type_archive: &TypeArchive, snapshot_id: S, ) -> bool { - let snapshot_id = snapshot_id.into_bytes_with_nul(); + let snapshot_id = snapshot_id.to_cstr(); unsafe { BNCollaborationIsTypeArchiveSnapshotIgnored( type_archive.handle.as_ptr(), @@ -697,7 +694,7 @@ pub fn is_type_archive_snapshot_ignored<S: BnStrCompatible>( /// Download a type archive from its remote, saving all snapshots to an archive in the /// specified `location`. Returns a [`TypeArchive`] for using later. -pub fn download_type_archive<S: BnStrCompatible>( +pub fn download_type_archive<S: AsCStr>( file: &RemoteFile, location: S, ) -> Result<Option<Ref<TypeArchive>>, ()> { @@ -706,13 +703,13 @@ pub fn download_type_archive<S: BnStrCompatible>( /// Download a type archive from its remote, saving all snapshots to an archive in the /// specified `location`. Returns a [`TypeArchive`] for using later. -pub fn download_type_archive_with_progress<S: BnStrCompatible, F: ProgressCallback>( +pub fn download_type_archive_with_progress<S: AsCStr, F: ProgressCallback>( file: &RemoteFile, location: S, mut progress: F, ) -> Result<Option<Ref<TypeArchive>>, ()> { let mut value = std::ptr::null_mut(); - let db_path = location.into_bytes_with_nul(); + let db_path = location.to_cstr(); let success = unsafe { BNCollaborationDownloadTypeArchive( file.handle.as_ptr(), diff --git a/rust/src/collaboration/user.rs b/rust/src/collaboration/user.rs index b08e9da4..43b4e854 100644 --- a/rust/src/collaboration/user.rs +++ b/rust/src/collaboration/user.rs @@ -4,7 +4,7 @@ use std::ffi::c_char; use std::ptr::NonNull; use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; #[repr(transparent)] pub struct RemoteUser { @@ -49,8 +49,8 @@ impl RemoteUser { } /// Set user's username. You will need to push the user to update the Remote - pub fn set_username<U: BnStrCompatible>(&self, username: U) -> Result<(), ()> { - let username = username.into_bytes_with_nul(); + pub fn set_username<U: AsCStr>(&self, username: U) -> Result<(), ()> { + let username = username.to_cstr(); let result = unsafe { BNCollaborationUserSetUsername( self.handle.as_ptr(), @@ -72,8 +72,8 @@ impl RemoteUser { } /// Set user's email. You will need to push the user to update the Remote - pub fn set_email<U: BnStrCompatible>(&self, email: U) -> Result<(), ()> { - let username = email.into_bytes_with_nul(); + pub fn set_email<U: AsCStr>(&self, email: U) -> Result<(), ()> { + let username = email.to_cstr(); let result = unsafe { BNCollaborationUserSetEmail( self.handle.as_ptr(), diff --git a/rust/src/command.rs b/rust/src/command.rs index 48a91164..0297d6cf 100644 --- a/rust/src/command.rs +++ b/rust/src/command.rs @@ -42,7 +42,7 @@ use std::os::raw::c_void; use crate::binary_view::BinaryView; use crate::function::Function; -use crate::string::BnStrCompatible; +use crate::string::AsCStr; /// The trait required for generic commands. See [register_command] for example usage. pub trait Command: 'static + Sync { @@ -95,7 +95,7 @@ where /// ``` pub fn register_command<S, C>(name: S, desc: S, command: C) where - S: BnStrCompatible, + S: AsCStr, C: Command, { extern "C" fn cb_action<C>(ctxt: *mut c_void, view: *mut BNBinaryView) @@ -126,8 +126,8 @@ where }) } - let name = name.into_bytes_with_nul(); - let desc = desc.into_bytes_with_nul(); + let name = name.to_cstr(); + let desc = desc.to_cstr(); let name_ptr = name.as_ref().as_ptr() as *mut _; let desc_ptr = desc.as_ref().as_ptr() as *mut _; @@ -196,7 +196,7 @@ where /// ``` pub fn register_command_for_address<S, C>(name: S, desc: S, command: C) where - S: BnStrCompatible, + S: AsCStr, C: AddressCommand, { extern "C" fn cb_action<C>(ctxt: *mut c_void, view: *mut BNBinaryView, addr: u64) @@ -227,8 +227,8 @@ where }) } - let name = name.into_bytes_with_nul(); - let desc = desc.into_bytes_with_nul(); + let name = name.to_cstr(); + let desc = desc.to_cstr(); let name_ptr = name.as_ref().as_ptr() as *mut _; let desc_ptr = desc.as_ref().as_ptr() as *mut _; @@ -298,7 +298,7 @@ where /// ``` pub fn register_command_for_range<S, C>(name: S, desc: S, command: C) where - S: BnStrCompatible, + S: AsCStr, C: RangeCommand, { extern "C" fn cb_action<C>(ctxt: *mut c_void, view: *mut BNBinaryView, addr: u64, len: u64) @@ -334,8 +334,8 @@ where }) } - let name = name.into_bytes_with_nul(); - let desc = desc.into_bytes_with_nul(); + let name = name.to_cstr(); + let desc = desc.to_cstr(); let name_ptr = name.as_ref().as_ptr() as *mut _; let desc_ptr = desc.as_ref().as_ptr() as *mut _; @@ -405,7 +405,7 @@ where /// ``` pub fn register_command_for_function<S, C>(name: S, desc: S, command: C) where - S: BnStrCompatible, + S: AsCStr, C: FunctionCommand, { extern "C" fn cb_action<C>(ctxt: *mut c_void, view: *mut BNBinaryView, func: *mut BNFunction) @@ -446,8 +446,8 @@ where }) } - let name = name.into_bytes_with_nul(); - let desc = desc.into_bytes_with_nul(); + let name = name.to_cstr(); + let desc = desc.to_cstr(); let name_ptr = name.as_ref().as_ptr() as *mut _; let desc_ptr = desc.as_ref().as_ptr() as *mut _; diff --git a/rust/src/component.rs b/rust/src/component.rs index 72441c52..5fe44b64 100644 --- a/rust/src/component.rs +++ b/rust/src/component.rs @@ -1,7 +1,7 @@ use crate::binary_view::{BinaryView, BinaryViewExt}; use crate::function::Function; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use crate::types::ComponentReferencedType; use std::ffi::c_char; use std::fmt::Debug; @@ -39,20 +39,20 @@ impl ComponentBuilder { let result = match (&self.parent, &self.name) { (None, None) => unsafe { BNCreateComponent(self.view.handle) }, (None, Some(name)) => { - let name_raw = name.into_bytes_with_nul(); + let name_raw = name.to_cstr(); unsafe { BNCreateComponentWithName(self.view.handle, name_raw.as_ptr() as *mut c_char) } } (Some(guid), None) => { - let guid_raw = guid.into_bytes_with_nul(); + let guid_raw = guid.to_cstr(); unsafe { BNCreateComponentWithParent(self.view.handle, guid_raw.as_ptr() as *mut c_char) } } (Some(guid), Some(name)) => { - let guid_raw = guid.into_bytes_with_nul(); - let name_raw = name.into_bytes_with_nul(); + let guid_raw = guid.to_cstr(); + let name_raw = name.to_cstr(); unsafe { BNCreateComponentWithParentAndName( self.view.handle, @@ -164,8 +164,8 @@ impl Component { unsafe { BnString::into_string(result) } } - pub fn set_name<S: BnStrCompatible>(&self, name: S) { - let name = name.into_bytes_with_nul(); + pub fn set_name<S: AsCStr>(&self, name: S) { + let name = name.to_cstr(); unsafe { BNComponentSetName( self.handle.as_ptr(), diff --git a/rust/src/custom_binary_view.rs b/rust/src/custom_binary_view.rs index de841a26..adcde09d 100644 --- a/rust/src/custom_binary_view.rs +++ b/rust/src/custom_binary_view.rs @@ -42,7 +42,7 @@ use crate::Endianness; /// implementation of the `CustomBinaryViewType` must return. pub fn register_view_type<S, T, F>(name: S, long_name: S, constructor: F) -> &'static T where - S: BnStrCompatible, + S: AsCStr, T: CustomBinaryViewType, F: FnOnce(BinaryViewType) -> T, { @@ -149,10 +149,10 @@ where }) } - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let name_ptr = name.as_ref().as_ptr() as *mut _; - let long_name = long_name.into_bytes_with_nul(); + let long_name = long_name.to_cstr(); let long_name_ptr = long_name.as_ref().as_ptr() as *mut _; let ctxt = Box::leak(Box::new(MaybeUninit::zeroed())); @@ -360,8 +360,8 @@ impl BinaryViewType { } /// Looks up a BinaryViewType by its short name - pub fn by_name<N: BnStrCompatible>(name: N) -> Result<Self> { - let bytes = name.into_bytes_with_nul(); + pub fn by_name<N: AsCStr>(name: N) -> Result<Self> { + let bytes = name.to_cstr(); let handle = unsafe { BNGetBinaryViewTypeByName(bytes.as_ref().as_ptr() as *const _) }; match handle.is_null() { false => Ok(unsafe { BinaryViewType::from_raw(handle) }), diff --git a/rust/src/data_buffer.rs b/rust/src/data_buffer.rs index 460bb94d..a163d346 100644 --- a/rust/src/data_buffer.rs +++ b/rust/src/data_buffer.rs @@ -19,7 +19,7 @@ use binaryninjacore_sys::*; use std::ffi::c_void; use std::slice; -use crate::string::BnString; +use crate::string::{AsCStr, BnString}; pub struct DataBuffer(*mut BNDataBuffer); @@ -128,8 +128,9 @@ impl DataBuffer { unsafe { BnString::into_string(BNDataBufferToBase64(self.0)) } } - pub fn from_base64(value: &BnString) -> Self { - Self(unsafe { BNDecodeBase64(value.as_ptr()) }) + pub fn from_base64(value: &str) -> Self { + let t = value.to_cstr(); + Self(unsafe { BNDecodeBase64(t.as_ptr()) }) } pub fn zlib_compress(&self) -> Self { diff --git a/rust/src/database.rs b/rust/src/database.rs index 7174ebe8..fd20d173 100644 --- a/rust/src/database.rs +++ b/rust/src/database.rs @@ -15,7 +15,7 @@ use crate::database::snapshot::{Snapshot, SnapshotId}; use crate::file_metadata::FileMetadata; use crate::progress::{NoProgressCallback, ProgressCallback}; use crate::rc::{Array, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; pub struct Database { pub(crate) handle: NonNull<BNDatabase>, @@ -62,7 +62,7 @@ impl Database { unsafe { BNSetDatabaseCurrentSnapshot(self.handle.as_ptr(), id.0) } } - pub fn write_snapshot_data<N: BnStrCompatible>( + pub fn write_snapshot_data<N: AsCStr>( &self, parents: &[SnapshotId], file: &BinaryView, @@ -90,10 +90,10 @@ impl Database { mut progress: P, ) -> SnapshotId where - N: BnStrCompatible, + N: AsCStr, P: ProgressCallback, { - let name_raw = name.into_bytes_with_nul(); + let name_raw = name.to_cstr(); let name_ptr = name_raw.as_ref().as_ptr() as *const c_char; let new_id = unsafe { @@ -133,8 +133,8 @@ impl Database { Err(()) } } - pub fn has_global<S: BnStrCompatible>(&self, key: S) -> bool { - let key_raw = key.into_bytes_with_nul(); + pub fn has_global<S: AsCStr>(&self, key: S) -> bool { + let key_raw = key.to_cstr(); let key_ptr = key_raw.as_ref().as_ptr() as *const c_char; unsafe { BNDatabaseHasGlobal(self.handle.as_ptr(), key_ptr) != 0 } } @@ -156,33 +156,33 @@ impl Database { } /// Get a specific global by key - pub fn read_global<S: BnStrCompatible>(&self, key: S) -> Option<BnString> { - let key_raw = key.into_bytes_with_nul(); + pub fn read_global<S: AsCStr>(&self, key: S) -> Option<BnString> { + let key_raw = key.to_cstr(); let key_ptr = key_raw.as_ref().as_ptr() as *const c_char; let result = unsafe { BNReadDatabaseGlobal(self.handle.as_ptr(), key_ptr) }; unsafe { NonNull::new(result).map(|_| BnString::from_raw(result)) } } /// Write a global into the database - pub fn write_global<K: BnStrCompatible, V: BnStrCompatible>(&self, key: K, value: V) -> bool { - let key_raw = key.into_bytes_with_nul(); + pub fn write_global<K: AsCStr, V: AsCStr>(&self, key: K, value: V) -> bool { + let key_raw = key.to_cstr(); let key_ptr = key_raw.as_ref().as_ptr() as *const c_char; - let value_raw = value.into_bytes_with_nul(); + let value_raw = value.to_cstr(); let value_ptr = value_raw.as_ref().as_ptr() as *const c_char; unsafe { BNWriteDatabaseGlobal(self.handle.as_ptr(), key_ptr, value_ptr) } } /// Get a specific global by key, as a binary buffer - pub fn read_global_data<S: BnStrCompatible>(&self, key: S) -> Option<DataBuffer> { - let key_raw = key.into_bytes_with_nul(); + pub fn read_global_data<S: AsCStr>(&self, key: S) -> Option<DataBuffer> { + let key_raw = key.to_cstr(); let key_ptr = key_raw.as_ref().as_ptr() as *const c_char; let result = unsafe { BNReadDatabaseGlobalData(self.handle.as_ptr(), key_ptr) }; NonNull::new(result).map(|_| DataBuffer::from_raw(result)) } /// Write a binary buffer into a global in the database - pub fn write_global_data<K: BnStrCompatible>(&self, key: K, value: &DataBuffer) -> bool { - let key_raw = key.into_bytes_with_nul(); + pub fn write_global_data<K: AsCStr>(&self, key: K, value: &DataBuffer) -> bool { + let key_raw = key.to_cstr(); let key_ptr = key_raw.as_ref().as_ptr() as *const c_char; unsafe { BNWriteDatabaseGlobalData(self.handle.as_ptr(), key_ptr, value.as_raw()) } } diff --git a/rust/src/database/kvs.rs b/rust/src/database/kvs.rs index 4b77bbdb..43cf17eb 100644 --- a/rust/src/database/kvs.rs +++ b/rust/src/database/kvs.rs @@ -1,6 +1,6 @@ use crate::data_buffer::DataBuffer; use crate::rc::{Array, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use binaryninjacore_sys::{ BNBeginKeyValueStoreNamespace, BNEndKeyValueStoreNamespace, BNFreeKeyValueStore, BNGetKeyValueStoreBuffer, BNGetKeyValueStoreDataSize, BNGetKeyValueStoreKeys, @@ -42,16 +42,16 @@ impl KeyValueStore { } /// Get the value for a single key - pub fn value<S: BnStrCompatible>(&self, key: S) -> Option<DataBuffer> { - let key_raw = key.into_bytes_with_nul(); + pub fn value<S: AsCStr>(&self, key: S) -> Option<DataBuffer> { + let key_raw = key.to_cstr(); let key_ptr = key_raw.as_ref().as_ptr() as *const c_char; let result = unsafe { BNGetKeyValueStoreBuffer(self.handle.as_ptr(), key_ptr) }; NonNull::new(result).map(|_| DataBuffer::from_raw(result)) } /// Set the value for a single key - pub fn set_value<S: BnStrCompatible>(&self, key: S, value: &DataBuffer) -> bool { - let key_raw = key.into_bytes_with_nul(); + pub fn set_value<S: AsCStr>(&self, key: S, value: &DataBuffer) -> bool { + let key_raw = key.to_cstr(); let key_ptr = key_raw.as_ref().as_ptr() as *const c_char; unsafe { BNSetKeyValueStoreBuffer(self.handle.as_ptr(), key_ptr, value.as_raw()) } } @@ -64,8 +64,8 @@ impl KeyValueStore { } /// Begin storing new keys into a namespace - pub fn begin_namespace<S: BnStrCompatible>(&self, name: S) { - let name_raw = name.into_bytes_with_nul(); + pub fn begin_namespace<S: AsCStr>(&self, name: S) { + let name_raw = name.to_cstr(); let name_ptr = name_raw.as_ref().as_ptr() as *const c_char; unsafe { BNBeginKeyValueStoreNamespace(self.handle.as_ptr(), name_ptr) } } diff --git a/rust/src/database/snapshot.rs b/rust/src/database/snapshot.rs index 3768138c..7d7e39d1 100644 --- a/rust/src/database/snapshot.rs +++ b/rust/src/database/snapshot.rs @@ -4,7 +4,7 @@ use crate::database::undo::UndoEntry; use crate::database::Database; use crate::progress::ProgressCallback; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use binaryninjacore_sys::{ BNCollaborationFreeSnapshotIdList, BNFreeSnapshot, BNFreeSnapshotList, BNGetSnapshotChildren, BNGetSnapshotDatabase, BNGetSnapshotFileContents, BNGetSnapshotFileContentsHash, @@ -50,8 +50,8 @@ impl Snapshot { } /// Set the displayed snapshot name - pub fn set_name<S: BnStrCompatible>(&self, value: S) { - let value_raw = value.into_bytes_with_nul(); + pub fn set_name<S: AsCStr>(&self, value: S) { + let value_raw = value.to_cstr(); let value_ptr = value_raw.as_ref().as_ptr() as *const c_char; unsafe { BNSetSnapshotName(self.handle.as_ptr(), value_ptr) } } diff --git a/rust/src/debuginfo.rs b/rust/src/debuginfo.rs index c4bc7add..0afe4c77 100644 --- a/rust/src/debuginfo.rs +++ b/rust/src/debuginfo.rs @@ -83,7 +83,7 @@ use crate::{ binary_view::BinaryView, platform::Platform, rc::*, - string::{raw_to_string, BnStrCompatible, BnString}, + string::{raw_to_string, AsCStr, BnString}, types::{NameAndType, Type}, }; @@ -115,8 +115,8 @@ impl DebugInfoParser { } /// Returns debug info parser of the given name, if it exists - pub fn from_name<S: BnStrCompatible>(name: S) -> Result<Ref<Self>, ()> { - let name = name.into_bytes_with_nul(); + pub fn from_name<S: AsCStr>(name: S) -> Result<Ref<Self>, ()> { + let name = name.to_cstr(); let parser = unsafe { BNGetDebugInfoParserByName(name.as_ref().as_ptr() as *mut _) }; if parser.is_null() { @@ -209,7 +209,7 @@ impl DebugInfoParser { // Registers a DebugInfoParser. See `binaryninja::debuginfo::DebugInfoParser` for more details. pub fn register<S, C>(name: S, parser_callbacks: C) -> Ref<Self> where - S: BnStrCompatible, + S: AsCStr, C: CustomDebugInfoParser, { extern "C" fn cb_is_valid<C>(ctxt: *mut c_void, view: *mut BNBinaryView) -> bool @@ -259,7 +259,7 @@ impl DebugInfoParser { }) } - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let name_ptr = name.as_ref().as_ptr() as *mut _; let ctxt = Box::into_raw(Box::new(parser_callbacks)); @@ -417,8 +417,8 @@ impl DebugInfo { } /// Returns all types within the parser - pub fn types_by_name<S: BnStrCompatible>(&self, parser_name: S) -> Vec<NameAndType> { - let parser_name = parser_name.into_bytes_with_nul(); + pub fn types_by_name<S: AsCStr>(&self, parser_name: S) -> Vec<NameAndType> { + let parser_name = parser_name.to_cstr(); let mut count: usize = 0; let debug_types_ptr = unsafe { @@ -455,8 +455,8 @@ impl DebugInfo { } /// Returns all functions within the parser - pub fn functions_by_name<S: BnStrCompatible>(&self, parser_name: S) -> Vec<DebugFunctionInfo> { - let parser_name = parser_name.into_bytes_with_nul(); + pub fn functions_by_name<S: AsCStr>(&self, parser_name: S) -> Vec<DebugFunctionInfo> { + let parser_name = parser_name.to_cstr(); let mut count: usize = 0; let functions_ptr = unsafe { @@ -495,11 +495,11 @@ impl DebugInfo { } /// Returns all data variables within the parser - pub fn data_variables_by_name<S: BnStrCompatible>( + pub fn data_variables_by_name<S: AsCStr>( &self, parser_name: S, ) -> Vec<NamedDataVariableWithType> { - let parser_name = parser_name.into_bytes_with_nul(); + let parser_name = parser_name.to_cstr(); let mut count: usize = 0; let data_variables_ptr = unsafe { @@ -537,9 +537,9 @@ impl DebugInfo { result } - pub fn type_by_name<S: BnStrCompatible>(&self, parser_name: S, name: S) -> Option<Ref<Type>> { - let parser_name = parser_name.into_bytes_with_nul(); - let name = name.into_bytes_with_nul(); + pub fn type_by_name<S: AsCStr>(&self, parser_name: S, name: S) -> Option<Ref<Type>> { + let parser_name = parser_name.to_cstr(); + let name = name.to_cstr(); let result = unsafe { BNGetDebugTypeByName( @@ -555,13 +555,13 @@ impl DebugInfo { } } - pub fn get_data_variable_by_name<S: BnStrCompatible>( + pub fn get_data_variable_by_name<S: AsCStr>( &self, parser_name: S, name: S, ) -> Option<NamedDataVariableWithType> { - let parser_name = parser_name.into_bytes_with_nul(); - let name = name.into_bytes_with_nul(); + let parser_name = parser_name.to_cstr(); + let name = name.to_cstr(); let mut dv = BNDataVariableAndName::default(); unsafe { if BNGetDebugDataVariableByName( @@ -577,12 +577,12 @@ impl DebugInfo { } } - pub fn get_data_variable_by_address<S: BnStrCompatible>( + pub fn get_data_variable_by_address<S: AsCStr>( &self, parser_name: S, address: u64, ) -> Option<NamedDataVariableWithType> { - let parser_name = parser_name.into_bytes_with_nul(); + let parser_name = parser_name.to_cstr(); let mut dv = BNDataVariableAndName::default(); unsafe { if BNGetDebugDataVariableByAddress( @@ -599,9 +599,9 @@ impl DebugInfo { } /// Returns a list of [`NameAndType`] where the `name` is the parser the type originates from. - pub fn get_types_by_name<S: BnStrCompatible>(&self, name: S) -> Vec<NameAndType> { + pub fn get_types_by_name<S: AsCStr>(&self, name: S) -> Vec<NameAndType> { let mut count: usize = 0; - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let raw_names_and_types_ptr = unsafe { BNGetDebugTypesByName(self.handle, name.as_ref().as_ptr() as *mut _, &mut count) }; @@ -619,11 +619,8 @@ impl DebugInfo { } // The tuple is (DebugInfoParserName, address, type) - pub fn get_data_variables_by_name<S: BnStrCompatible>( - &self, - name: S, - ) -> Vec<(String, u64, Ref<Type>)> { - let name = name.into_bytes_with_nul(); + pub fn get_data_variables_by_name<S: AsCStr>(&self, name: S) -> Vec<(String, u64, Ref<Type>)> { + let name = name.to_cstr(); let mut count: usize = 0; let raw_variables_and_names = unsafe { @@ -674,37 +671,37 @@ impl DebugInfo { result } - pub fn remove_parser_info<S: BnStrCompatible>(&self, parser_name: S) -> bool { - let parser_name = parser_name.into_bytes_with_nul(); + pub fn remove_parser_info<S: AsCStr>(&self, parser_name: S) -> bool { + let parser_name = parser_name.to_cstr(); unsafe { BNRemoveDebugParserInfo(self.handle, parser_name.as_ref().as_ptr() as *mut _) } } - pub fn remove_parser_types<S: BnStrCompatible>(&self, parser_name: S) -> bool { - let parser_name = parser_name.into_bytes_with_nul(); + pub fn remove_parser_types<S: AsCStr>(&self, parser_name: S) -> bool { + let parser_name = parser_name.to_cstr(); unsafe { BNRemoveDebugParserTypes(self.handle, parser_name.as_ref().as_ptr() as *mut _) } } - pub fn remove_parser_functions<S: BnStrCompatible>(&self, parser_name: S) -> bool { - let parser_name = parser_name.into_bytes_with_nul(); + pub fn remove_parser_functions<S: AsCStr>(&self, parser_name: S) -> bool { + let parser_name = parser_name.to_cstr(); unsafe { BNRemoveDebugParserFunctions(self.handle, parser_name.as_ref().as_ptr() as *mut _) } } - pub fn remove_parser_data_variables<S: BnStrCompatible>(&self, parser_name: S) -> bool { - let parser_name = parser_name.into_bytes_with_nul(); + pub fn remove_parser_data_variables<S: AsCStr>(&self, parser_name: S) -> bool { + let parser_name = parser_name.to_cstr(); unsafe { BNRemoveDebugParserDataVariables(self.handle, parser_name.as_ref().as_ptr() as *mut _) } } - pub fn remove_type_by_name<S: BnStrCompatible>(&self, parser_name: S, name: S) -> bool { - let parser_name = parser_name.into_bytes_with_nul(); - let name = name.into_bytes_with_nul(); + pub fn remove_type_by_name<S: AsCStr>(&self, parser_name: S, name: S) -> bool { + let parser_name = parser_name.to_cstr(); + let name = name.to_cstr(); unsafe { BNRemoveDebugTypeByName( @@ -715,12 +712,8 @@ impl DebugInfo { } } - pub fn remove_function_by_index<S: BnStrCompatible>( - &self, - parser_name: S, - index: usize, - ) -> bool { - let parser_name = parser_name.into_bytes_with_nul(); + pub fn remove_function_by_index<S: AsCStr>(&self, parser_name: S, index: usize) -> bool { + let parser_name = parser_name.to_cstr(); unsafe { BNRemoveDebugFunctionByIndex( @@ -731,12 +724,8 @@ impl DebugInfo { } } - pub fn remove_data_variable_by_address<S: BnStrCompatible>( - &self, - parser_name: S, - address: u64, - ) -> bool { - let parser_name = parser_name.into_bytes_with_nul(); + pub fn remove_data_variable_by_address<S: AsCStr>(&self, parser_name: S, address: u64) -> bool { + let parser_name = parser_name.to_cstr(); unsafe { BNRemoveDebugDataVariableByAddress( @@ -748,16 +737,11 @@ impl DebugInfo { } /// Adds a type scoped under the current parser's name to the debug info - pub fn add_type<S: BnStrCompatible>( - &self, - name: S, - new_type: &Type, - components: &[&str], - ) -> bool { + pub fn add_type<S: AsCStr>(&self, name: S, new_type: &Type, components: &[&str]) -> bool { // SAFETY: Lifetime of `components` will live long enough, so passing as_ptr is safe. let raw_components: Vec<_> = components.iter().map(|&c| c.as_ptr()).collect(); - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); unsafe { BNAddDebugType( self.handle, @@ -771,24 +755,15 @@ impl DebugInfo { /// Adds a function scoped under the current parser's name to the debug info pub fn add_function(&self, new_func: &DebugFunctionInfo) -> bool { - let short_name_bytes = new_func - .short_name - .as_ref() - .map(|name| name.into_bytes_with_nul()); + let short_name_bytes = new_func.short_name.as_ref().map(|name| name.to_cstr()); let short_name = short_name_bytes .as_ref() .map_or(std::ptr::null_mut() as *mut _, |name| name.as_ptr() as _); - let full_name_bytes = new_func - .full_name - .as_ref() - .map(|name| name.into_bytes_with_nul()); + let full_name_bytes = new_func.full_name.as_ref().map(|name| name.to_cstr()); let full_name = full_name_bytes .as_ref() .map_or(std::ptr::null_mut() as *mut _, |name| name.as_ptr() as _); - let raw_name_bytes = new_func - .raw_name - .as_ref() - .map(|name| name.into_bytes_with_nul()); + let raw_name_bytes = new_func.raw_name.as_ref().map(|name| name.to_cstr()); let raw_name = raw_name_bytes .as_ref() .map_or(std::ptr::null_mut() as *mut _, |name| name.as_ptr() as _); @@ -801,9 +776,7 @@ impl DebugInfo { unsafe { for component in &new_func.components { - components_array.push(BNAllocString( - component.clone().into_bytes_with_nul().as_ptr() as _, - )); + components_array.push(BNAllocString(component.clone().to_cstr().as_ptr() as _)); } for local_variable in &new_func.local_variables { @@ -845,7 +818,7 @@ impl DebugInfo { } /// Adds a data variable scoped under the current parser's name to the debug info - pub fn add_data_variable<S: BnStrCompatible>( + pub fn add_data_variable<S: AsCStr>( &self, address: u64, t: &Type, @@ -860,7 +833,7 @@ impl DebugInfo { match name { Some(name) => { - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); unsafe { BNAddDebugDataVariable( self.handle, diff --git a/rust/src/demangle.rs b/rust/src/demangle.rs index bfe65f9a..9cec0c93 100644 --- a/rust/src/demangle.rs +++ b/rust/src/demangle.rs @@ -19,20 +19,20 @@ use std::ffi::{c_char, c_void}; use crate::architecture::CoreArchitecture; use crate::binary_view::BinaryView; -use crate::string::{raw_to_string, BnStrCompatible, BnString}; +use crate::string::{raw_to_string, AsCStr, BnString}; use crate::types::{QualifiedName, Type}; use crate::rc::*; pub type Result<R> = std::result::Result<R, ()>; -pub fn demangle_generic<S: BnStrCompatible>( +pub fn demangle_generic<S: AsCStr>( arch: &CoreArchitecture, mangled_name: S, view: Option<&BinaryView>, simplify: bool, ) -> Option<(QualifiedName, Option<Ref<Type>>)> { - let mangled_name_bwn = mangled_name.into_bytes_with_nul(); + let mangled_name_bwn = mangled_name.to_cstr(); let mangled_name_ptr = mangled_name_bwn.as_ref(); let mut out_type: *mut BNType = std::ptr::null_mut(); let mut out_name = BNQualifiedName::default(); @@ -58,8 +58,8 @@ pub fn demangle_generic<S: BnStrCompatible>( } } -pub fn demangle_llvm<S: BnStrCompatible>(mangled_name: S, simplify: bool) -> Option<QualifiedName> { - let mangled_name_bwn = mangled_name.into_bytes_with_nul(); +pub fn demangle_llvm<S: AsCStr>(mangled_name: S, simplify: bool) -> Option<QualifiedName> { + let mangled_name_bwn = mangled_name.to_cstr(); let mangled_name_ptr = mangled_name_bwn.as_ref(); let mut out_name: *mut *mut std::os::raw::c_char = std::ptr::null_mut(); let mut out_size: usize = 0; @@ -87,12 +87,12 @@ pub fn demangle_llvm<S: BnStrCompatible>(mangled_name: S, simplify: bool) -> Opt } } -pub fn demangle_gnu3<S: BnStrCompatible>( +pub fn demangle_gnu3<S: AsCStr>( arch: &CoreArchitecture, mangled_name: S, simplify: bool, ) -> Option<(QualifiedName, Option<Ref<Type>>)> { - let mangled_name_bwn = mangled_name.into_bytes_with_nul(); + let mangled_name_bwn = mangled_name.to_cstr(); let mangled_name_ptr = mangled_name_bwn.as_ref(); let mut out_type: *mut BNType = std::ptr::null_mut(); let mut out_name: *mut *mut std::os::raw::c_char = std::ptr::null_mut(); @@ -128,12 +128,12 @@ pub fn demangle_gnu3<S: BnStrCompatible>( } } -pub fn demangle_ms<S: BnStrCompatible>( +pub fn demangle_ms<S: AsCStr>( arch: &CoreArchitecture, mangled_name: S, simplify: bool, ) -> Option<(QualifiedName, Option<Ref<Type>>)> { - let mangled_name_bwn = mangled_name.into_bytes_with_nul(); + let mangled_name_bwn = mangled_name.to_cstr(); let mangled_name_ptr = mangled_name_bwn.as_ref(); let mut out_type: *mut BNType = std::ptr::null_mut(); @@ -187,18 +187,18 @@ impl Demangler { unsafe { Array::<Demangler>::new(demanglers, count, ()) } } - pub fn is_mangled_string<S: BnStrCompatible>(&self, name: S) -> bool { - let bytes = name.into_bytes_with_nul(); + pub fn is_mangled_string<S: AsCStr>(&self, name: S) -> bool { + let bytes = name.to_cstr(); unsafe { BNIsDemanglerMangledName(self.handle, bytes.as_ref().as_ptr() as *const _) } } - pub fn demangle<S: BnStrCompatible>( + pub fn demangle<S: AsCStr>( &self, arch: &CoreArchitecture, name: S, view: Option<&BinaryView>, ) -> Option<(QualifiedName, Option<Ref<Type>>)> { - let name_bytes = name.into_bytes_with_nul(); + let name_bytes = name.to_cstr(); let mut out_type = std::ptr::null_mut(); let mut out_var_name = BNQualifiedName::default(); @@ -236,8 +236,8 @@ impl Demangler { unsafe { BnString::into_string(BNGetDemanglerName(self.handle)) } } - pub fn from_name<S: BnStrCompatible>(name: S) -> Option<Self> { - let name_bytes = name.into_bytes_with_nul(); + pub fn from_name<S: AsCStr>(name: S) -> Option<Self> { + let name_bytes = name.to_cstr(); let demangler = unsafe { BNGetDemanglerByName(name_bytes.as_ref().as_ptr() as *const _) }; if demangler.is_null() { None @@ -248,7 +248,7 @@ impl Demangler { pub fn register<S, C>(name: S, demangler: C) -> Self where - S: BnStrCompatible, + S: AsCStr, C: CustomDemangler, { extern "C" fn cb_is_mangled_string<C>(ctxt: *mut c_void, name: *const c_char) -> bool @@ -308,7 +308,7 @@ impl Demangler { }) } - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let name_ptr = name.as_ref().as_ptr() as *mut _; let ctxt = Box::into_raw(Box::new(demangler)); diff --git a/rust/src/disassembly.rs b/rust/src/disassembly.rs index 6125f623..5964324d 100644 --- a/rust/src/disassembly.rs +++ b/rust/src/disassembly.rs @@ -22,7 +22,7 @@ use crate::function::{Location, NativeBlock}; use crate::high_level_il as hlil; use crate::low_level_il as llil; use crate::medium_level_il as mlil; -use crate::string::BnStrCompatible; +use crate::string::AsCStr; use crate::string::{raw_to_string, strings_to_string_list, BnString}; use crate::rc::*; @@ -1242,7 +1242,7 @@ impl DisassemblyTextRenderer { unsafe { Array::new(tokens, count, ()) } } - pub fn wrap_comment<S1: BnStrCompatible, S2: BnStrCompatible, S3: BnStrCompatible>( + pub fn wrap_comment<S1: AsCStr, S2: AsCStr, S3: AsCStr>( &self, cur_line: DisassemblyTextLine, comment: S1, @@ -1251,9 +1251,9 @@ impl DisassemblyTextRenderer { indent_spaces: S3, ) -> Array<DisassemblyTextLine> { let cur_line_raw = DisassemblyTextLine::into_raw(cur_line); - let comment_raw = comment.into_bytes_with_nul(); - let leading_spaces_raw = leading_spaces.into_bytes_with_nul(); - let indent_spaces_raw = indent_spaces.into_bytes_with_nul(); + let comment_raw = comment.to_cstr(); + let leading_spaces_raw = leading_spaces.to_cstr(); + let indent_spaces_raw = indent_spaces.to_cstr(); let mut count = 0; let lines = unsafe { BNDisassemblyTextRendererWrapComment( diff --git a/rust/src/download_provider.rs b/rust/src/download_provider.rs index 4b7b3c0c..f9e21e64 100644 --- a/rust/src/download_provider.rs +++ b/rust/src/download_provider.rs @@ -1,6 +1,6 @@ use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; use crate::settings::Settings; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use binaryninjacore_sys::*; use std::collections::HashMap; use std::ffi::{c_void, CStr}; @@ -13,11 +13,9 @@ pub struct DownloadProvider { } impl DownloadProvider { - pub fn get<S: BnStrCompatible>(name: S) -> Option<DownloadProvider> { + pub fn get<S: AsCStr>(name: S) -> Option<DownloadProvider> { let result = unsafe { - BNGetDownloadProviderByName( - name.into_bytes_with_nul().as_ref().as_ptr() as *const c_char - ) + BNGetDownloadProviderByName(name.to_cstr().as_ref().as_ptr() as *const c_char) }; if result.is_null() { return None; @@ -134,7 +132,7 @@ impl DownloadInstance { } } - pub fn perform_request<S: BnStrCompatible>( + pub fn perform_request<S: AsCStr>( &mut self, url: S, callbacks: DownloadInstanceOutputCallbacks, @@ -150,7 +148,7 @@ impl DownloadInstance { let result = unsafe { BNPerformDownloadRequest( self.handle, - url.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + url.to_cstr().as_ref().as_ptr() as *const c_char, &mut cbs as *mut BNDownloadInstanceOutputCallbacks, ) }; @@ -204,10 +202,10 @@ impl DownloadInstance { } pub fn perform_custom_request< - M: BnStrCompatible, - U: BnStrCompatible, - HK: BnStrCompatible, - HV: BnStrCompatible, + M: AsCStr, + U: AsCStr, + HK: AsCStr, + HV: AsCStr, I: IntoIterator<Item = (HK, HV)>, >( &mut self, @@ -219,8 +217,8 @@ impl DownloadInstance { let mut header_keys = vec![]; let mut header_values = vec![]; for (key, value) in headers { - header_keys.push(key.into_bytes_with_nul()); - header_values.push(value.into_bytes_with_nul()); + header_keys.push(key.to_cstr()); + header_values.push(value.to_cstr()); } let mut header_key_ptrs = vec![]; @@ -246,8 +244,8 @@ impl DownloadInstance { let result = unsafe { BNPerformCustomRequest( self.handle, - method.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, - url.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + method.to_cstr().as_ref().as_ptr() as *const c_char, + url.to_cstr().as_ref().as_ptr() as *const c_char, header_key_ptrs.len() as u64, header_key_ptrs.as_ptr(), header_value_ptrs.as_ptr(), diff --git a/rust/src/enterprise.rs b/rust/src/enterprise.rs index d09ac333..74389d45 100644 --- a/rust/src/enterprise.rs +++ b/rust/src/enterprise.rs @@ -1,5 +1,5 @@ use crate::rc::Array; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use std::ffi::c_void; use std::marker::PhantomData; use std::time::{Duration, SystemTime, UNIX_EPOCH}; @@ -120,8 +120,8 @@ pub fn server_url() -> String { unsafe { BnString::into_string(binaryninjacore_sys::BNGetEnterpriseServerUrl()) } } -pub fn set_server_url<S: BnStrCompatible>(url: S) -> Result<(), ()> { - let url = url.into_bytes_with_nul(); +pub fn set_server_url<S: AsCStr>(url: S) -> Result<(), ()> { + let url = url.to_cstr(); let result = unsafe { binaryninjacore_sys::BNSetEnterpriseServerUrl( url.as_ref().as_ptr() as *const std::os::raw::c_char @@ -185,11 +185,11 @@ pub fn is_server_license_still_activated() -> bool { pub fn authenticate_server_with_credentials<U, P>(username: U, password: P, remember: bool) -> bool where - U: BnStrCompatible, - P: BnStrCompatible, + U: AsCStr, + P: AsCStr, { - let username = username.into_bytes_with_nul(); - let password = password.into_bytes_with_nul(); + let username = username.to_cstr(); + let password = password.to_cstr(); unsafe { binaryninjacore_sys::BNAuthenticateEnterpriseServerWithCredentials( username.as_ref().as_ptr() as *const std::os::raw::c_char, @@ -199,8 +199,8 @@ where } } -pub fn authenticate_server_with_method<S: BnStrCompatible>(method: S, remember: bool) -> bool { - let method = method.into_bytes_with_nul(); +pub fn authenticate_server_with_method<S: AsCStr>(method: S, remember: bool) -> bool { + let method = method.to_cstr(); unsafe { binaryninjacore_sys::BNAuthenticateEnterpriseServerWithMethod( method.as_ref().as_ptr() as *const std::os::raw::c_char, diff --git a/rust/src/external_library.rs b/rust/src/external_library.rs index 5360f29d..26425ccd 100644 --- a/rust/src/external_library.rs +++ b/rust/src/external_library.rs @@ -1,6 +1,6 @@ use crate::project::file::ProjectFile; use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use crate::symbol::Symbol; use binaryninjacore_sys::*; use std::ffi::c_char; @@ -167,9 +167,9 @@ impl ExternalLocation { /// Set the symbol pointed to by this ExternalLocation. /// ExternalLocations must have a valid target address and/or symbol set. - pub fn set_target_symbol<S: BnStrCompatible>(&self, symbol: Option<S>) -> bool { + pub fn set_target_symbol<S: AsCStr>(&self, symbol: Option<S>) -> bool { let symbol = symbol - .map(|x| x.into_bytes_with_nul().as_ref().as_ptr() as *const c_char) + .map(|x| x.to_cstr().as_ref().as_ptr() as *const c_char) .unwrap_or(std::ptr::null_mut()); unsafe { BNExternalLocationSetTargetSymbol(self.handle.as_ptr(), symbol) } } diff --git a/rust/src/file_metadata.rs b/rust/src/file_metadata.rs index c14aaf29..6b6a79a8 100644 --- a/rust/src/file_metadata.rs +++ b/rust/src/file_metadata.rs @@ -52,7 +52,7 @@ impl FileMetadata { Self::ref_from_raw(unsafe { BNCreateFileMetadata() }) } - pub fn with_filename<S: BnStrCompatible>(name: S) -> Ref<Self> { + pub fn with_filename<S: AsCStr>(name: S) -> Ref<Self> { let ret = FileMetadata::new(); ret.set_filename(name); ret @@ -75,8 +75,8 @@ impl FileMetadata { } } - pub fn set_filename<S: BnStrCompatible>(&self, name: S) { - let name = name.into_bytes_with_nul(); + pub fn set_filename<S: AsCStr>(&self, name: S) { + let name = name.to_cstr(); unsafe { BNSetFilename(self.handle, name.as_ref().as_ptr() as *mut _); @@ -107,8 +107,8 @@ impl FileMetadata { self.is_database_backed_for_view_type("") } - pub fn is_database_backed_for_view_type<S: BnStrCompatible>(&self, view_type: S) -> bool { - let view_type = view_type.into_bytes_with_nul(); + pub fn is_database_backed_for_view_type<S: AsCStr>(&self, view_type: S) -> bool { + let view_type = view_type.to_cstr(); unsafe { BNIsBackedByDatabase(self.handle, view_type.as_ref().as_ptr() as *const _) } } @@ -135,15 +135,15 @@ impl FileMetadata { unsafe { BnString::into_string(BNBeginUndoActions(self.handle, anonymous_allowed)) } } - pub fn commit_undo_actions<S: BnStrCompatible>(&self, id: S) { - let id = id.into_bytes_with_nul(); + pub fn commit_undo_actions<S: AsCStr>(&self, id: S) { + let id = id.to_cstr(); unsafe { BNCommitUndoActions(self.handle, id.as_ref().as_ptr() as *const _); } } - pub fn revert_undo_actions<S: BnStrCompatible>(&self, id: S) { - let id = id.into_bytes_with_nul(); + pub fn revert_undo_actions<S: AsCStr>(&self, id: S) { + let id = id.to_cstr(); unsafe { BNRevertUndoActions(self.handle, id.as_ref().as_ptr() as *const _); } @@ -169,8 +169,8 @@ impl FileMetadata { unsafe { BNGetCurrentOffset(self.handle) } } - pub fn navigate_to<S: BnStrCompatible>(&self, view: S, offset: u64) -> Result<(), ()> { - let view = view.into_bytes_with_nul(); + pub fn navigate_to<S: AsCStr>(&self, view: S, offset: u64) -> Result<(), ()> { + let view = view.to_cstr(); unsafe { if BNNavigate(self.handle, view.as_ref().as_ptr() as *const _, offset) { @@ -181,8 +181,8 @@ impl FileMetadata { } } - pub fn view_of_type<S: BnStrCompatible>(&self, view: S) -> Option<Ref<BinaryView>> { - let view = view.into_bytes_with_nul(); + pub fn view_of_type<S: AsCStr>(&self, view: S) -> Option<Ref<BinaryView>> { + let view = view.to_cstr(); unsafe { let raw_view_ptr = BNGetFileViewOfType(self.handle, view.as_ref().as_ptr() as *const _); @@ -215,7 +215,7 @@ impl FileMetadata { return false; }; - let file_path = file_path.as_ref().into_bytes_with_nul(); + let file_path = file_path.as_ref().to_cstr(); unsafe { BNCreateDatabase( raw_view.handle, @@ -226,7 +226,7 @@ impl FileMetadata { } // TODO: Pass settings? - pub fn create_database_with_progress<S: BnStrCompatible, P: ProgressCallback>( + pub fn create_database_with_progress<S: AsCStr, P: ProgressCallback>( &self, file_path: impl AsRef<Path>, mut progress: P, @@ -235,7 +235,7 @@ impl FileMetadata { let Some(raw_view) = self.view_of_type("Raw") else { return false; }; - let file_path = file_path.as_ref().into_bytes_with_nul(); + let file_path = file_path.as_ref().to_cstr(); unsafe { BNCreateDatabaseWithProgress( raw_view.handle, @@ -256,11 +256,11 @@ impl FileMetadata { unsafe { BNSaveAutoSnapshot(raw_view.handle, ptr::null_mut() as *mut _) } } - pub fn open_database_for_configuration<S: BnStrCompatible>( + pub fn open_database_for_configuration<S: AsCStr>( &self, filename: S, ) -> Result<Ref<BinaryView>, ()> { - let filename = filename.into_bytes_with_nul(); + let filename = filename.to_cstr(); unsafe { let bv = BNOpenDatabaseForConfiguration(self.handle, filename.as_ref().as_ptr() as *const _); @@ -273,8 +273,8 @@ impl FileMetadata { } } - pub fn open_database<S: BnStrCompatible>(&self, filename: S) -> Result<Ref<BinaryView>, ()> { - let filename = filename.into_bytes_with_nul(); + pub fn open_database<S: AsCStr>(&self, filename: S) -> Result<Ref<BinaryView>, ()> { + let filename = filename.to_cstr(); let filename_ptr = filename.as_ref().as_ptr() as *mut _; let view = unsafe { BNOpenExistingDatabase(self.handle, filename_ptr) }; @@ -286,12 +286,12 @@ impl FileMetadata { } } - pub fn open_database_with_progress<S: BnStrCompatible, P: ProgressCallback>( + pub fn open_database_with_progress<S: AsCStr, P: ProgressCallback>( &self, filename: S, mut progress: P, ) -> Result<Ref<BinaryView>, ()> { - let filename = filename.into_bytes_with_nul(); + let filename = filename.to_cstr(); let filename_ptr = filename.as_ref().as_ptr() as *mut _; let view = unsafe { diff --git a/rust/src/function.rs b/rust/src/function.rs index 50753d74..dcefaa35 100644 --- a/rust/src/function.rs +++ b/rust/src/function.rs @@ -372,8 +372,8 @@ impl Function { unsafe { BnString::into_string(BNGetFunctionComment(self.handle)) } } - pub fn set_comment<S: BnStrCompatible>(&self, comment: S) { - let raw = comment.into_bytes_with_nul(); + pub fn set_comment<S: AsCStr>(&self, comment: S) { + let raw = comment.to_cstr(); unsafe { BNSetFunctionComment(self.handle, raw.as_ref().as_ptr() as *mut _); @@ -394,8 +394,8 @@ impl Function { unsafe { BnString::into_string(BNGetCommentForAddress(self.handle, addr)) } } - pub fn set_comment_at<S: BnStrCompatible>(&self, addr: u64, comment: S) { - let raw = comment.into_bytes_with_nul(); + pub fn set_comment_at<S: AsCStr>(&self, addr: u64, comment: S) { + let raw = comment.to_cstr(); unsafe { BNSetCommentForAddress(self.handle, addr, raw.as_ref().as_ptr() as *mut _); @@ -1103,7 +1103,7 @@ impl Function { /// let crash = bv.create_tag_type("Crashes", "🎯"); /// fun.add_tag(&crash, "Nullpointer dereference", Some(0x1337), false, None); /// ``` - pub fn add_tag<S: BnStrCompatible>( + pub fn add_tag<S: AsCStr>( &self, tag_type: &TagType, data: S, @@ -1707,10 +1707,10 @@ impl Function { operand: usize, display_type: IntegerDisplayType, arch: Option<CoreArchitecture>, - enum_display_typeid: Option<impl BnStrCompatible>, + enum_display_typeid: Option<impl AsCStr>, ) { let arch = arch.unwrap_or_else(|| self.arch()); - let enum_display_typeid = enum_display_typeid.map(BnStrCompatible::into_bytes_with_nul); + let enum_display_typeid = enum_display_typeid.map(AsCStr::to_cstr); let enum_display_typeid_ptr = enum_display_typeid .map(|x| x.as_ref().as_ptr() as *const c_char) .unwrap_or(std::ptr::null()); diff --git a/rust/src/high_level_il/operation.rs b/rust/src/high_level_il/operation.rs index c5733a43..302a6d73 100644 --- a/rust/src/high_level_il/operation.rs +++ b/rust/src/high_level_il/operation.rs @@ -6,7 +6,7 @@ use super::HighLevelILLiftedInstruction; use crate::architecture::CoreIntrinsic; use crate::function::Function; use crate::rc::Ref; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use crate::variable::{ConstantData, SSAVariable, Variable}; #[derive(Clone, PartialEq, Eq)] @@ -20,8 +20,8 @@ impl GotoLabel { unsafe { BnString::into_string(BNGetGotoLabelName(self.function.handle, self.target)) } } - fn set_name<S: BnStrCompatible>(&self, name: S) { - let raw = name.into_bytes_with_nul(); + fn set_name<S: AsCStr>(&self, name: S) { + let raw = name.to_cstr(); unsafe { BNSetUserGotoLabelName( self.function.handle, @@ -327,7 +327,7 @@ impl LiftedLabel { self.target.name() } - pub fn set_name<S: BnStrCompatible>(&self, name: S) { + pub fn set_name<S: AsCStr>(&self, name: S) { self.target.set_name(name) } } diff --git a/rust/src/interaction.rs b/rust/src/interaction.rs index 23dcaf85..7e007eb9 100644 --- a/rust/src/interaction.rs +++ b/rust/src/interaction.rs @@ -21,7 +21,7 @@ use std::path::PathBuf; use crate::binary_view::BinaryView; use crate::rc::Ref; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; pub fn get_text_line_input(prompt: &str, title: &str) -> Option<String> { let mut value: *mut c_char = std::ptr::null_mut(); @@ -29,8 +29,8 @@ pub fn get_text_line_input(prompt: &str, title: &str) -> Option<String> { let result = unsafe { BNGetTextLineInput( &mut value, - prompt.into_bytes_with_nul().as_ptr() as *mut _, - title.into_bytes_with_nul().as_ptr() as *mut _, + prompt.to_cstr().as_ptr() as *mut _, + title.to_cstr().as_ptr() as *mut _, ) }; if !result { @@ -46,8 +46,8 @@ pub fn get_integer_input(prompt: &str, title: &str) -> Option<i64> { let result = unsafe { BNGetIntegerInput( &mut value, - prompt.into_bytes_with_nul().as_ptr() as *mut _, - title.into_bytes_with_nul().as_ptr() as *mut _, + prompt.to_cstr().as_ptr() as *mut _, + title.to_cstr().as_ptr() as *mut _, ) }; @@ -64,8 +64,8 @@ pub fn get_address_input(prompt: &str, title: &str) -> Option<u64> { let result = unsafe { BNGetAddressInput( &mut value, - prompt.into_bytes_with_nul().as_ptr() as *mut _, - title.into_bytes_with_nul().as_ptr() as *mut _, + prompt.to_cstr().as_ptr() as *mut _, + title.to_cstr().as_ptr() as *mut _, std::ptr::null_mut(), 0, ) @@ -84,8 +84,8 @@ pub fn get_open_filename_input(prompt: &str, extension: &str) -> Option<PathBuf> let result = unsafe { BNGetOpenFileNameInput( &mut value, - prompt.into_bytes_with_nul().as_ptr() as *mut _, - extension.into_bytes_with_nul().as_ptr() as *mut _, + prompt.to_cstr().as_ptr() as *mut _, + extension.to_cstr().as_ptr() as *mut _, ) }; if !result { @@ -106,9 +106,9 @@ pub fn get_save_filename_input( let result = unsafe { BNGetSaveFileNameInput( &mut value, - prompt.into_bytes_with_nul().as_ptr() as *mut _, - extension.into_bytes_with_nul().as_ptr() as *mut _, - default_name.into_bytes_with_nul().as_ptr() as *mut _, + prompt.to_cstr().as_ptr() as *mut _, + extension.to_cstr().as_ptr() as *mut _, + default_name.to_cstr().as_ptr() as *mut _, ) }; if !result { @@ -125,8 +125,8 @@ pub fn get_directory_name_input(prompt: &str, default_name: &str) -> Option<Path let result = unsafe { BNGetDirectoryNameInput( &mut value, - prompt.into_bytes_with_nul().as_ptr() as *mut _, - default_name.into_bytes_with_nul().as_ptr() as *mut _, + prompt.to_cstr().as_ptr() as *mut _, + default_name.to_cstr().as_ptr() as *mut _, ) }; if !result { @@ -148,8 +148,8 @@ pub fn show_message_box( ) -> MessageBoxButtonResult { unsafe { BNShowMessageBox( - title.into_bytes_with_nul().as_ptr() as *mut _, - text.into_bytes_with_nul().as_ptr() as *mut _, + title.to_cstr().as_ptr() as *mut _, + text.to_cstr().as_ptr() as *mut _, buttons, icon, ) @@ -495,7 +495,7 @@ impl FormInputBuilder { BNGetFormInput( self.fields.as_mut_ptr(), self.fields.len(), - title.into_bytes_with_nul().as_ptr() as *const _, + title.to_cstr().as_ptr() as *const _, ) } { let result = self @@ -577,7 +577,7 @@ pub fn run_progress_dialog<F: Fn(Box<dyn Fn(usize, usize) -> Result<(), ()>>)>( if unsafe { BNRunProgressDialog( - title.into_bytes_with_nul().as_ptr() as *mut _, + title.to_cstr().as_ptr() as *mut _, can_cancel, Some(cb_task::<F>), &mut ctxt as *mut _ as *mut c_void, diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 4d6b97b4..63872be3 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -102,7 +102,7 @@ use std::cmp; use std::collections::HashMap; use std::ffi::{c_char, c_void, CStr}; use std::path::{Path, PathBuf}; -use string::BnStrCompatible; +use string::AsCStr; use string::BnString; use string::IntoJson; @@ -128,7 +128,7 @@ pub fn load_with_progress<P: ProgressCallback>( file_path: impl AsRef<Path>, mut progress: P, ) -> Option<Ref<BinaryView>> { - let file_path = file_path.as_ref().into_bytes_with_nul(); + let file_path = file_path.as_ref().to_cstr(); let options = c""; let handle = unsafe { BNLoadFilename( @@ -193,13 +193,9 @@ where O: IntoJson, P: ProgressCallback, { - let file_path = file_path.as_ref().into_bytes_with_nul(); + let file_path = file_path.as_ref().to_cstr(); let options_or_default = if let Some(opt) = options { - opt.get_json_string() - .ok()? - .into_bytes_with_nul() - .as_ref() - .to_vec() + opt.get_json_string().ok()?.to_cstr().to_bytes().to_vec() } else { Metadata::new_of_type(MetadataType::KeyValueDataType) .get_json_string() @@ -247,11 +243,7 @@ where P: ProgressCallback, { let options_or_default = if let Some(opt) = options { - opt.get_json_string() - .ok()? - .into_bytes_with_nul() - .as_ref() - .to_vec() + opt.get_json_string().ok()?.to_cstr().to_bytes().to_vec() } else { Metadata::new_of_type(MetadataType::KeyValueDataType) .get_json_string() @@ -292,7 +284,7 @@ pub fn bundled_plugin_directory() -> Result<PathBuf, ()> { } pub fn set_bundled_plugin_directory(new_dir: impl AsRef<Path>) { - let new_dir = new_dir.as_ref().into_bytes_with_nul(); + let new_dir = new_dir.as_ref().to_cstr(); unsafe { BNSetBundledPluginDirectory(new_dir.as_ptr() as *const c_char) }; } @@ -336,7 +328,7 @@ pub fn save_last_run() { } pub fn path_relative_to_bundled_plugin_directory(path: impl AsRef<Path>) -> Result<PathBuf, ()> { - let path_raw = path.as_ref().into_bytes_with_nul(); + let path_raw = path.as_ref().to_cstr(); let s: *mut c_char = unsafe { BNGetPathRelativeToBundledPluginDirectory(path_raw.as_ptr() as *const c_char) }; if s.is_null() { @@ -346,7 +338,7 @@ pub fn path_relative_to_bundled_plugin_directory(path: impl AsRef<Path>) -> Resu } pub fn path_relative_to_user_plugin_directory(path: impl AsRef<Path>) -> Result<PathBuf, ()> { - let path_raw = path.as_ref().into_bytes_with_nul(); + let path_raw = path.as_ref().to_cstr(); let s: *mut c_char = unsafe { BNGetPathRelativeToUserPluginDirectory(path_raw.as_ptr() as *const c_char) }; if s.is_null() { @@ -356,7 +348,7 @@ pub fn path_relative_to_user_plugin_directory(path: impl AsRef<Path>) -> Result< } pub fn path_relative_to_user_directory(path: impl AsRef<Path>) -> Result<PathBuf, ()> { - let path_raw = path.as_ref().into_bytes_with_nul(); + let path_raw = path.as_ref().to_cstr(); let s: *mut c_char = unsafe { BNGetPathRelativeToUserDirectory(path_raw.as_ptr() as *const c_char) }; if s.is_null() { @@ -481,8 +473,8 @@ impl VersionInfo { unsafe { BnString::free_raw(value.channel) }; } - pub fn from_string<S: BnStrCompatible>(string: S) -> Self { - let string = string.into_bytes_with_nul(); + pub fn from_string<S: AsCStr>(string: S) -> Self { + let string = string.to_cstr(); let result = unsafe { BNParseVersionString(string.as_ref().as_ptr() as *const c_char) }; Self::from_owned_raw(result) } @@ -540,14 +532,14 @@ pub fn license_count() -> i32 { /// 1. Check the BN_LICENSE environment variable /// 2. Check the Binary Ninja user directory for license.dat #[cfg(not(feature = "demo"))] -pub fn set_license<S: BnStrCompatible + Default>(license: Option<S>) { - let license = license.unwrap_or_default().into_bytes_with_nul(); +pub fn set_license<S: AsCStr + Default>(license: Option<S>) { + let license = license.unwrap_or_default().to_cstr(); let license_slice = license.as_ref(); unsafe { BNSetLicense(license_slice.as_ptr() as *const c_char) } } #[cfg(feature = "demo")] -pub fn set_license<S: BnStrCompatible + Default>(_license: Option<S>) {} +pub fn set_license<S: AsCStr + Default>(_license: Option<S>) {} pub fn product() -> String { unsafe { BnString::into_string(BNGetProduct()) } @@ -566,8 +558,8 @@ pub fn is_ui_enabled() -> bool { unsafe { BNIsUIEnabled() } } -pub fn is_database<S: BnStrCompatible>(filename: S) -> bool { - let filename = filename.into_bytes_with_nul(); +pub fn is_database<S: AsCStr>(filename: S) -> bool { + let filename = filename.to_cstr(); let filename_slice = filename.as_ref(); unsafe { BNIsDatabase(filename_slice.as_ptr() as *const c_char) } } @@ -596,16 +588,12 @@ pub fn plugin_ui_abi_minimum_version() -> u32 { BN_MINIMUM_UI_ABI_VERSION } -pub fn add_required_plugin_dependency<S: BnStrCompatible>(name: S) { - unsafe { - BNAddRequiredPluginDependency(name.into_bytes_with_nul().as_ref().as_ptr() as *const c_char) - }; +pub fn add_required_plugin_dependency<S: AsCStr>(name: S) { + unsafe { BNAddRequiredPluginDependency(name.to_cstr().as_ref().as_ptr() as *const c_char) }; } -pub fn add_optional_plugin_dependency<S: BnStrCompatible>(name: S) { - unsafe { - BNAddOptionalPluginDependency(name.into_bytes_with_nul().as_ref().as_ptr() as *const c_char) - }; +pub fn add_optional_plugin_dependency<S: AsCStr>(name: S) { + unsafe { BNAddOptionalPluginDependency(name.to_cstr().as_ref().as_ptr() as *const c_char) }; } // Provide ABI version automatically so that the core can verify binary compatibility diff --git a/rust/src/medium_level_il/function.rs b/rust/src/medium_level_il/function.rs index 0ac82ff1..de3ece02 100644 --- a/rust/src/medium_level_il/function.rs +++ b/rust/src/medium_level_il/function.rs @@ -11,7 +11,7 @@ use crate::disassembly::DisassemblySettings; use crate::flowgraph::FlowGraph; use crate::function::{Function, Location}; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref, RefCountable}; -use crate::string::BnStrCompatible; +use crate::string::AsCStr; use crate::types::Type; use crate::variable::{PossibleValueSet, RegisterValue, SSAVariable, UserVariableValue, Variable}; @@ -122,14 +122,14 @@ impl MediumLevelILFunction { unsafe { Array::new(raw_instr_idxs, count, self.to_owned()) } } - pub fn create_user_stack_var<'a, S: BnStrCompatible, C: Into<Conf<&'a Type>>>( + pub fn create_user_stack_var<'a, S: AsCStr, C: Into<Conf<&'a Type>>>( self, offset: i64, var_type: C, name: S, ) { let mut owned_raw_var_ty = Conf::<&Type>::into_raw(var_type.into()); - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); unsafe { BNCreateUserStackVariable( self.function().handle, @@ -144,7 +144,7 @@ impl MediumLevelILFunction { unsafe { BNDeleteUserStackVariable(self.function().handle, offset) } } - pub fn create_user_var<'a, S: BnStrCompatible, C: Into<Conf<&'a Type>>>( + pub fn create_user_var<'a, S: AsCStr, C: Into<Conf<&'a Type>>>( &self, var: &Variable, var_type: C, @@ -153,7 +153,7 @@ impl MediumLevelILFunction { ) { let raw_var = BNVariable::from(var); let mut owned_raw_var_ty = Conf::<&Type>::into_raw(var_type.into()); - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); unsafe { BNCreateUserVariable( self.function().handle, @@ -274,14 +274,14 @@ impl MediumLevelILFunction { Ok(()) } - pub fn create_auto_stack_var<'a, T: Into<Conf<&'a Type>>, S: BnStrCompatible>( + pub fn create_auto_stack_var<'a, T: Into<Conf<&'a Type>>, S: AsCStr>( &self, offset: i64, var_type: T, name: S, ) { let mut owned_raw_var_ty = Conf::<&Type>::into_raw(var_type.into()); - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let name_c_str = name.as_ref(); unsafe { BNCreateAutoStackVariable( @@ -297,7 +297,7 @@ impl MediumLevelILFunction { unsafe { BNDeleteAutoStackVariable(self.function().handle, offset) } } - pub fn create_auto_var<'a, S: BnStrCompatible, C: Into<Conf<&'a Type>>>( + pub fn create_auto_var<'a, S: AsCStr, C: Into<Conf<&'a Type>>>( &self, var: &Variable, var_type: C, @@ -306,7 +306,7 @@ impl MediumLevelILFunction { ) { let raw_var = BNVariable::from(var); let mut owned_raw_var_ty = Conf::<&Type>::into_raw(var_type.into()); - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let name_c_str = name.as_ref(); unsafe { BNCreateAutoVariable( diff --git a/rust/src/metadata.rs b/rust/src/metadata.rs index fc935cd5..c31e806b 100644 --- a/rust/src/metadata.rs +++ b/rust/src/metadata.rs @@ -1,5 +1,5 @@ use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString, IntoJson}; +use crate::string::{AsCStr, BnString, IntoJson}; use binaryninjacore_sys::*; use std::collections::HashMap; use std::os::raw::c_char; @@ -267,14 +267,14 @@ impl Metadata { Ok(Some(unsafe { Self::ref_from_raw(ptr) })) } - pub fn get<S: BnStrCompatible>(&self, key: S) -> Result<Option<Ref<Metadata>>, ()> { + pub fn get<S: AsCStr>(&self, key: S) -> Result<Option<Ref<Metadata>>, ()> { if self.get_type() != MetadataType::KeyValueDataType { return Err(()); } let ptr: *mut BNMetadata = unsafe { BNMetadataGetForKey( self.handle, - key.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + key.to_cstr().as_ref().as_ptr() as *const c_char, ) }; if ptr.is_null() { @@ -291,7 +291,7 @@ impl Metadata { Ok(()) } - pub fn insert<S: BnStrCompatible>(&self, key: S, value: &Metadata) -> Result<(), ()> { + pub fn insert<S: AsCStr>(&self, key: S, value: &Metadata) -> Result<(), ()> { if self.get_type() != MetadataType::KeyValueDataType { return Err(()); } @@ -299,7 +299,7 @@ impl Metadata { unsafe { BNMetadataSetValueForKey( self.handle, - key.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + key.to_cstr().as_ref().as_ptr() as *const c_char, value.handle, ) }; @@ -315,7 +315,7 @@ impl Metadata { Ok(()) } - pub fn remove_key<S: BnStrCompatible>(&self, key: S) -> Result<(), ()> { + pub fn remove_key<S: AsCStr>(&self, key: S) -> Result<(), ()> { if self.get_type() != MetadataType::KeyValueDataType { return Err(()); } @@ -323,7 +323,7 @@ impl Metadata { unsafe { BNMetadataRemoveKey( self.handle, - key.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + key.to_cstr().as_ref().as_ptr() as *const c_char, ) }; Ok(()) @@ -398,7 +398,7 @@ impl From<String> for Ref<Metadata> { fn from(value: String) -> Self { unsafe { Metadata::ref_from_raw(BNCreateMetadataStringData( - value.into_bytes_with_nul().as_ptr() as *const c_char, + value.to_cstr().as_ptr() as *const c_char )) } } @@ -408,7 +408,7 @@ impl From<&str> for Ref<Metadata> { fn from(value: &str) -> Self { unsafe { Metadata::ref_from_raw(BNCreateMetadataStringData( - value.into_bytes_with_nul().as_ptr() as *const c_char, + value.to_cstr().as_ptr() as *const c_char )) } } @@ -444,12 +444,10 @@ impl From<&Array<Metadata>> for Ref<Metadata> { } } -impl<S: BnStrCompatible> From<HashMap<S, Ref<Metadata>>> for Ref<Metadata> { +impl<S: AsCStr> From<HashMap<S, Ref<Metadata>>> for Ref<Metadata> { fn from(value: HashMap<S, Ref<Metadata>>) -> Self { - let data: Vec<(S::Result, Ref<Metadata>)> = value - .into_iter() - .map(|(k, v)| (k.into_bytes_with_nul(), v)) - .collect(); + let data: Vec<(S::Result, Ref<Metadata>)> = + value.into_iter().map(|(k, v)| (k.to_cstr(), v)).collect(); let mut keys: Vec<*const c_char> = data .iter() .map(|(k, _)| k.as_ref().as_ptr() as *const c_char) @@ -468,14 +466,12 @@ impl<S: BnStrCompatible> From<HashMap<S, Ref<Metadata>>> for Ref<Metadata> { impl<S, T> From<&[(S, T)]> for Ref<Metadata> where - S: BnStrCompatible + Copy, + S: AsCStr + Copy, for<'a> &'a T: Into<Ref<Metadata>>, { fn from(value: &[(S, T)]) -> Self { - let data: Vec<(S::Result, Ref<Metadata>)> = value - .iter() - .map(|(k, v)| (k.into_bytes_with_nul(), v.into())) - .collect(); + let data: Vec<(S::Result, Ref<Metadata>)> = + value.iter().map(|(k, v)| (k.to_cstr(), v.into())).collect(); let mut keys: Vec<*const c_char> = data .iter() .map(|(k, _)| k.as_ref().as_ptr() as *const c_char) @@ -494,7 +490,7 @@ where impl<S, T, const N: usize> From<[(S, T); N]> for Ref<Metadata> where - S: BnStrCompatible + Copy, + S: AsCStr + Copy, for<'a> &'a T: Into<Ref<Metadata>>, { fn from(value: [(S, T); N]) -> Self { @@ -548,11 +544,11 @@ impl From<&Vec<f64>> for Ref<Metadata> { } } -impl<S: BnStrCompatible> From<Vec<S>> for Ref<Metadata> { +impl<S: AsCStr> From<Vec<S>> for Ref<Metadata> { fn from(value: Vec<S>) -> Self { let mut refs = vec![]; for v in value { - refs.push(v.into_bytes_with_nul()); + refs.push(v.to_cstr()); } let mut pointers = vec![]; for r in &refs { diff --git a/rust/src/platform.rs b/rust/src/platform.rs index 65138c19..19186740 100644 --- a/rust/src/platform.rs +++ b/rust/src/platform.rs @@ -82,8 +82,8 @@ impl Platform { Ref::new(Self { handle }) } - pub fn by_name<S: BnStrCompatible>(name: S) -> Option<Ref<Self>> { - let raw_name = name.into_bytes_with_nul(); + pub fn by_name<S: AsCStr>(name: S) -> Option<Ref<Self>> { + let raw_name = name.to_cstr(); unsafe { let res = BNGetPlatformByName(raw_name.as_ref().as_ptr() as *mut _); @@ -113,8 +113,8 @@ impl Platform { } } - pub fn list_by_os<S: BnStrCompatible>(name: S) -> Array<Platform> { - let raw_name = name.into_bytes_with_nul(); + pub fn list_by_os<S: AsCStr>(name: S) -> Array<Platform> { + let raw_name = name.to_cstr(); unsafe { let mut count = 0; @@ -124,11 +124,8 @@ impl Platform { } } - pub fn list_by_os_and_arch<S: BnStrCompatible>( - name: S, - arch: &CoreArchitecture, - ) -> Array<Platform> { - let raw_name = name.into_bytes_with_nul(); + pub fn list_by_os_and_arch<S: AsCStr>(name: S, arch: &CoreArchitecture) -> Array<Platform> { + let raw_name = name.to_cstr(); unsafe { let mut count = 0; @@ -151,8 +148,8 @@ impl Platform { } } - pub fn new<A: Architecture, S: BnStrCompatible>(arch: &A, name: S) -> Ref<Self> { - let name = name.into_bytes_with_nul(); + pub fn new<A: Architecture, S: AsCStr>(arch: &A, name: S) -> Ref<Self> { + let name = name.to_cstr(); unsafe { let handle = BNCreatePlatform(arch.as_ref().handle, name.as_ref().as_ptr() as *mut _); assert!(!handle.is_null()); @@ -179,9 +176,9 @@ impl Platform { unsafe { TypeContainer::from_raw(type_container_ptr.unwrap()) } } - pub fn get_type_libraries_by_name<T: BnStrCompatible>(&self, name: T) -> Array<TypeLibrary> { + pub fn get_type_libraries_by_name<T: AsCStr>(&self, name: T) -> Array<TypeLibrary> { let mut count = 0; - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let result = unsafe { BNGetPlatformTypeLibrariesByName( self.handle, @@ -193,8 +190,8 @@ impl Platform { unsafe { Array::new(result, count, ()) } } - pub fn register_os<S: BnStrCompatible>(&self, os: S) { - let os = os.into_bytes_with_nul(); + pub fn register_os<S: AsCStr>(&self, os: S) { + let os = os.to_cstr(); unsafe { BNRegisterPlatform(os.as_ref().as_ptr() as *mut _, self.handle); diff --git a/rust/src/project.rs b/rust/src/project.rs index ebb6949e..453f1c56 100644 --- a/rust/src/project.rs +++ b/rust/src/project.rs @@ -13,7 +13,7 @@ use crate::progress::{NoProgressCallback, ProgressCallback}; use crate::project::file::ProjectFile; use crate::project::folder::ProjectFolder; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; pub struct Project { pub(crate) handle: NonNull<BNProject>, @@ -39,9 +39,9 @@ impl Project { /// /// * `path` - Path to the project directory (.bnpr) /// * `name` - Name of the new project - pub fn create<P: BnStrCompatible, S: BnStrCompatible>(path: P, name: S) -> Option<Ref<Self>> { - let path_raw = path.into_bytes_with_nul(); - let name_raw = name.into_bytes_with_nul(); + pub fn create<P: AsCStr, S: AsCStr>(path: P, name: S) -> Option<Ref<Self>> { + let path_raw = path.to_cstr(); + let name_raw = name.to_cstr(); let handle = unsafe { BNCreateProject( path_raw.as_ref().as_ptr() as *const c_char, @@ -54,8 +54,8 @@ impl Project { /// Open an existing project /// /// * `path` - Path to the project directory (.bnpr) or project metadata file (.bnpm) - pub fn open_project<P: BnStrCompatible>(path: P) -> Option<Ref<Self>> { - let path_raw = path.into_bytes_with_nul(); + pub fn open_project<P: AsCStr>(path: P) -> Option<Ref<Self>> { + let path_raw = path.to_cstr(); let handle = unsafe { BNOpenProject(path_raw.as_ref().as_ptr() as *const c_char) }; NonNull::new(handle).map(|h| unsafe { Self::ref_from_raw(h) }) } @@ -99,8 +99,8 @@ impl Project { } /// Set the name of the project - pub fn set_name<S: BnStrCompatible>(&self, value: S) { - let value = value.into_bytes_with_nul(); + pub fn set_name<S: AsCStr>(&self, value: S) { + let value = value.to_cstr(); unsafe { BNProjectSetName( self.handle.as_ptr(), @@ -115,8 +115,8 @@ impl Project { } /// Set the description of the project - pub fn set_description<S: BnStrCompatible>(&self, value: S) { - let value = value.into_bytes_with_nul(); + pub fn set_description<S: AsCStr>(&self, value: S) { + let value = value.to_cstr(); unsafe { BNProjectSetDescription( self.handle.as_ptr(), @@ -126,8 +126,8 @@ impl Project { } /// Retrieves metadata stored under a key from the project - pub fn query_metadata<S: BnStrCompatible>(&self, key: S) -> Ref<Metadata> { - let key = key.into_bytes_with_nul(); + pub fn query_metadata<S: AsCStr>(&self, key: S) -> Ref<Metadata> { + let key = key.to_cstr(); let result = unsafe { BNProjectQueryMetadata(self.handle.as_ptr(), key.as_ref().as_ptr() as *const c_char) }; @@ -138,8 +138,8 @@ impl Project { /// /// * `key` - Key under which to store the Metadata object /// * `value` - Object to store - pub fn store_metadata<S: BnStrCompatible>(&self, key: S, value: &Metadata) -> bool { - let key_raw = key.into_bytes_with_nul(); + pub fn store_metadata<S: AsCStr>(&self, key: S, value: &Metadata) -> bool { + let key_raw = key.to_cstr(); unsafe { BNProjectStoreMetadata( self.handle.as_ptr(), @@ -150,8 +150,8 @@ impl Project { } /// Removes the metadata associated with this `key` from the project - pub fn remove_metadata<S: BnStrCompatible>(&self, key: S) { - let key_raw = key.into_bytes_with_nul(); + pub fn remove_metadata<S: AsCStr>(&self, key: S) { + let key_raw = key.to_cstr(); unsafe { BNProjectRemoveMetadata( self.handle.as_ptr(), @@ -176,8 +176,8 @@ impl Project { description: D, ) -> Result<Ref<ProjectFolder>, ()> where - P: BnStrCompatible, - D: BnStrCompatible, + P: AsCStr, + D: AsCStr, { self.create_folder_from_path_with_progress(path, parent, description, NoProgressCallback) } @@ -196,12 +196,12 @@ impl Project { mut progress: PC, ) -> Result<Ref<ProjectFolder>, ()> where - P: BnStrCompatible, - D: BnStrCompatible, + P: AsCStr, + D: AsCStr, PC: ProgressCallback, { - let path_raw = path.into_bytes_with_nul(); - let description_raw = description.into_bytes_with_nul(); + let path_raw = path.to_cstr(); + let description_raw = description.to_cstr(); let parent_ptr = parent.map(|p| p.handle.as_ptr()).unwrap_or(null_mut()); unsafe { @@ -229,11 +229,11 @@ impl Project { description: D, ) -> Result<Ref<ProjectFolder>, ()> where - N: BnStrCompatible, - D: BnStrCompatible, + N: AsCStr, + D: AsCStr, { - let name_raw = name.into_bytes_with_nul(); - let description_raw = description.into_bytes_with_nul(); + let name_raw = name.to_cstr(); + let description_raw = description.to_cstr(); let parent_ptr = parent.map(|p| p.handle.as_ptr()).unwrap_or(null_mut()); unsafe { let result = BNProjectCreateFolder( @@ -260,14 +260,14 @@ impl Project { id: I, ) -> Result<Ref<ProjectFolder>, ()> where - N: BnStrCompatible, - D: BnStrCompatible, - I: BnStrCompatible, + N: AsCStr, + D: AsCStr, + I: AsCStr, { - let name_raw = name.into_bytes_with_nul(); - let description_raw = description.into_bytes_with_nul(); + let name_raw = name.to_cstr(); + let description_raw = description.to_cstr(); let parent_ptr = parent.map(|p| p.handle.as_ptr()).unwrap_or(null_mut()); - let id_raw = id.into_bytes_with_nul(); + let id_raw = id.to_cstr(); unsafe { let result = BNProjectCreateFolderUnsafe( self.handle.as_ptr(), @@ -292,8 +292,8 @@ impl Project { } /// Retrieve a folder in the project by unique folder `id` - pub fn folder_by_id<S: BnStrCompatible>(&self, id: S) -> Option<Ref<ProjectFolder>> { - let id_raw = id.into_bytes_with_nul(); + pub fn folder_by_id<S: AsCStr>(&self, id: S) -> Option<Ref<ProjectFolder>> { + let id_raw = id.to_cstr(); let id_ptr = id_raw.as_ref().as_ptr() as *const c_char; let result = unsafe { BNProjectGetFolderById(self.handle.as_ptr(), id_ptr) }; let handle = NonNull::new(result)?; @@ -350,9 +350,9 @@ impl Project { description: D, ) -> Result<Ref<ProjectFile>, ()> where - P: BnStrCompatible, - N: BnStrCompatible, - D: BnStrCompatible, + P: AsCStr, + N: AsCStr, + D: AsCStr, { self.create_file_from_path_with_progress( path, @@ -379,14 +379,14 @@ impl Project { mut progress: PC, ) -> Result<Ref<ProjectFile>, ()> where - P: BnStrCompatible, - N: BnStrCompatible, - D: BnStrCompatible, + P: AsCStr, + N: AsCStr, + D: AsCStr, PC: ProgressCallback, { - let path_raw = path.into_bytes_with_nul(); - let name_raw = name.into_bytes_with_nul(); - let description_raw = description.into_bytes_with_nul(); + let path_raw = path.to_cstr(); + let name_raw = name.to_cstr(); + let description_raw = description.to_cstr(); let folder_ptr = folder.map(|p| p.handle.as_ptr()).unwrap_or(null_mut()); unsafe { @@ -421,10 +421,10 @@ impl Project { creation_time: SystemTime, ) -> Result<Ref<ProjectFile>, ()> where - P: BnStrCompatible, - N: BnStrCompatible, - D: BnStrCompatible, - I: BnStrCompatible, + P: AsCStr, + N: AsCStr, + D: AsCStr, + I: AsCStr, { self.create_file_from_path_unsafe_with_progress( path, @@ -458,16 +458,16 @@ impl Project { mut progress: PC, ) -> Result<Ref<ProjectFile>, ()> where - P: BnStrCompatible, - N: BnStrCompatible, - D: BnStrCompatible, - I: BnStrCompatible, + P: AsCStr, + N: AsCStr, + D: AsCStr, + I: AsCStr, PC: ProgressCallback, { - let path_raw = path.into_bytes_with_nul(); - let name_raw = name.into_bytes_with_nul(); - let description_raw = description.into_bytes_with_nul(); - let id_raw = id.into_bytes_with_nul(); + let path_raw = path.to_cstr(); + let name_raw = name.to_cstr(); + let description_raw = description.to_cstr(); + let id_raw = id.to_cstr(); let folder_ptr = folder.map(|p| p.handle.as_ptr()).unwrap_or(null_mut()); unsafe { @@ -500,8 +500,8 @@ impl Project { description: D, ) -> Result<Ref<ProjectFile>, ()> where - N: BnStrCompatible, - D: BnStrCompatible, + N: AsCStr, + D: AsCStr, { self.create_file_with_progress(contents, folder, name, description, NoProgressCallback) } @@ -522,12 +522,12 @@ impl Project { mut progress: P, ) -> Result<Ref<ProjectFile>, ()> where - N: BnStrCompatible, - D: BnStrCompatible, + N: AsCStr, + D: AsCStr, P: ProgressCallback, { - let name_raw = name.into_bytes_with_nul(); - let description_raw = description.into_bytes_with_nul(); + let name_raw = name.to_cstr(); + let description_raw = description.to_cstr(); let folder_ptr = folder.map(|p| p.handle.as_ptr()).unwrap_or(null_mut()); unsafe { @@ -563,9 +563,9 @@ impl Project { creation_time: SystemTime, ) -> Result<Ref<ProjectFile>, ()> where - N: BnStrCompatible, - D: BnStrCompatible, - I: BnStrCompatible, + N: AsCStr, + D: AsCStr, + I: AsCStr, { self.create_file_unsafe_with_progress( contents, @@ -599,14 +599,14 @@ impl Project { mut progress: P, ) -> Result<Ref<ProjectFile>, ()> where - N: BnStrCompatible, - D: BnStrCompatible, - I: BnStrCompatible, + N: AsCStr, + D: AsCStr, + I: AsCStr, P: ProgressCallback, { - let name_raw = name.into_bytes_with_nul(); - let description_raw = description.into_bytes_with_nul(); - let id_raw = id.into_bytes_with_nul(); + let name_raw = name.to_cstr(); + let description_raw = description.to_cstr(); + let id_raw = id.to_cstr(); let folder_ptr = folder.map(|p| p.handle.as_ptr()).unwrap_or(null_mut()); unsafe { @@ -635,8 +635,8 @@ impl Project { } /// Retrieve a file in the project by unique `id` - pub fn file_by_id<S: BnStrCompatible>(&self, id: S) -> Option<Ref<ProjectFile>> { - let id_raw = id.into_bytes_with_nul(); + pub fn file_by_id<S: AsCStr>(&self, id: S) -> Option<Ref<ProjectFile>> { + let id_raw = id.to_cstr(); let id_ptr = id_raw.as_ref().as_ptr() as *const c_char; let result = unsafe { BNProjectGetFileById(self.handle.as_ptr(), id_ptr) }; @@ -645,8 +645,8 @@ impl Project { } /// Retrieve a file in the project by the `path` on disk - pub fn file_by_path<S: BnStrCompatible>(&self, path: S) -> Option<Ref<ProjectFile>> { - let path_raw = path.into_bytes_with_nul(); + pub fn file_by_path<S: AsCStr>(&self, path: S) -> Option<Ref<ProjectFile>> { + let path_raw = path.to_cstr(); let path_ptr = path_raw.as_ref().as_ptr() as *const c_char; let result = unsafe { BNProjectGetFileByPathOnDisk(self.handle.as_ptr(), path_ptr) }; diff --git a/rust/src/project/file.rs b/rust/src/project/file.rs index 35f25937..d1724ab0 100644 --- a/rust/src/project/file.rs +++ b/rust/src/project/file.rs @@ -1,6 +1,6 @@ use crate::project::{systime_from_bntime, Project, ProjectFolder}; use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use binaryninjacore_sys::{ BNFreeProjectFile, BNFreeProjectFileList, BNNewProjectFileReference, BNProjectFile, BNProjectFileExistsOnDisk, BNProjectFileExport, BNProjectFileGetCreationTimestamp, @@ -57,8 +57,8 @@ impl ProjectFile { } /// Set the name of this file - pub fn set_name<S: BnStrCompatible>(&self, value: S) -> bool { - let value_raw = value.into_bytes_with_nul(); + pub fn set_name<S: AsCStr>(&self, value: S) -> bool { + let value_raw = value.to_cstr(); unsafe { BNProjectFileSetName( self.handle.as_ptr(), @@ -73,8 +73,8 @@ impl ProjectFile { } /// Set the description of this file - pub fn set_description<S: BnStrCompatible>(&self, value: S) -> bool { - let value_raw = value.into_bytes_with_nul(); + pub fn set_description<S: AsCStr>(&self, value: S) -> bool { + let value_raw = value.to_cstr(); unsafe { BNProjectFileSetDescription( self.handle.as_ptr(), @@ -104,8 +104,8 @@ impl ProjectFile { /// Export this file to disk, `true' if the export succeeded /// /// * `dest` - Destination path for the exported contents - pub fn export<S: BnStrCompatible>(&self, dest: S) -> bool { - let dest_raw = dest.into_bytes_with_nul(); + pub fn export<S: AsCStr>(&self, dest: S) -> bool { + let dest_raw = dest.to_cstr(); unsafe { BNProjectFileExport( self.handle.as_ptr(), diff --git a/rust/src/project/folder.rs b/rust/src/project/folder.rs index 316abeaf..b8881ddc 100644 --- a/rust/src/project/folder.rs +++ b/rust/src/project/folder.rs @@ -1,7 +1,7 @@ use crate::progress::{NoProgressCallback, ProgressCallback}; use crate::project::Project; use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use binaryninjacore_sys::{ BNFreeProjectFolder, BNFreeProjectFolderList, BNNewProjectFolderReference, BNProjectFolder, BNProjectFolderExport, BNProjectFolderGetDescription, BNProjectFolderGetId, @@ -46,8 +46,8 @@ impl ProjectFolder { } /// Set the name of this folder - pub fn set_name<S: BnStrCompatible>(&self, value: S) -> bool { - let value_raw = value.into_bytes_with_nul(); + pub fn set_name<S: AsCStr>(&self, value: S) -> bool { + let value_raw = value.to_cstr(); unsafe { BNProjectFolderSetName( self.handle.as_ptr(), @@ -62,8 +62,8 @@ impl ProjectFolder { } /// Set the description of this folder - pub fn set_description<S: BnStrCompatible>(&self, value: S) -> bool { - let value_raw = value.into_bytes_with_nul(); + pub fn set_description<S: AsCStr>(&self, value: S) -> bool { + let value_raw = value.to_cstr(); unsafe { BNProjectFolderSetDescription( self.handle.as_ptr(), @@ -88,7 +88,7 @@ impl ProjectFolder { /// Recursively export this folder to disk, returns `true' if the export succeeded /// /// * `dest` - Destination path for the exported contents - pub fn export<S: BnStrCompatible>(&self, dest: S) -> bool { + pub fn export<S: AsCStr>(&self, dest: S) -> bool { self.export_with_progress(dest, NoProgressCallback) } @@ -99,10 +99,10 @@ impl ProjectFolder { /// * `progress` - [`ProgressCallback`] that will be called as contents are exporting pub fn export_with_progress<S, P>(&self, dest: S, mut progress: P) -> bool where - S: BnStrCompatible, + S: AsCStr, P: ProgressCallback, { - let dest_raw = dest.into_bytes_with_nul(); + let dest_raw = dest.to_cstr(); let success = unsafe { BNProjectFolderExport( diff --git a/rust/src/relocation.rs b/rust/src/relocation.rs index f10115c8..b794f698 100644 --- a/rust/src/relocation.rs +++ b/rust/src/relocation.rs @@ -1,6 +1,6 @@ use crate::low_level_il::RegularLowLevelILFunction; use crate::rc::Guard; -use crate::string::BnStrCompatible; +use crate::string::AsCStr; use crate::{ architecture::CoreArchitecture, binary_view::BinaryView, @@ -404,7 +404,7 @@ unsafe impl RefCountable for CoreRelocationHandler { pub(crate) fn register_relocation_handler<S, R, F>(arch: &CoreArchitecture, name: S, func: F) where - S: BnStrCompatible, + S: AsCStr, R: 'static + RelocationHandler<Handle = CustomRelocationHandlerHandle<R>> + Send + Sync + Sized, F: FnOnce(CustomRelocationHandlerHandle<R>, CoreRelocationHandler) -> R, { @@ -503,7 +503,7 @@ where .into() } - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let raw = Box::leak(Box::new( MaybeUninit::<RelocationHandlerBuilder<_>>::zeroed(), diff --git a/rust/src/render_layer.rs b/rust/src/render_layer.rs index 80ecc639..175ee167 100644 --- a/rust/src/render_layer.rs +++ b/rust/src/render_layer.rs @@ -6,7 +6,7 @@ use crate::flowgraph::FlowGraph; use crate::function::{Function, NativeBlock}; use crate::linear_view::{LinearDisassemblyLine, LinearDisassemblyLineType, LinearViewObject}; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner}; -use crate::string::BnStrCompatible; +use crate::string::AsCStr; use binaryninjacore_sys::*; use std::ffi::{c_char, c_void}; use std::ptr::NonNull; @@ -61,7 +61,7 @@ impl Default for RenderLayerDefaultState { } /// Register a [`RenderLayer`] with the API. -pub fn register_render_layer<S: BnStrCompatible, T: RenderLayer>( +pub fn register_render_layer<S: AsCStr, T: RenderLayer>( name: S, render_layer: T, default_state: RenderLayerDefaultState, @@ -75,7 +75,7 @@ pub fn register_render_layer<S: BnStrCompatible, T: RenderLayer>( }; let result = unsafe { BNRegisterRenderLayer( - name.into_bytes_with_nul().as_ref().as_ptr() as *const _, + name.to_cstr().as_ref().as_ptr() as *const _, &mut callback, default_state.into(), ) @@ -303,8 +303,8 @@ impl CoreRenderLayer { unsafe { Array::new(result, count, ()) } } - pub fn render_layer_by_name<S: BnStrCompatible>(name: S) -> Option<CoreRenderLayer> { - let name_raw = name.into_bytes_with_nul(); + pub fn render_layer_by_name<S: AsCStr>(name: S) -> Option<CoreRenderLayer> { + let name_raw = name.to_cstr(); let result = unsafe { BNGetRenderLayerByName(name_raw.as_ref().as_ptr() as *const c_char) }; NonNull::new(result).map(Self::from_raw) } diff --git a/rust/src/repository.rs b/rust/src/repository.rs index 90e414d5..8d2fbafe 100644 --- a/rust/src/repository.rs +++ b/rust/src/repository.rs @@ -9,7 +9,7 @@ use binaryninjacore_sys::*; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; use crate::repository::plugin::RepositoryPlugin; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; pub use manager::RepositoryManager; @@ -52,8 +52,8 @@ impl Repository { unsafe { Array::new(result, count, ()) } } - pub fn plugin_by_path<S: BnStrCompatible>(&self, path: S) -> Option<Ref<RepositoryPlugin>> { - let path = path.into_bytes_with_nul(); + pub fn plugin_by_path<S: AsCStr>(&self, path: S) -> Option<Ref<RepositoryPlugin>> { + let path = path.to_cstr(); let result = unsafe { BNRepositoryGetPluginByPath( self.handle.as_ptr(), diff --git a/rust/src/repository/manager.rs b/rust/src/repository/manager.rs index 59889162..e5911802 100644 --- a/rust/src/repository/manager.rs +++ b/rust/src/repository/manager.rs @@ -1,6 +1,6 @@ use crate::rc::{Array, Ref, RefCountable}; use crate::repository::Repository; -use crate::string::BnStrCompatible; +use crate::string::AsCStr; use binaryninjacore_sys::{ BNCreateRepositoryManager, BNFreeRepositoryManager, BNGetRepositoryManager, BNNewRepositoryManagerReference, BNRepositoryGetRepositoryByPath, BNRepositoryManager, @@ -29,8 +29,8 @@ impl RepositoryManager { Ref::new(Self { handle }) } - pub fn new<S: BnStrCompatible>(plugins_path: S) -> Ref<Self> { - let plugins_path = plugins_path.into_bytes_with_nul(); + pub fn new<S: AsCStr>(plugins_path: S) -> Ref<Self> { + let plugins_path = plugins_path.to_cstr(); let result = unsafe { BNCreateRepositoryManager(plugins_path.as_ref().as_ptr() as *const c_char) }; unsafe { Self::ref_from_raw(NonNull::new(result).unwrap()) } @@ -61,13 +61,9 @@ impl RepositoryManager { /// * `repository_path` - path to where the repository will be stored on disk locally /// /// Returns true if the repository was successfully added, false otherwise. - pub fn add_repository<U: BnStrCompatible, P: BnStrCompatible>( - &self, - url: U, - repository_path: P, - ) -> bool { - let url = url.into_bytes_with_nul(); - let repo_path = repository_path.into_bytes_with_nul(); + pub fn add_repository<U: AsCStr, P: AsCStr>(&self, url: U, repository_path: P) -> bool { + let url = url.to_cstr(); + let repo_path = repository_path.to_cstr(); unsafe { BNRepositoryManagerAddRepository( self.handle.as_ptr(), @@ -77,8 +73,8 @@ impl RepositoryManager { } } - pub fn repository_by_path<P: BnStrCompatible>(&self, path: P) -> Option<Repository> { - let path = path.into_bytes_with_nul(); + pub fn repository_by_path<P: AsCStr>(&self, path: P) -> Option<Repository> { + let path = path.to_cstr(); let result = unsafe { BNRepositoryGetRepositoryByPath( self.handle.as_ptr(), diff --git a/rust/src/secrets_provider.rs b/rust/src/secrets_provider.rs index 5f42dbea..7acf6d4b 100644 --- a/rust/src/secrets_provider.rs +++ b/rust/src/secrets_provider.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use std::ptr::NonNull; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; pub trait SecretsProvider { fn has_data(&mut self, key: &str) -> bool; @@ -27,7 +27,7 @@ impl CoreSecretsProvider { /// Register a new provider pub fn new<C: SecretsProvider>(name: &str, callback: C) -> Self { // SAFETY: once create SecretsProvider is never dropped - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let callback = Box::leak(Box::new(callback)); let mut callbacks = BNSecretsProviderCallbacks { context: callback as *mut C as *mut c_void, @@ -50,8 +50,8 @@ impl CoreSecretsProvider { } /// Retrieve a provider by name - pub fn by_name<S: BnStrCompatible>(name: S) -> Option<CoreSecretsProvider> { - let name = name.into_bytes_with_nul(); + pub fn by_name<S: AsCStr>(name: S) -> Option<CoreSecretsProvider> { + let name = name.to_cstr(); let result = unsafe { BNGetSecretsProviderByName(name.as_ref().as_ptr() as *const c_char) }; NonNull::new(result).map(|h| unsafe { Self::from_raw(h) }) } @@ -63,16 +63,16 @@ impl CoreSecretsProvider { } /// Check if data for a specific key exists, but do not retrieve it - pub fn has_data<S: BnStrCompatible>(&self, key: S) -> bool { - let key = key.into_bytes_with_nul(); + pub fn has_data<S: AsCStr>(&self, key: S) -> bool { + let key = key.to_cstr(); unsafe { BNSecretsProviderHasData(self.handle.as_ptr(), key.as_ref().as_ptr() as *const c_char) } } /// Retrieve data for the given key, if it exists - pub fn get_data<S: BnStrCompatible>(&self, key: S) -> String { - let key = key.into_bytes_with_nul(); + pub fn get_data<S: AsCStr>(&self, key: S) -> String { + let key = key.to_cstr(); let result = unsafe { BNGetSecretsProviderData(self.handle.as_ptr(), key.as_ref().as_ptr() as *const c_char) }; @@ -80,9 +80,9 @@ impl CoreSecretsProvider { } /// Store data with the given key - pub fn store_data<K: BnStrCompatible, V: BnStrCompatible>(&self, key: K, value: V) -> bool { - let key = key.into_bytes_with_nul(); - let value = value.into_bytes_with_nul(); + pub fn store_data<K: AsCStr, V: AsCStr>(&self, key: K, value: V) -> bool { + let key = key.to_cstr(); + let value = value.to_cstr(); unsafe { BNStoreSecretsProviderData( self.handle.as_ptr(), @@ -93,8 +93,8 @@ impl CoreSecretsProvider { } /// Delete stored data with the given key - pub fn delete_data<S: BnStrCompatible>(&self, key: S) -> bool { - let key = key.into_bytes_with_nul(); + pub fn delete_data<S: AsCStr>(&self, key: S) -> bool { + let key = key.to_cstr(); unsafe { BNDeleteSecretsProviderData( self.handle.as_ptr(), diff --git a/rust/src/section.rs b/rust/src/section.rs index 46a201d4..d1098e67 100644 --- a/rust/src/section.rs +++ b/rust/src/section.rs @@ -270,10 +270,10 @@ impl SectionBuilder { } pub(crate) fn create(self, view: &BinaryView) { - let name = self.name.into_bytes_with_nul(); - let ty = self.ty.into_bytes_with_nul(); - let linked_section = self.linked_section.into_bytes_with_nul(); - let info_section = self.info_section.into_bytes_with_nul(); + let name = self.name.to_cstr(); + let ty = self.ty.to_cstr(); + let linked_section = self.linked_section.to_cstr(); + let info_section = self.info_section.to_cstr(); let start = self.range.start; let len = self.range.end.wrapping_sub(start); diff --git a/rust/src/settings.rs b/rust/src/settings.rs index 4b4d418f..b49dbdea 100644 --- a/rust/src/settings.rs +++ b/rust/src/settings.rs @@ -20,7 +20,7 @@ use std::fmt::Debug; use crate::binary_view::BinaryView; use crate::rc::*; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use crate::function::Function; @@ -44,8 +44,8 @@ impl Settings { Self::new_with_id(GLOBAL_INSTANCE_ID) } - pub fn new_with_id<S: BnStrCompatible>(instance_id: S) -> Ref<Self> { - let instance_id = instance_id.into_bytes_with_nul(); + pub fn new_with_id<S: AsCStr>(instance_id: S) -> Ref<Self> { + let instance_id = instance_id.to_cstr(); unsafe { let handle = BNCreateSettings(instance_id.as_ref().as_ptr() as *mut _); debug_assert!(!handle.is_null()); @@ -53,8 +53,8 @@ impl Settings { } } - pub fn set_resource_id<S: BnStrCompatible>(&self, resource_id: S) { - let resource_id = resource_id.into_bytes_with_nul(); + pub fn set_resource_id<S: AsCStr>(&self, resource_id: S) { + let resource_id = resource_id.to_cstr(); unsafe { BNSettingsSetResourceId(self.handle, resource_id.as_ref().as_ptr() as *mut _) }; } @@ -62,16 +62,16 @@ impl Settings { unsafe { BnString::into_string(BNSettingsSerializeSchema(self.handle)) } } - pub fn deserialize_schema<S: BnStrCompatible>(&self, schema: S) -> bool { + pub fn deserialize_schema<S: AsCStr>(&self, schema: S) -> bool { self.deserialize_schema_with_scope(schema, SettingsScope::SettingsAutoScope) } - pub fn deserialize_schema_with_scope<S: BnStrCompatible>( + pub fn deserialize_schema_with_scope<S: AsCStr>( &self, schema: S, scope: SettingsScope, ) -> bool { - let schema = schema.into_bytes_with_nul(); + let schema = schema.to_cstr(); unsafe { BNSettingsDeserializeSchema( self.handle, @@ -82,8 +82,8 @@ impl Settings { } } - pub fn contains<S: BnStrCompatible>(&self, key: S) -> bool { - let key = key.into_bytes_with_nul(); + pub fn contains<S: AsCStr>(&self, key: S) -> bool { + let key = key.to_cstr(); unsafe { BNSettingsContains(self.handle, key.as_ref().as_ptr() as *mut _) } } @@ -97,16 +97,12 @@ impl Settings { // TODO Update the settings API to take an optional BinaryView or Function. Separate functions or...? - pub fn get_bool<S: BnStrCompatible>(&self, key: S) -> bool { + pub fn get_bool<S: AsCStr>(&self, key: S) -> bool { self.get_bool_with_opts(key, &mut QueryOptions::default()) } - pub fn get_bool_with_opts<S: BnStrCompatible>( - &self, - key: S, - options: &mut QueryOptions, - ) -> bool { - let key = key.into_bytes_with_nul(); + pub fn get_bool_with_opts<S: AsCStr>(&self, key: S, options: &mut QueryOptions) -> bool { + let key = key.to_cstr(); let view_ptr = match options.view.as_ref() { Some(view) => view.handle, _ => std::ptr::null_mut(), @@ -126,16 +122,12 @@ impl Settings { } } - pub fn get_double<S: BnStrCompatible>(&self, key: S) -> f64 { + pub fn get_double<S: AsCStr>(&self, key: S) -> f64 { self.get_double_with_opts(key, &mut QueryOptions::default()) } - pub fn get_double_with_opts<S: BnStrCompatible>( - &self, - key: S, - options: &mut QueryOptions, - ) -> f64 { - let key = key.into_bytes_with_nul(); + pub fn get_double_with_opts<S: AsCStr>(&self, key: S, options: &mut QueryOptions) -> f64 { + let key = key.to_cstr(); let view_ptr = match options.view.as_ref() { Some(view) => view.handle, _ => std::ptr::null_mut(), @@ -155,16 +147,12 @@ impl Settings { } } - pub fn get_integer<S: BnStrCompatible>(&self, key: S) -> u64 { + pub fn get_integer<S: AsCStr>(&self, key: S) -> u64 { self.get_integer_with_opts(key, &mut QueryOptions::default()) } - pub fn get_integer_with_opts<S: BnStrCompatible>( - &self, - key: S, - options: &mut QueryOptions, - ) -> u64 { - let key = key.into_bytes_with_nul(); + pub fn get_integer_with_opts<S: AsCStr>(&self, key: S, options: &mut QueryOptions) -> u64 { + let key = key.to_cstr(); let view_ptr = match options.view.as_ref() { Some(view) => view.handle, _ => std::ptr::null_mut(), @@ -184,16 +172,12 @@ impl Settings { } } - pub fn get_string<S: BnStrCompatible>(&self, key: S) -> String { + pub fn get_string<S: AsCStr>(&self, key: S) -> String { self.get_string_with_opts(key, &mut QueryOptions::default()) } - pub fn get_string_with_opts<S: BnStrCompatible>( - &self, - key: S, - options: &mut QueryOptions, - ) -> String { - let key = key.into_bytes_with_nul(); + pub fn get_string_with_opts<S: AsCStr>(&self, key: S, options: &mut QueryOptions) -> String { + let key = key.to_cstr(); let view_ptr = match options.view.as_ref() { Some(view) => view.handle, _ => std::ptr::null_mut(), @@ -213,16 +197,16 @@ impl Settings { } } - pub fn get_string_list<S: BnStrCompatible>(&self, key: S) -> Array<BnString> { + pub fn get_string_list<S: AsCStr>(&self, key: S) -> Array<BnString> { self.get_string_list_with_opts(key, &mut QueryOptions::default()) } - pub fn get_string_list_with_opts<S: BnStrCompatible>( + pub fn get_string_list_with_opts<S: AsCStr>( &self, key: S, options: &mut QueryOptions, ) -> Array<BnString> { - let key = key.into_bytes_with_nul(); + let key = key.to_cstr(); let view_ptr = match options.view.as_ref() { Some(view) => view.handle, _ => std::ptr::null_mut(), @@ -248,16 +232,12 @@ impl Settings { } } - pub fn get_json<S: BnStrCompatible>(&self, key: S) -> String { + pub fn get_json<S: AsCStr>(&self, key: S) -> String { self.get_json_with_opts(key, &mut QueryOptions::default()) } - pub fn get_json_with_opts<S: BnStrCompatible>( - &self, - key: S, - options: &mut QueryOptions, - ) -> String { - let key = key.into_bytes_with_nul(); + pub fn get_json_with_opts<S: AsCStr>(&self, key: S, options: &mut QueryOptions) -> String { + let key = key.to_cstr(); let view_ptr = match options.view.as_ref() { Some(view) => view.handle, _ => std::ptr::null_mut(), @@ -277,17 +257,12 @@ impl Settings { } } - pub fn set_bool<S: BnStrCompatible>(&self, key: S, value: bool) { + pub fn set_bool<S: AsCStr>(&self, key: S, value: bool) { self.set_bool_with_opts(key, value, &QueryOptions::default()) } - pub fn set_bool_with_opts<S: BnStrCompatible>( - &self, - key: S, - value: bool, - options: &QueryOptions, - ) { - let key = key.into_bytes_with_nul(); + pub fn set_bool_with_opts<S: AsCStr>(&self, key: S, value: bool, options: &QueryOptions) { + let key = key.to_cstr(); let view_ptr = match options.view.as_ref() { Some(view) => view.handle, _ => std::ptr::null_mut(), @@ -308,16 +283,11 @@ impl Settings { } } - pub fn set_double<S: BnStrCompatible>(&self, key: S, value: f64) { + pub fn set_double<S: AsCStr>(&self, key: S, value: f64) { self.set_double_with_opts(key, value, &QueryOptions::default()) } - pub fn set_double_with_opts<S: BnStrCompatible>( - &self, - key: S, - value: f64, - options: &QueryOptions, - ) { - let key = key.into_bytes_with_nul(); + pub fn set_double_with_opts<S: AsCStr>(&self, key: S, value: f64, options: &QueryOptions) { + let key = key.to_cstr(); let view_ptr = match options.view.as_ref() { Some(view) => view.handle, _ => std::ptr::null_mut(), @@ -338,17 +308,12 @@ impl Settings { } } - pub fn set_integer<S: BnStrCompatible>(&self, key: S, value: u64) { + pub fn set_integer<S: AsCStr>(&self, key: S, value: u64) { self.set_integer_with_opts(key, value, &QueryOptions::default()) } - pub fn set_integer_with_opts<S: BnStrCompatible>( - &self, - key: S, - value: u64, - options: &QueryOptions, - ) { - let key = key.into_bytes_with_nul(); + pub fn set_integer_with_opts<S: AsCStr>(&self, key: S, value: u64, options: &QueryOptions) { + let key = key.to_cstr(); let view_ptr = match options.view.as_ref() { Some(view) => view.handle, _ => std::ptr::null_mut(), @@ -369,18 +334,18 @@ impl Settings { } } - pub fn set_string<S1: BnStrCompatible, S2: BnStrCompatible>(&self, key: S1, value: S2) { + pub fn set_string<S1: AsCStr, S2: AsCStr>(&self, key: S1, value: S2) { self.set_string_with_opts(key, value, &QueryOptions::default()) } - pub fn set_string_with_opts<S1: BnStrCompatible, S2: BnStrCompatible>( + pub fn set_string_with_opts<S1: AsCStr, S2: AsCStr>( &self, key: S1, value: S2, options: &QueryOptions, ) { - let key = key.into_bytes_with_nul(); - let value = value.into_bytes_with_nul(); + let key = key.to_cstr(); + let value = value.to_cstr(); let view_ptr = match options.view.as_ref() { Some(view) => view.handle, _ => std::ptr::null_mut(), @@ -401,7 +366,7 @@ impl Settings { } } - pub fn set_string_list<S1: BnStrCompatible, S2: BnStrCompatible, I: Iterator<Item = S2>>( + pub fn set_string_list<S1: AsCStr, S2: AsCStr, I: Iterator<Item = S2>>( &self, key: S1, value: I, @@ -409,18 +374,14 @@ impl Settings { self.set_string_list_with_opts(key, value, &QueryOptions::default()) } - pub fn set_string_list_with_opts< - S1: BnStrCompatible, - S2: BnStrCompatible, - I: Iterator<Item = S2>, - >( + pub fn set_string_list_with_opts<S1: AsCStr, S2: AsCStr, I: Iterator<Item = S2>>( &self, key: S1, value: I, options: &QueryOptions, ) -> bool { - let key = key.into_bytes_with_nul(); - let raw_list: Vec<_> = value.map(|s| s.into_bytes_with_nul()).collect(); + let key = key.to_cstr(); + let raw_list: Vec<_> = value.map(|s| s.to_cstr()).collect(); let mut raw_list_ptr: Vec<_> = raw_list .iter() .map(|s| s.as_ref().as_ptr() as *const c_char) @@ -447,18 +408,18 @@ impl Settings { } } - pub fn set_json<S1: BnStrCompatible, S2: BnStrCompatible>(&self, key: S1, value: S2) -> bool { + pub fn set_json<S1: AsCStr, S2: AsCStr>(&self, key: S1, value: S2) -> bool { self.set_json_with_opts(key, value, &QueryOptions::default()) } - pub fn set_json_with_opts<S1: BnStrCompatible, S2: BnStrCompatible>( + pub fn set_json_with_opts<S1: AsCStr, S2: AsCStr>( &self, key: S1, value: S2, options: &QueryOptions, ) -> bool { - let key = key.into_bytes_with_nul(); - let value = value.into_bytes_with_nul(); + let key = key.to_cstr(); + let value = value.to_cstr(); let view_ptr = match options.view.as_ref() { Some(view) => view.handle, _ => std::ptr::null_mut(), @@ -479,9 +440,9 @@ impl Settings { } } - pub fn get_property_string<S: BnStrCompatible>(&self, key: S, property: S) -> String { - let key = key.into_bytes_with_nul(); - let property = property.into_bytes_with_nul(); + pub fn get_property_string<S: AsCStr>(&self, key: S, property: S) -> String { + let key = key.to_cstr(); + let property = property.to_cstr(); unsafe { BnString::into_string(BNSettingsQueryPropertyString( self.handle, @@ -491,13 +452,9 @@ impl Settings { } } - pub fn get_property_string_list<S: BnStrCompatible>( - &self, - key: S, - property: S, - ) -> Array<BnString> { - let key = key.into_bytes_with_nul(); - let property = property.into_bytes_with_nul(); + pub fn get_property_string_list<S: AsCStr>(&self, key: S, property: S) -> Array<BnString> { + let key = key.to_cstr(); + let property = property.to_cstr(); let mut size: usize = 0; unsafe { Array::new( @@ -513,9 +470,9 @@ impl Settings { } } - pub fn update_bool_property<S: BnStrCompatible>(&self, key: S, property: S, value: bool) { - let key = key.into_bytes_with_nul(); - let property = property.into_bytes_with_nul(); + pub fn update_bool_property<S: AsCStr>(&self, key: S, property: S, value: bool) { + let key = key.to_cstr(); + let property = property.to_cstr(); unsafe { BNSettingsUpdateBoolProperty( self.handle, @@ -526,9 +483,9 @@ impl Settings { } } - pub fn update_integer_property<S: BnStrCompatible>(&self, key: S, property: S, value: u64) { - let key = key.into_bytes_with_nul(); - let property = property.into_bytes_with_nul(); + pub fn update_integer_property<S: AsCStr>(&self, key: S, property: S, value: u64) { + let key = key.to_cstr(); + let property = property.to_cstr(); unsafe { BNSettingsUpdateUInt64Property( self.handle, @@ -539,9 +496,9 @@ impl Settings { } } - pub fn update_double_property<S: BnStrCompatible>(&self, key: S, property: S, value: f64) { - let key = key.into_bytes_with_nul(); - let property = property.into_bytes_with_nul(); + pub fn update_double_property<S: AsCStr>(&self, key: S, property: S, value: f64) { + let key = key.to_cstr(); + let property = property.to_cstr(); unsafe { BNSettingsUpdateDoubleProperty( self.handle, @@ -552,10 +509,10 @@ impl Settings { } } - pub fn update_string_property<S: BnStrCompatible>(&self, key: S, property: S, value: S) { - let key = key.into_bytes_with_nul(); - let property = property.into_bytes_with_nul(); - let value = value.into_bytes_with_nul(); + pub fn update_string_property<S: AsCStr>(&self, key: S, property: S, value: S) { + let key = key.to_cstr(); + let property = property.to_cstr(); + let value = value.to_cstr(); unsafe { BNSettingsUpdateStringProperty( self.handle, @@ -566,15 +523,15 @@ impl Settings { } } - pub fn update_string_list_property<S: BnStrCompatible, I: Iterator<Item = S>>( + pub fn update_string_list_property<S: AsCStr, I: Iterator<Item = S>>( &self, key: S, property: S, value: I, ) { - let key = key.into_bytes_with_nul(); - let property = property.into_bytes_with_nul(); - let raw_list: Vec<_> = value.map(|s| s.into_bytes_with_nul()).collect(); + let key = key.to_cstr(); + let property = property.to_cstr(); + let raw_list: Vec<_> = value.map(|s| s.to_cstr()).collect(); let mut raw_list_ptr: Vec<_> = raw_list .iter() .map(|s| s.as_ref().as_ptr() as *const c_char) @@ -591,13 +548,9 @@ impl Settings { } } - pub fn register_group<S1: BnStrCompatible, S2: BnStrCompatible>( - &self, - group: S1, - title: S2, - ) -> bool { - let group = group.into_bytes_with_nul(); - let title = title.into_bytes_with_nul(); + pub fn register_group<S1: AsCStr, S2: AsCStr>(&self, group: S1, title: S2) -> bool { + let group = group.to_cstr(); + let title = title.to_cstr(); unsafe { BNSettingsRegisterGroup( @@ -608,13 +561,9 @@ impl Settings { } } - pub fn register_setting_json<S1: BnStrCompatible, S2: BnStrCompatible>( - &self, - group: S1, - properties: S2, - ) -> bool { - let group = group.into_bytes_with_nul(); - let properties = properties.into_bytes_with_nul(); + pub fn register_setting_json<S1: AsCStr, S2: AsCStr>(&self, group: S1, properties: S2) -> bool { + let group = group.to_cstr(); + let properties = properties.to_cstr(); unsafe { BNSettingsRegisterSetting( diff --git a/rust/src/string.rs b/rust/src/string.rs index 5bd871f9..17fcf911 100644 --- a/rust/src/string.rs +++ b/rust/src/string.rs @@ -44,29 +44,27 @@ pub(crate) fn strings_to_string_list(strings: &[String]) -> *mut *mut c_char { unsafe { BNAllocStringList(raw_str_list.as_mut_ptr(), raw_str_list.len()) } } -/// Is the equivalent of `core::ffi::CString` but using the alloc and free from `binaryninjacore-sys`. +/// A nul-terminated C string allocated by the core. +/// +/// Received from a variety of core function calls, and must be used when giving strings to the +/// core from many core-invoked callbacks, or otherwise passing ownership of the string to the core. +/// +/// These are strings we're responsible for freeing, such as strings allocated by the core and +/// given to us through the API and then forgotten about by the core. +/// +/// When passing to the core, make sure to use [`BnString::to_cstr`] and [`CStr::as_ptr`]. +/// +/// When giving ownership to the core, make sure to prevent dropping by calling [`BnString::into_raw`]. #[repr(transparent)] pub struct BnString { raw: *mut c_char, } -/// A nul-terminated C string allocated by the core. -/// -/// Received from a variety of core function calls, and -/// must be used when giving strings to the core from many -/// core-invoked callbacks. -/// -/// These are strings we're responsible for freeing, such as -/// strings allocated by the core and given to us through the API -/// and then forgotten about by the core. impl BnString { - pub fn new<S: BnStrCompatible>(s: S) -> Self { + pub fn new<S: AsCStr>(s: S) -> Self { use binaryninjacore_sys::BNAllocString; - let raw = s.into_bytes_with_nul(); - unsafe { - let ptr = raw.as_ref().as_ptr() as *mut _; - Self::from_raw(BNAllocString(ptr)) - } + let raw = s.to_cstr(); + unsafe { Self::from_raw(BNAllocString(raw.as_ptr())) } } /// Take an owned core string and convert it to [`String`]. @@ -190,118 +188,116 @@ unsafe impl CoreArrayProviderInner for BnString { } } -pub unsafe trait BnStrCompatible { - type Result: AsRef<[u8]>; +pub unsafe trait AsCStr { + type Result: Deref<Target = CStr>; - fn into_bytes_with_nul(self) -> Self::Result; + fn to_cstr(self) -> Self::Result; } -unsafe impl<'a> BnStrCompatible for &'a CStr { - type Result = &'a [u8]; +unsafe impl<'a> AsCStr for &'a CStr { + type Result = Self; - fn into_bytes_with_nul(self) -> Self::Result { - self.to_bytes_with_nul() + fn to_cstr(self) -> Self::Result { + self } } -unsafe impl BnStrCompatible for BnString { +unsafe impl AsCStr for BnString { type Result = Self; - fn into_bytes_with_nul(self) -> Self::Result { + fn to_cstr(self) -> Self::Result { self } } -unsafe impl BnStrCompatible for &BnString { - type Result = Self; +unsafe impl AsCStr for &BnString { + type Result = BnString; - fn into_bytes_with_nul(self) -> Self::Result { - self + fn to_cstr(self) -> Self::Result { + self.clone() } } -unsafe impl BnStrCompatible for CString { - type Result = Vec<u8>; +unsafe impl AsCStr for CString { + type Result = Self; - fn into_bytes_with_nul(self) -> Self::Result { - self.into_bytes_with_nul() + fn to_cstr(self) -> Self::Result { + self } } -unsafe impl BnStrCompatible for &str { - type Result = Vec<u8>; +unsafe impl AsCStr for &str { + type Result = CString; - fn into_bytes_with_nul(self) -> Self::Result { - let ret = CString::new(self).expect("can't pass strings with internal nul bytes to core!"); - ret.into_bytes_with_nul() + fn to_cstr(self) -> Self::Result { + CString::new(self).expect("can't pass strings with internal nul bytes to core!") } } -unsafe impl BnStrCompatible for String { - type Result = Vec<u8>; +unsafe impl AsCStr for String { + type Result = CString; - fn into_bytes_with_nul(self) -> Self::Result { - self.as_str().into_bytes_with_nul() + fn to_cstr(self) -> Self::Result { + CString::new(self).expect("can't pass strings with internal nul bytes to core!") } } -unsafe impl BnStrCompatible for &String { - type Result = Vec<u8>; +unsafe impl AsCStr for &String { + type Result = CString; - fn into_bytes_with_nul(self) -> Self::Result { - self.as_str().into_bytes_with_nul() + fn to_cstr(self) -> Self::Result { + self.clone().to_cstr() } } -unsafe impl<'a> BnStrCompatible for &'a Cow<'a, str> { - type Result = Vec<u8>; +unsafe impl<'a> AsCStr for &'a Cow<'a, str> { + type Result = CString; - fn into_bytes_with_nul(self) -> Self::Result { - self.to_string().into_bytes_with_nul() + fn to_cstr(self) -> Self::Result { + self.to_string().to_cstr() } } -unsafe impl BnStrCompatible for Cow<'_, str> { - type Result = Vec<u8>; +unsafe impl AsCStr for Cow<'_, str> { + type Result = CString; - fn into_bytes_with_nul(self) -> Self::Result { - self.to_string().into_bytes_with_nul() + fn to_cstr(self) -> Self::Result { + self.to_string().to_cstr() } } -unsafe impl BnStrCompatible for &QualifiedName { - type Result = Vec<u8>; +unsafe impl AsCStr for &QualifiedName { + type Result = CString; - fn into_bytes_with_nul(self) -> Self::Result { - self.to_string().into_bytes_with_nul() + fn to_cstr(self) -> Self::Result { + self.to_string().to_cstr() } } -unsafe impl BnStrCompatible for PathBuf { - type Result = Vec<u8>; +unsafe impl AsCStr for PathBuf { + type Result = CString; - fn into_bytes_with_nul(self) -> Self::Result { - self.as_path().into_bytes_with_nul() + fn to_cstr(self) -> Self::Result { + self.as_path().to_cstr() } } -unsafe impl BnStrCompatible for &Path { - type Result = Vec<u8>; +unsafe impl AsCStr for &Path { + type Result = CString; - fn into_bytes_with_nul(self) -> Self::Result { - let ret = CString::new(self.as_os_str().as_encoded_bytes()) - .expect("can't pass paths with internal nul bytes to core!"); - ret.into_bytes_with_nul() + fn to_cstr(self) -> Self::Result { + CString::new(self.as_os_str().as_encoded_bytes()) + .expect("can't pass paths with internal nul bytes to core!") } } pub trait IntoJson { - type Output: BnStrCompatible; + type Output: AsCStr; fn get_json_string(self) -> Result<Self::Output, ()>; } -impl<S: BnStrCompatible> IntoJson for S { +impl<S: AsCStr> IntoJson for S { type Output = S; fn get_json_string(self) -> Result<Self::Output, ()> { diff --git a/rust/src/symbol.rs b/rust/src/symbol.rs index 2ff92db5..b06a0f2f 100644 --- a/rust/src/symbol.rs +++ b/rust/src/symbol.rs @@ -153,9 +153,9 @@ impl SymbolBuilder { } pub fn create(self) -> Ref<Symbol> { - let raw_name = self.raw_name.into_bytes_with_nul(); - let short_name = self.short_name.map(|s| s.into_bytes_with_nul()); - let full_name = self.full_name.map(|s| s.into_bytes_with_nul()); + let raw_name = self.raw_name.to_cstr(); + let short_name = self.short_name.map(|s| s.to_cstr()); + let full_name = self.full_name.map(|s| s.to_cstr()); // Lifetimes, man let raw_name = raw_name.as_ptr() as _; diff --git a/rust/src/tags.rs b/rust/src/tags.rs index 63c3634a..30cc4682 100644 --- a/rust/src/tags.rs +++ b/rust/src/tags.rs @@ -42,8 +42,8 @@ impl Tag { Ref::new(Self { handle }) } - pub fn new<S: BnStrCompatible>(t: &TagType, data: S) -> Ref<Self> { - let data = data.into_bytes_with_nul(); + pub fn new<S: AsCStr>(t: &TagType, data: S) -> Ref<Self> { + let data = data.to_cstr(); unsafe { Self::ref_from_raw(BNCreateTag(t.handle, data.as_ref().as_ptr() as *mut _)) } } @@ -59,8 +59,8 @@ impl Tag { unsafe { TagType::ref_from_raw(BNTagGetType(self.handle)) } } - pub fn set_data<S: BnStrCompatible>(&self, data: S) { - let data = data.into_bytes_with_nul(); + pub fn set_data<S: AsCStr>(&self, data: S) { + let data = data.to_cstr(); unsafe { BNTagSetData(self.handle, data.as_ref().as_ptr() as *mut _); } @@ -134,11 +134,7 @@ impl TagType { Ref::new(Self { handle }) } - pub fn create<N: BnStrCompatible, I: BnStrCompatible>( - view: &BinaryView, - name: N, - icon: I, - ) -> Ref<Self> { + pub fn create<N: AsCStr, I: AsCStr>(view: &BinaryView, name: N, icon: I) -> Ref<Self> { let tag_type = unsafe { Self::ref_from_raw(BNCreateTagType(view.handle)) }; tag_type.set_name(name); tag_type.set_icon(icon); @@ -153,8 +149,8 @@ impl TagType { unsafe { BnString::into_string(BNTagTypeGetIcon(self.handle)) } } - pub fn set_icon<S: BnStrCompatible>(&self, icon: S) { - let icon = icon.into_bytes_with_nul(); + pub fn set_icon<S: AsCStr>(&self, icon: S) { + let icon = icon.to_cstr(); unsafe { BNTagTypeSetIcon(self.handle, icon.as_ref().as_ptr() as *mut _); } @@ -164,8 +160,8 @@ impl TagType { unsafe { BnString::into_string(BNTagTypeGetName(self.handle)) } } - pub fn set_name<S: BnStrCompatible>(&self, name: S) { - let name = name.into_bytes_with_nul(); + pub fn set_name<S: AsCStr>(&self, name: S) { + let name = name.to_cstr(); unsafe { BNTagTypeSetName(self.handle, name.as_ref().as_ptr() as *mut _); } @@ -183,8 +179,8 @@ impl TagType { unsafe { BNTagTypeGetType(self.handle) } } - pub fn set_type<S: BnStrCompatible>(&self, t: S) { - let t = t.into_bytes_with_nul(); + pub fn set_type<S: AsCStr>(&self, t: S) { + let t = t.to_cstr(); unsafe { BNTagTypeSetName(self.handle, t.as_ref().as_ptr() as *mut _); } diff --git a/rust/src/template_simplifier.rs b/rust/src/template_simplifier.rs index dd815f69..57d2b0b4 100644 --- a/rust/src/template_simplifier.rs +++ b/rust/src/template_simplifier.rs @@ -1,16 +1,16 @@ use crate::{ - string::{BnStrCompatible, BnString}, + string::{AsCStr, BnString}, types::QualifiedName, }; use binaryninjacore_sys::{BNRustSimplifyStrToFQN, BNRustSimplifyStrToStr}; -pub fn simplify_str_to_str<S: BnStrCompatible>(input: S) -> BnString { - let name = input.into_bytes_with_nul(); +pub fn simplify_str_to_str<S: AsCStr>(input: S) -> BnString { + let name = input.to_cstr(); unsafe { BnString::from_raw(BNRustSimplifyStrToStr(name.as_ref().as_ptr() as *mut _)) } } -pub fn simplify_str_to_fqn<S: BnStrCompatible>(input: S, simplify: bool) -> QualifiedName { - let name = input.into_bytes_with_nul(); +pub fn simplify_str_to_fqn<S: AsCStr>(input: S, simplify: bool) -> QualifiedName { + let name = input.to_cstr(); unsafe { QualifiedName::from_owned_raw(BNRustSimplifyStrToFQN( name.as_ref().as_ptr() as *mut _, diff --git a/rust/src/type_archive.rs b/rust/src/type_archive.rs index ee4bc276..5e94f19e 100644 --- a/rust/src/type_archive.rs +++ b/rust/src/type_archive.rs @@ -10,7 +10,7 @@ use crate::data_buffer::DataBuffer; use crate::metadata::Metadata; use crate::platform::Platform; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{raw_to_string, BnStrCompatible, BnString}; +use crate::string::{raw_to_string, AsCStr, BnString}; use crate::type_container::TypeContainer; use crate::types::{QualifiedName, QualifiedNameAndType, QualifiedNameTypeAndId, Type}; @@ -65,7 +65,7 @@ impl TypeArchive { /// Open the Type Archive at the given path, if it exists. pub fn open(path: impl AsRef<Path>) -> Option<Ref<TypeArchive>> { - let raw_path = path.as_ref().into_bytes_with_nul(); + let raw_path = path.as_ref().to_cstr(); let handle = unsafe { BNOpenTypeArchive(raw_path.as_ptr() as *const c_char) }; NonNull::new(handle).map(|handle| unsafe { TypeArchive::ref_from_raw(handle) }) } @@ -74,7 +74,7 @@ impl TypeArchive { /// /// If the file has already been created and is not a valid type archive this will return `None`. pub fn create(path: impl AsRef<Path>, platform: &Platform) -> Option<Ref<TypeArchive>> { - let raw_path = path.as_ref().into_bytes_with_nul(); + let raw_path = path.as_ref().to_cstr(); let handle = unsafe { BNCreateTypeArchive(raw_path.as_ptr() as *const c_char, platform.handle) }; NonNull::new(handle).map(|handle| unsafe { TypeArchive::ref_from_raw(handle) }) @@ -83,13 +83,13 @@ impl TypeArchive { /// Create a Type Archive at the given path and id, returning None if it could not be created. /// /// If the file has already been created and is not a valid type archive this will return `None`. - pub fn create_with_id<I: BnStrCompatible>( + pub fn create_with_id<I: AsCStr>( path: impl AsRef<Path>, id: I, platform: &Platform, ) -> Option<Ref<TypeArchive>> { - let raw_path = path.as_ref().into_bytes_with_nul(); - let id = id.into_bytes_with_nul(); + let raw_path = path.as_ref().to_cstr(); + let id = id.to_cstr(); let handle = unsafe { BNCreateTypeArchiveWithId( raw_path.as_ptr() as *const c_char, @@ -101,8 +101,8 @@ impl TypeArchive { } /// Get a reference to the Type Archive with the known id, if one exists. - pub fn lookup_by_id<S: BnStrCompatible>(id: S) -> Option<Ref<TypeArchive>> { - let id = id.into_bytes_with_nul(); + pub fn lookup_by_id<S: AsCStr>(id: S) -> Option<Ref<TypeArchive>> { + let id = id.to_cstr(); let handle = unsafe { BNLookupTypeArchiveById(id.as_ref().as_ptr() as *const c_char) }; NonNull::new(handle).map(|handle| unsafe { TypeArchive::ref_from_raw(handle) }) } @@ -156,7 +156,7 @@ impl TypeArchive { } /// Get the ids of the parents to the given snapshot - pub fn get_snapshot_parent_ids<S: BnStrCompatible>( + pub fn get_snapshot_parent_ids<S: AsCStr>( &self, snapshot: &TypeArchiveSnapshotId, ) -> Option<Array<BnString>> { @@ -172,7 +172,7 @@ impl TypeArchive { } /// Get the ids of the children to the given snapshot - pub fn get_snapshot_child_ids<S: BnStrCompatible>( + pub fn get_snapshot_child_ids<S: AsCStr>( &self, snapshot: &TypeArchiveSnapshotId, ) -> Option<Array<BnString>> { @@ -235,8 +235,8 @@ impl TypeArchive { /// /// * `id` - Old id of type in archive /// * `new_name` - New type name - pub fn rename_type_by_id<S: BnStrCompatible>(&self, id: S, new_name: QualifiedName) -> bool { - let id = id.into_bytes_with_nul(); + pub fn rename_type_by_id<S: AsCStr>(&self, id: S, new_name: QualifiedName) -> bool { + let id = id.to_cstr(); let raw_name = QualifiedName::into_raw(new_name); let result = unsafe { BNRenameTypeArchiveType( @@ -259,8 +259,8 @@ impl TypeArchive { } /// Delete an existing type in the type archive. - pub fn delete_type_by_id<S: BnStrCompatible>(&self, id: S) -> bool { - let id = id.into_bytes_with_nul(); + pub fn delete_type_by_id<S: AsCStr>(&self, id: S) -> bool { + let id = id.to_cstr(); let result = unsafe { BNDeleteTypeArchiveType(self.handle.as_ptr(), id.as_ref().as_ptr() as *const c_char) }; @@ -270,7 +270,7 @@ impl TypeArchive { /// Retrieve a stored type in the archive /// /// * `name` - Type name - pub fn get_type_by_name<S: BnStrCompatible>(&self, name: QualifiedName) -> Option<Ref<Type>> { + pub fn get_type_by_name<S: AsCStr>(&self, name: QualifiedName) -> Option<Ref<Type>> { self.get_type_by_name_from_snapshot(name, &TypeArchiveSnapshotId::unset()) } @@ -298,7 +298,7 @@ impl TypeArchive { /// Retrieve a stored type in the archive by id /// /// * `id` - Type id - pub fn get_type_by_id<I: BnStrCompatible>(&self, id: I) -> Option<Ref<Type>> { + pub fn get_type_by_id<I: AsCStr>(&self, id: I) -> Option<Ref<Type>> { self.get_type_by_id_from_snapshot(id, &TypeArchiveSnapshotId::unset()) } @@ -306,12 +306,12 @@ impl TypeArchive { /// /// * `id` - Type id /// * `snapshot` - Snapshot id to search for types - pub fn get_type_by_id_from_snapshot<I: BnStrCompatible>( + pub fn get_type_by_id_from_snapshot<I: AsCStr>( &self, id: I, snapshot: &TypeArchiveSnapshotId, ) -> Option<Ref<Type>> { - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let result = unsafe { BNGetTypeArchiveTypeById( self.handle.as_ptr(), @@ -325,7 +325,7 @@ impl TypeArchive { /// Retrieve a type's name by its id /// /// * `id` - Type id - pub fn get_type_name_by_id<I: BnStrCompatible>(&self, id: I) -> QualifiedName { + pub fn get_type_name_by_id<I: AsCStr>(&self, id: I) -> QualifiedName { self.get_type_name_by_id_from_snapshot(id, &TypeArchiveSnapshotId::unset()) } @@ -333,12 +333,12 @@ impl TypeArchive { /// /// * `id` - Type id /// * `snapshot` - Snapshot id to search for types - pub fn get_type_name_by_id_from_snapshot<I: BnStrCompatible>( + pub fn get_type_name_by_id_from_snapshot<I: AsCStr>( &self, id: I, snapshot: &TypeArchiveSnapshotId, ) -> QualifiedName { - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let result = unsafe { BNGetTypeArchiveTypeName( self.handle.as_ptr(), @@ -479,7 +479,7 @@ impl TypeArchive { /// Get all types a given type references directly /// /// * `id` - Source type id - pub fn get_outgoing_direct_references<I: BnStrCompatible>(&self, id: I) -> Array<BnString> { + pub fn get_outgoing_direct_references<I: AsCStr>(&self, id: I) -> Array<BnString> { self.get_outgoing_direct_references_from_snapshot(id, &TypeArchiveSnapshotId::unset()) } @@ -487,12 +487,12 @@ impl TypeArchive { /// /// * `id` - Source type id /// * `snapshot` - Snapshot id to search for types - pub fn get_outgoing_direct_references_from_snapshot<I: BnStrCompatible>( + pub fn get_outgoing_direct_references_from_snapshot<I: AsCStr>( &self, id: I, snapshot: &TypeArchiveSnapshotId, ) -> Array<BnString> { - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let mut count = 0; let result = unsafe { BNGetTypeArchiveOutgoingDirectTypeReferences( @@ -509,7 +509,7 @@ impl TypeArchive { /// Get all types a given type references, and any types that the referenced types reference /// /// * `id` - Source type id - pub fn get_outgoing_recursive_references<I: BnStrCompatible>(&self, id: I) -> Array<BnString> { + pub fn get_outgoing_recursive_references<I: AsCStr>(&self, id: I) -> Array<BnString> { self.get_outgoing_recursive_references_from_snapshot(id, &TypeArchiveSnapshotId::unset()) } @@ -517,12 +517,12 @@ impl TypeArchive { /// /// * `id` - Source type id /// * `snapshot` - Snapshot id to search for types - pub fn get_outgoing_recursive_references_from_snapshot<I: BnStrCompatible>( + pub fn get_outgoing_recursive_references_from_snapshot<I: AsCStr>( &self, id: I, snapshot: &TypeArchiveSnapshotId, ) -> Array<BnString> { - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let mut count = 0; let result = unsafe { BNGetTypeArchiveOutgoingRecursiveTypeReferences( @@ -539,7 +539,7 @@ impl TypeArchive { /// Get all types that reference a given type /// /// * `id` - Target type id - pub fn get_incoming_direct_references<I: BnStrCompatible>(&self, id: I) -> Array<BnString> { + pub fn get_incoming_direct_references<I: AsCStr>(&self, id: I) -> Array<BnString> { self.get_incoming_direct_references_with_snapshot(id, &TypeArchiveSnapshotId::unset()) } @@ -547,12 +547,12 @@ impl TypeArchive { /// /// * `id` - Target type id /// * `snapshot` - Snapshot id to search for types - pub fn get_incoming_direct_references_with_snapshot<I: BnStrCompatible>( + pub fn get_incoming_direct_references_with_snapshot<I: AsCStr>( &self, id: I, snapshot: &TypeArchiveSnapshotId, ) -> Array<BnString> { - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let mut count = 0; let result = unsafe { BNGetTypeArchiveIncomingDirectTypeReferences( @@ -569,7 +569,7 @@ impl TypeArchive { /// Get all types that reference a given type, and all types that reference them, recursively /// /// * `id` - Target type id - pub fn get_incoming_recursive_references<I: BnStrCompatible>(&self, id: I) -> Array<BnString> { + pub fn get_incoming_recursive_references<I: AsCStr>(&self, id: I) -> Array<BnString> { self.get_incoming_recursive_references_with_snapshot(id, &TypeArchiveSnapshotId::unset()) } @@ -577,12 +577,12 @@ impl TypeArchive { /// /// * `id` - Target type id /// * `snapshot` - Snapshot id to search for types, or empty string to search the latest snapshot - pub fn get_incoming_recursive_references_with_snapshot<I: BnStrCompatible>( + pub fn get_incoming_recursive_references_with_snapshot<I: AsCStr>( &self, id: I, snapshot: &TypeArchiveSnapshotId, ) -> Array<BnString> { - let id = id.into_bytes_with_nul(); + let id = id.to_cstr(); let mut count = 0; let result = unsafe { BNGetTypeArchiveIncomingRecursiveTypeReferences( @@ -597,8 +597,8 @@ impl TypeArchive { } /// Look up a metadata entry in the archive - pub fn query_metadata<S: BnStrCompatible>(&self, key: S) -> Option<Ref<Metadata>> { - let key = key.into_bytes_with_nul(); + pub fn query_metadata<S: AsCStr>(&self, key: S) -> Option<Ref<Metadata>> { + let key = key.to_cstr(); let result = unsafe { BNTypeArchiveQueryMetadata(self.handle.as_ptr(), key.as_ref().as_ptr() as *const c_char) }; @@ -609,8 +609,8 @@ impl TypeArchive { /// /// * `key` - key value to associate the Metadata object with /// * `md` - object to store. - pub fn store_metadata<S: BnStrCompatible>(&self, key: S, md: &Metadata) { - let key = key.into_bytes_with_nul(); + pub fn store_metadata<S: AsCStr>(&self, key: S, md: &Metadata) { + let key = key.to_cstr(); let result = unsafe { BNTypeArchiveStoreMetadata( self.handle.as_ptr(), @@ -622,8 +622,8 @@ impl TypeArchive { } /// Delete a given metadata entry in the archive from the `key` - pub fn remove_metadata<S: BnStrCompatible>(&self, key: S) -> bool { - let key = key.into_bytes_with_nul(); + pub fn remove_metadata<S: AsCStr>(&self, key: S) -> bool { + let key = key.to_cstr(); unsafe { BNTypeArchiveRemoveMetadata( self.handle.as_ptr(), @@ -633,10 +633,7 @@ impl TypeArchive { } /// Turn a given `snapshot` id into a data stream - pub fn serialize_snapshot<S: BnStrCompatible>( - &self, - snapshot: &TypeArchiveSnapshotId, - ) -> DataBuffer { + pub fn serialize_snapshot<S: AsCStr>(&self, snapshot: &TypeArchiveSnapshotId) -> DataBuffer { let result = unsafe { BNTypeArchiveSerializeSnapshot( self.handle.as_ptr(), @@ -709,8 +706,8 @@ impl TypeArchive { // TODO: Make this AsRef<Path>? /// Determine if `file` is a Type Archive - pub fn is_type_archive<P: BnStrCompatible>(file: P) -> bool { - let file = file.into_bytes_with_nul(); + pub fn is_type_archive<P: AsCStr>(file: P) -> bool { + let file = file.to_cstr(); unsafe { BNIsTypeArchive(file.as_ref().as_ptr() as *const c_char) } } @@ -734,7 +731,7 @@ impl TypeArchive { parents: &[TypeArchiveSnapshotId], ) -> TypeArchiveSnapshotId where - P: BnStrCompatible, + P: AsCStr, F: FnMut(&TypeArchiveSnapshotId) -> bool, { unsafe extern "C" fn cb_callback<F: FnMut(&TypeArchiveSnapshotId) -> bool>( @@ -781,12 +778,12 @@ impl TypeArchive { merge_conflicts: M, ) -> Result<BnString, Array<BnString>> where - B: BnStrCompatible, - F: BnStrCompatible, - S: BnStrCompatible, + B: AsCStr, + F: AsCStr, + S: AsCStr, M: IntoIterator<Item = (MI, MK)>, - MI: BnStrCompatible, - MK: BnStrCompatible, + MI: AsCStr, + MK: AsCStr, { self.merge_snapshots_with_progress( base_snapshot, @@ -816,17 +813,17 @@ impl TypeArchive { mut progress: P, ) -> Result<BnString, Array<BnString>> where - B: BnStrCompatible, - F: BnStrCompatible, - S: BnStrCompatible, + B: AsCStr, + F: AsCStr, + S: AsCStr, M: IntoIterator<Item = (MI, MK)>, - MI: BnStrCompatible, - MK: BnStrCompatible, + MI: AsCStr, + MK: AsCStr, P: ProgressCallback, { - let base_snapshot = base_snapshot.into_bytes_with_nul(); - let first_snapshot = first_snapshot.into_bytes_with_nul(); - let second_snapshot = second_snapshot.into_bytes_with_nul(); + let base_snapshot = base_snapshot.to_cstr(); + let first_snapshot = first_snapshot.to_cstr(); + let second_snapshot = second_snapshot.to_cstr(); let (merge_keys, merge_values): (Vec<BnString>, Vec<BnString>) = merge_conflicts .into_iter() .map(|(k, v)| (BnString::new(k), BnString::new(v))) @@ -1170,8 +1167,8 @@ impl TypeArchiveMergeConflict { } // TODO: This needs documentation! - pub fn success<S: BnStrCompatible>(&self, value: S) -> bool { - let value = value.into_bytes_with_nul(); + pub fn success<S: AsCStr>(&self, value: S) -> bool { + let value = value.to_cstr(); unsafe { BNTypeArchiveMergeConflictSuccess( self.handle.as_ptr(), diff --git a/rust/src/type_container.rs b/rust/src/type_container.rs index 1535732d..5941b313 100644 --- a/rust/src/type_container.rs +++ b/rust/src/type_container.rs @@ -11,7 +11,7 @@ use crate::platform::Platform; use crate::progress::{NoProgressCallback, ProgressCallback}; use crate::rc::{Array, Ref}; -use crate::string::{raw_to_string, BnStrCompatible, BnString}; +use crate::string::{raw_to_string, AsCStr, BnString}; use crate::type_parser::{TypeParserError, TypeParserResult}; use crate::types::{QualifiedName, QualifiedNameAndType, Type}; use binaryninjacore_sys::*; @@ -137,12 +137,8 @@ impl TypeContainer { /// (by id) to use the new name. /// /// Returns true if the type was renamed. - pub fn rename_type<T: Into<QualifiedName>, S: BnStrCompatible>( - &self, - name: T, - type_id: S, - ) -> bool { - let type_id = type_id.into_bytes_with_nul(); + pub fn rename_type<T: Into<QualifiedName>, S: AsCStr>(&self, name: T, type_id: S) -> bool { + let type_id = type_id.to_cstr(); let raw_name = QualifiedName::into_raw(name.into()); let success = unsafe { BNTypeContainerRenameType( @@ -159,8 +155,8 @@ impl TypeContainer { /// not specified and you may end up with broken references if any still exist. /// /// Returns true if the type was deleted. - pub fn delete_type<S: BnStrCompatible>(&self, type_id: S) -> bool { - let type_id = type_id.into_bytes_with_nul(); + pub fn delete_type<S: AsCStr>(&self, type_id: S) -> bool { + let type_id = type_id.to_cstr(); unsafe { BNTypeContainerDeleteType( self.handle.as_ptr(), @@ -184,8 +180,8 @@ impl TypeContainer { /// Get the unique name of the type in the Type Container with the given id. /// /// If no type with that id exists, returns None. - pub fn type_name<S: BnStrCompatible>(&self, type_id: S) -> Option<QualifiedName> { - let type_id = type_id.into_bytes_with_nul(); + pub fn type_name<S: AsCStr>(&self, type_id: S) -> Option<QualifiedName> { + let type_id = type_id.to_cstr(); let mut result = BNQualifiedName::default(); let success = unsafe { BNTypeContainerGetTypeName( @@ -200,8 +196,8 @@ impl TypeContainer { /// Get the definition of the type in the Type Container with the given id. /// /// If no type with that id exists, returns None. - pub fn type_by_id<S: BnStrCompatible>(&self, type_id: S) -> Option<Ref<Type>> { - let type_id = type_id.into_bytes_with_nul(); + pub fn type_by_id<S: AsCStr>(&self, type_id: S) -> Option<Ref<Type>> { + let type_id = type_id.to_cstr(); let mut result = std::ptr::null_mut(); let success = unsafe { BNTypeContainerGetTypeById( @@ -305,12 +301,12 @@ impl TypeContainer { /// /// * `source` - Source code to parse /// * `import_dependencies` - If Type Library / Type Archive types should be imported during parsing - pub fn parse_type_string<S: BnStrCompatible>( + pub fn parse_type_string<S: AsCStr>( &self, source: S, import_dependencies: bool, ) -> Result<QualifiedNameAndType, Array<TypeParserError>> { - let source = source.into_bytes_with_nul(); + let source = source.to_cstr(); let mut result = BNQualifiedNameAndType::default(); let mut errors = std::ptr::null_mut(); let mut error_count = 0; @@ -351,33 +347,30 @@ impl TypeContainer { import_dependencies: bool, ) -> Result<TypeParserResult, Array<TypeParserError>> where - S: BnStrCompatible, - F: BnStrCompatible, + S: AsCStr, + F: AsCStr, O: IntoIterator, - O::Item: BnStrCompatible, + O::Item: AsCStr, D: IntoIterator, - D::Item: BnStrCompatible, - A: BnStrCompatible, + D::Item: AsCStr, + A: AsCStr, { - let source = source.into_bytes_with_nul(); - let filename = filename.into_bytes_with_nul(); - let options: Vec<_> = options - .into_iter() - .map(|o| o.into_bytes_with_nul()) - .collect(); + let source = source.to_cstr(); + let filename = filename.to_cstr(); + let options: Vec<_> = options.into_iter().map(|o| o.to_cstr()).collect(); let options_raw: Vec<*const c_char> = options .iter() .map(|o| o.as_ref().as_ptr() as *const c_char) .collect(); let include_directories: Vec<_> = include_directories .into_iter() - .map(|d| d.into_bytes_with_nul()) + .map(|d| d.to_cstr()) .collect(); let include_directories_raw: Vec<*const c_char> = include_directories .iter() .map(|d| d.as_ref().as_ptr() as *const c_char) .collect(); - let auto_type_source = auto_type_source.into_bytes_with_nul(); + let auto_type_source = auto_type_source.to_cstr(); let mut raw_result = BNTypeParserResult::default(); let mut errors = std::ptr::null_mut(); let mut error_count = 0; diff --git a/rust/src/type_library.rs b/rust/src/type_library.rs index ee978513..91e86c61 100644 --- a/rust/src/type_library.rs +++ b/rust/src/type_library.rs @@ -7,7 +7,7 @@ use crate::{ metadata::Metadata, platform::Platform, rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref}, - string::{BnStrCompatible, BnString}, + string::{AsCStr, BnString}, types::{QualifiedName, QualifiedNameAndType, Type}, }; @@ -42,8 +42,8 @@ impl TypeLibrary { } /// Creates an empty type library object with a random GUID and the provided name. - pub fn new<S: BnStrCompatible>(arch: CoreArchitecture, name: S) -> TypeLibrary { - let name = name.into_bytes_with_nul(); + pub fn new<S: AsCStr>(arch: CoreArchitecture, name: S) -> TypeLibrary { + let name = name.to_cstr(); let new_lib = unsafe { BNNewTypeLibrary(arch.handle, name.as_ref().as_ptr() as *const ffi::c_char) }; unsafe { TypeLibrary::from_raw(ptr::NonNull::new(new_lib).unwrap()) } @@ -57,9 +57,9 @@ impl TypeLibrary { } /// Decompresses a type library file to a file on disk. - pub fn decompress_to_file<P: BnStrCompatible, O: BnStrCompatible>(path: P, output: O) -> bool { - let path = path.into_bytes_with_nul(); - let output = output.into_bytes_with_nul(); + pub fn decompress_to_file<P: AsCStr, O: AsCStr>(path: P, output: O) -> bool { + let path = path.to_cstr(); + let output = output.to_cstr(); unsafe { BNTypeLibraryDecompressToFile( path.as_ref().as_ptr() as *const ffi::c_char, @@ -69,16 +69,16 @@ impl TypeLibrary { } /// Loads a finalized type library instance from file - pub fn load_from_file<S: BnStrCompatible>(path: S) -> Option<TypeLibrary> { - let path = path.into_bytes_with_nul(); + pub fn load_from_file<S: AsCStr>(path: S) -> Option<TypeLibrary> { + let path = path.to_cstr(); let handle = unsafe { BNLoadTypeLibraryFromFile(path.as_ref().as_ptr() as *const ffi::c_char) }; ptr::NonNull::new(handle).map(|h| unsafe { TypeLibrary::from_raw(h) }) } /// Saves a finalized type library instance to file - pub fn write_to_file<S: BnStrCompatible>(&self, path: S) -> bool { - let path = path.into_bytes_with_nul(); + pub fn write_to_file<S: AsCStr>(&self, path: S) -> bool { + let path = path.to_cstr(); unsafe { BNWriteTypeLibraryToFile(self.as_raw(), path.as_ref().as_ptr() as *const ffi::c_char) } @@ -86,8 +86,8 @@ impl TypeLibrary { /// Looks up the first type library found with a matching name. Keep in mind that names are not /// necessarily unique. - pub fn from_name<S: BnStrCompatible>(arch: CoreArchitecture, name: S) -> Option<TypeLibrary> { - let name = name.into_bytes_with_nul(); + pub fn from_name<S: AsCStr>(arch: CoreArchitecture, name: S) -> Option<TypeLibrary> { + let name = name.to_cstr(); let handle = unsafe { BNLookupTypeLibraryByName(arch.handle, name.as_ref().as_ptr() as *const ffi::c_char) }; @@ -95,8 +95,8 @@ impl TypeLibrary { } /// Attempts to grab a type library associated with the provided Architecture and GUID pair - pub fn from_guid<S: BnStrCompatible>(arch: CoreArchitecture, guid: S) -> Option<TypeLibrary> { - let guid = guid.into_bytes_with_nul(); + pub fn from_guid<S: AsCStr>(arch: CoreArchitecture, guid: S) -> Option<TypeLibrary> { + let guid = guid.to_cstr(); let handle = unsafe { BNLookupTypeLibraryByGuid(arch.handle, guid.as_ref().as_ptr() as *const ffi::c_char) }; @@ -117,8 +117,8 @@ impl TypeLibrary { } /// Sets the name of a type library instance that has not been finalized - pub fn set_name<S: BnStrCompatible>(&self, value: S) { - let value = value.into_bytes_with_nul(); + pub fn set_name<S: AsCStr>(&self, value: S) { + let value = value.to_cstr(); unsafe { BNSetTypeLibraryName(self.as_raw(), value.as_ref().as_ptr() as *const ffi::c_char) } @@ -135,8 +135,8 @@ impl TypeLibrary { } /// Sets the dependency name of a type library instance that has not been finalized - pub fn set_dependency_name<S: BnStrCompatible>(&self, value: S) { - let value = value.into_bytes_with_nul(); + pub fn set_dependency_name<S: AsCStr>(&self, value: S) { + let value = value.to_cstr(); unsafe { BNSetTypeLibraryDependencyName( self.as_raw(), @@ -152,8 +152,8 @@ impl TypeLibrary { } /// Sets the GUID of a type library instance that has not been finalized - pub fn set_guid<S: BnStrCompatible>(&self, value: S) { - let value = value.into_bytes_with_nul(); + pub fn set_guid<S: AsCStr>(&self, value: S) { + let value = value.to_cstr(); unsafe { BNSetTypeLibraryGuid(self.as_raw(), value.as_ref().as_ptr() as *const ffi::c_char) } @@ -168,8 +168,8 @@ impl TypeLibrary { } /// Adds an extra name to this type library used during library lookups and dependency resolution - pub fn add_alternate_name<S: BnStrCompatible>(&self, value: S) { - let value = value.into_bytes_with_nul(); + pub fn add_alternate_name<S: AsCStr>(&self, value: S) { + let value = value.to_cstr(); unsafe { BNAddTypeLibraryAlternateName( self.as_raw(), @@ -212,8 +212,8 @@ impl TypeLibrary { } /// Retrieves a metadata associated with the given key stored in the type library - pub fn query_metadata<S: BnStrCompatible>(&self, key: S) -> Option<Metadata> { - let key = key.into_bytes_with_nul(); + pub fn query_metadata<S: AsCStr>(&self, key: S) -> Option<Metadata> { + let key = key.to_cstr(); let result = unsafe { BNTypeLibraryQueryMetadata(self.as_raw(), key.as_ref().as_ptr() as *const ffi::c_char) }; @@ -231,8 +231,8 @@ impl TypeLibrary { /// /// * `key` - key value to associate the Metadata object with /// * `md` - object to store. - pub fn store_metadata<S: BnStrCompatible>(&self, key: S, md: &Metadata) { - let key = key.into_bytes_with_nul(); + pub fn store_metadata<S: AsCStr>(&self, key: S, md: &Metadata) { + let key = key.to_cstr(); unsafe { BNTypeLibraryStoreMetadata( self.as_raw(), @@ -243,8 +243,8 @@ impl TypeLibrary { } /// Removes the metadata associated with key from the current type library. - pub fn remove_metadata<S: BnStrCompatible>(&self, key: S) { - let key = key.into_bytes_with_nul(); + pub fn remove_metadata<S: AsCStr>(&self, key: S) { + let key = key.to_cstr(); unsafe { BNTypeLibraryRemoveMetadata(self.as_raw(), key.as_ref().as_ptr() as *const ffi::c_char) } @@ -299,8 +299,8 @@ impl TypeLibrary { /// Use this api with extreme caution. /// /// </div> - pub fn add_type_source<S: BnStrCompatible>(&self, name: QualifiedName, source: S) { - let source = source.into_bytes_with_nul(); + pub fn add_type_source<S: AsCStr>(&self, name: QualifiedName, source: S) { + let source = source.to_cstr(); let mut raw_name = QualifiedName::into_raw(name); unsafe { BNAddTypeLibraryNamedTypeSource( diff --git a/rust/src/type_parser.rs b/rust/src/type_parser.rs index dbf5a709..1cfe346c 100644 --- a/rust/src/type_parser.rs +++ b/rust/src/type_parser.rs @@ -6,7 +6,7 @@ use std::ptr::NonNull; use crate::platform::Platform; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref}; -use crate::string::{raw_to_string, BnStrCompatible, BnString}; +use crate::string::{raw_to_string, AsCStr, BnString}; use crate::type_container::TypeContainer; use crate::types::{QualifiedName, QualifiedNameAndType, Type}; @@ -14,7 +14,7 @@ pub type TypeParserErrorSeverity = BNTypeParserErrorSeverity; pub type TypeParserOption = BNTypeParserOption; /// Register a custom parser with the API -pub fn register_type_parser<S: BnStrCompatible, T: TypeParser>( +pub fn register_type_parser<S: AsCStr, T: TypeParser>( name: S, parser: T, ) -> (&'static mut T, CoreTypeParser) { @@ -30,10 +30,7 @@ pub fn register_type_parser<S: BnStrCompatible, T: TypeParser>( freeErrorList: Some(cb_free_error_list), }; let result = unsafe { - BNRegisterTypeParser( - name.into_bytes_with_nul().as_ref().as_ptr() as *const _, - &mut callback, - ) + BNRegisterTypeParser(name.to_cstr().as_ref().as_ptr() as *const _, &mut callback) }; let core = unsafe { CoreTypeParser::from_raw(NonNull::new(result).unwrap()) }; (parser, core) @@ -55,8 +52,8 @@ impl CoreTypeParser { unsafe { Array::new(result, count, ()) } } - pub fn parser_by_name<S: BnStrCompatible>(name: S) -> Option<CoreTypeParser> { - let name_raw = name.into_bytes_with_nul(); + pub fn parser_by_name<S: AsCStr>(name: S) -> Option<CoreTypeParser> { + let name_raw = name.to_cstr(); let result = unsafe { BNGetTypeParserByName(name_raw.as_ref().as_ptr() as *const c_char) }; NonNull::new(result).map(|x| unsafe { Self::from_raw(x) }) } diff --git a/rust/src/type_printer.rs b/rust/src/type_printer.rs index 67d36570..b49832de 100644 --- a/rust/src/type_printer.rs +++ b/rust/src/type_printer.rs @@ -4,7 +4,7 @@ use crate::binary_view::BinaryView; use crate::disassembly::InstructionTextToken; use crate::platform::Platform; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref}; -use crate::string::{raw_to_string, BnStrCompatible, BnString}; +use crate::string::{raw_to_string, AsCStr, BnString}; use crate::type_container::TypeContainer; use crate::types::{NamedTypeReference, QualifiedName, QualifiedNameAndType, Type}; use binaryninjacore_sys::*; @@ -15,7 +15,7 @@ pub type TokenEscapingType = BNTokenEscapingType; pub type TypeDefinitionLineType = BNTypeDefinitionLineType; /// Register a custom parser with the API -pub fn register_type_printer<S: BnStrCompatible, T: TypePrinter>( +pub fn register_type_printer<S: AsCStr, T: TypePrinter>( name: S, parser: T, ) -> (&'static mut T, CoreTypePrinter) { @@ -36,7 +36,7 @@ pub fn register_type_printer<S: BnStrCompatible, T: TypePrinter>( }; let result = unsafe { BNRegisterTypePrinter( - name.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + name.to_cstr().as_ref().as_ptr() as *const c_char, &mut callback, ) }; @@ -61,8 +61,8 @@ impl CoreTypePrinter { unsafe { Array::new(result, count, ()) } } - pub fn printer_by_name<S: BnStrCompatible>(name: S) -> Option<CoreTypePrinter> { - let name_raw = name.into_bytes_with_nul(); + pub fn printer_by_name<S: AsCStr>(name: S) -> Option<CoreTypePrinter> { + let name_raw = name.to_cstr(); let result = unsafe { BNGetTypePrinterByName(name_raw.as_ref().as_ptr() as *const c_char) }; NonNull::new(result).map(|x| unsafe { Self::from_raw(x) }) } diff --git a/rust/src/types.rs b/rust/src/types.rs index a46dce2e..710a8857 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -24,7 +24,7 @@ use crate::{ binary_view::{BinaryView, BinaryViewExt}, calling_convention::CoreCallingConvention, rc::*, - string::{BnStrCompatible, BnString}, + string::{AsCStr, BnString}, }; use crate::confidence::{Conf, MAX_CONFIDENCE, MIN_CONFIDENCE}; @@ -258,10 +258,10 @@ impl TypeBuilder { } } - pub fn named_int<S: BnStrCompatible>(width: usize, is_signed: bool, alt_name: S) -> Self { + pub fn named_int<S: AsCStr>(width: usize, is_signed: bool, alt_name: S) -> Self { let mut is_signed = Conf::new(is_signed, MAX_CONFIDENCE).into(); // let alt_name = BnString::new(alt_name); - let alt_name = alt_name.into_bytes_with_nul(); // This segfaulted once, so the above version is there if we need to change to it, but in theory this is copied into a `const string&` on the C++ side; I'm just not 100% confident that a constant reference copies data + let alt_name = alt_name.to_cstr(); // This segfaulted once, so the above version is there if we need to change to it, but in theory this is copied into a `const string&` on the C++ side; I'm just not 100% confident that a constant reference copies data unsafe { Self::from_raw(BNCreateIntegerTypeBuilder( @@ -281,9 +281,9 @@ impl TypeBuilder { } } - pub fn named_float<S: BnStrCompatible>(width: usize, alt_name: S) -> Self { + pub fn named_float<S: AsCStr>(width: usize, alt_name: S) -> Self { // let alt_name = BnString::new(alt_name); - let alt_name = alt_name.into_bytes_with_nul(); // See same line in `named_int` above + let alt_name = alt_name.to_cstr(); // See same line in `named_int` above unsafe { Self::from_raw(BNCreateFloatTypeBuilder( @@ -649,10 +649,10 @@ impl Type { } } - pub fn named_int<S: BnStrCompatible>(width: usize, is_signed: bool, alt_name: S) -> Ref<Self> { + pub fn named_int<S: AsCStr>(width: usize, is_signed: bool, alt_name: S) -> Ref<Self> { let mut is_signed = Conf::new(is_signed, MAX_CONFIDENCE).into(); // let alt_name = BnString::new(alt_name); - let alt_name = alt_name.into_bytes_with_nul(); // This segfaulted once, so the above version is there if we need to change to it, but in theory this is copied into a `const string&` on the C++ side; I'm just not 100% confident that a constant reference copies data + let alt_name = alt_name.to_cstr(); // This segfaulted once, so the above version is there if we need to change to it, but in theory this is copied into a `const string&` on the C++ side; I'm just not 100% confident that a constant reference copies data unsafe { Self::ref_from_raw(BNCreateIntegerType( @@ -672,9 +672,9 @@ impl Type { } } - pub fn named_float<S: BnStrCompatible>(width: usize, alt_name: S) -> Ref<Self> { + pub fn named_float<S: AsCStr>(width: usize, alt_name: S) -> Ref<Self> { // let alt_name = BnString::new(alt_name); - let alt_name = alt_name.into_bytes_with_nul(); // See same line in `named_int` above + let alt_name = alt_name.to_cstr(); // See same line in `named_int` above unsafe { Self::ref_from_raw(BNCreateFloatType(width, alt_name.as_ref().as_ptr() as _)) } } @@ -1217,24 +1217,24 @@ impl EnumerationBuilder { unsafe { Enumeration::ref_from_raw(BNFinalizeEnumerationBuilder(self.handle)) } } - pub fn append<S: BnStrCompatible>(&mut self, name: S) -> &mut Self { - let name = name.into_bytes_with_nul(); + pub fn append<S: AsCStr>(&mut self, name: S) -> &mut Self { + let name = name.to_cstr(); unsafe { BNAddEnumerationBuilderMember(self.handle, name.as_ref().as_ptr() as _); } self } - pub fn insert<S: BnStrCompatible>(&mut self, name: S, value: u64) -> &mut Self { - let name = name.into_bytes_with_nul(); + pub fn insert<S: AsCStr>(&mut self, name: S, value: u64) -> &mut Self { + let name = name.to_cstr(); unsafe { BNAddEnumerationBuilderMemberWithValue(self.handle, name.as_ref().as_ptr() as _, value); } self } - pub fn replace<S: BnStrCompatible>(&mut self, id: usize, name: S, value: u64) -> &mut Self { - let name = name.into_bytes_with_nul(); + pub fn replace<S: AsCStr>(&mut self, id: usize, name: S, value: u64) -> &mut Self { + let name = name.to_cstr(); unsafe { BNReplaceEnumerationBuilderMember(self.handle, id, name.as_ref().as_ptr() as _, value); } @@ -1476,14 +1476,14 @@ impl StructureBuilder { self } - pub fn append<'a, S: BnStrCompatible, T: Into<Conf<&'a Type>>>( + pub fn append<'a, S: AsCStr, T: Into<Conf<&'a Type>>>( &mut self, ty: T, name: S, access: MemberAccess, scope: MemberScope, ) -> &mut Self { - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let owned_raw_ty = Conf::<&Type>::into_raw(ty.into()); unsafe { BNAddStructureBuilderMember( @@ -1513,7 +1513,7 @@ impl StructureBuilder { self } - pub fn insert<'a, S: BnStrCompatible, T: Into<Conf<&'a Type>>>( + pub fn insert<'a, S: AsCStr, T: Into<Conf<&'a Type>>>( &mut self, ty: T, name: S, @@ -1522,7 +1522,7 @@ impl StructureBuilder { access: MemberAccess, scope: MemberScope, ) -> &mut Self { - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let owned_raw_ty = Conf::<&Type>::into_raw(ty.into()); unsafe { BNAddStructureBuilderMemberAtOffset( @@ -1538,14 +1538,14 @@ impl StructureBuilder { self } - pub fn replace<'a, S: BnStrCompatible, T: Into<Conf<&'a Type>>>( + pub fn replace<'a, S: AsCStr, T: Into<Conf<&'a Type>>>( &mut self, index: usize, ty: T, name: S, overwrite_existing: bool, ) -> &mut Self { - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let owned_raw_ty = Conf::<&Type>::into_raw(ty.into()); unsafe { BNReplaceStructureBuilderMember( @@ -1870,12 +1870,12 @@ impl NamedTypeReference { /// You should not assign type ids yourself: if you use this to reference a type you are going /// to create but have not yet created, you may run into problems when giving your types to /// a BinaryView. - pub fn new_with_id<T: Into<QualifiedName>, S: BnStrCompatible>( + pub fn new_with_id<T: Into<QualifiedName>, S: AsCStr>( type_class: NamedTypeReferenceClass, type_id: S, name: T, ) -> Ref<Self> { - let type_id = type_id.into_bytes_with_nul(); + let type_id = type_id.to_cstr(); let mut raw_name = QualifiedName::into_raw(name.into()); let result = unsafe { Self::ref_from_raw(BNCreateNamedType( diff --git a/rust/src/websocket/client.rs b/rust/src/websocket/client.rs index 36c7bedd..43e1e1f7 100644 --- a/rust/src/websocket/client.rs +++ b/rust/src/websocket/client.rs @@ -1,5 +1,5 @@ use crate::rc::{Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use binaryninjacore_sys::*; use std::ffi::{c_char, c_void, CStr}; use std::ptr::NonNull; @@ -21,8 +21,8 @@ pub trait WebsocketClient: Sync + Send { fn connect<I, K, V>(&self, host: &str, headers: I) -> bool where I: IntoIterator<Item = (K, V)>, - K: BnStrCompatible, - V: BnStrCompatible; + K: AsCStr, + V: AsCStr; fn write(&self, data: &[u8]) -> bool; @@ -77,14 +77,14 @@ impl CoreWebsocketClient { ) -> bool where I: IntoIterator<Item = (K, V)>, - K: BnStrCompatible, - V: BnStrCompatible, + K: AsCStr, + V: AsCStr, C: WebsocketClientCallback, { - let url = host.into_bytes_with_nul(); + let url = host.to_cstr(); let (header_keys, header_values): (Vec<K::Result>, Vec<V::Result>) = headers .into_iter() - .map(|(k, v)| (k.into_bytes_with_nul(), v.into_bytes_with_nul())) + .map(|(k, v)| (k.to_cstr(), v.to_cstr())) .unzip(); let header_keys: Vec<*const c_char> = header_keys .iter() @@ -129,7 +129,7 @@ impl CoreWebsocketClient { /// Call the error callback function pub fn notify_error(&self, msg: &str) { - let error = msg.into_bytes_with_nul(); + let error = msg.to_cstr(); unsafe { BNNotifyWebsocketClientError(self.handle.as_ptr(), error.as_ptr() as *const c_char) } diff --git a/rust/src/websocket/provider.rs b/rust/src/websocket/provider.rs index 2d01fbc3..48c198d2 100644 --- a/rust/src/websocket/provider.rs +++ b/rust/src/websocket/provider.rs @@ -1,5 +1,5 @@ use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use crate::websocket::client; use crate::websocket::client::{CoreWebsocketClient, WebsocketClient}; use binaryninjacore_sys::*; @@ -11,7 +11,7 @@ pub fn register_websocket_provider<W>(name: &str) -> &'static mut W where W: WebsocketProvider, { - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); let provider_uninit = MaybeUninit::uninit(); // SAFETY: Websocket provider is never freed let leaked_provider = Box::leak(Box::new(provider_uninit)); @@ -80,8 +80,8 @@ impl CoreWebsocketProvider { unsafe { Array::new(result, count, ()) } } - pub fn by_name<S: BnStrCompatible>(name: S) -> Option<CoreWebsocketProvider> { - let name = name.into_bytes_with_nul(); + pub fn by_name<S: AsCStr>(name: S) -> Option<CoreWebsocketProvider> { + let name = name.to_cstr(); let result = unsafe { BNGetWebsocketProviderByName(name.as_ref().as_ptr() as *const c_char) }; NonNull::new(result).map(|h| unsafe { Self::from_raw(h) }) diff --git a/rust/src/worker_thread.rs b/rust/src/worker_thread.rs index 349456e5..aed872de 100644 --- a/rust/src/worker_thread.rs +++ b/rust/src/worker_thread.rs @@ -1,4 +1,4 @@ -use crate::string::BnStrCompatible; +use crate::string::AsCStr; use binaryninjacore_sys::*; use std::ffi::{c_char, c_void}; @@ -17,10 +17,10 @@ impl WorkerThreadActionExecutor { } } -pub fn execute_on_worker_thread<F: Fn() + 'static, S: BnStrCompatible>(name: S, f: F) { +pub fn execute_on_worker_thread<F: Fn() + 'static, S: AsCStr>(name: S, f: F) { let boxed_executor = Box::new(WorkerThreadActionExecutor { func: Box::new(f) }); let raw_executor = Box::into_raw(boxed_executor); - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); unsafe { BNWorkerEnqueueNamed( raw_executor as *mut c_void, @@ -30,10 +30,10 @@ pub fn execute_on_worker_thread<F: Fn() + 'static, S: BnStrCompatible>(name: S, } } -pub fn execute_on_worker_thread_priority<F: Fn() + 'static, S: BnStrCompatible>(name: S, f: F) { +pub fn execute_on_worker_thread_priority<F: Fn() + 'static, S: AsCStr>(name: S, f: F) { let boxed_executor = Box::new(WorkerThreadActionExecutor { func: Box::new(f) }); let raw_executor = Box::into_raw(boxed_executor); - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); unsafe { BNWorkerPriorityEnqueueNamed( raw_executor as *mut c_void, @@ -43,10 +43,10 @@ pub fn execute_on_worker_thread_priority<F: Fn() + 'static, S: BnStrCompatible>( } } -pub fn execute_on_worker_thread_interactive<F: Fn() + 'static, S: BnStrCompatible>(name: S, f: F) { +pub fn execute_on_worker_thread_interactive<F: Fn() + 'static, S: AsCStr>(name: S, f: F) { let boxed_executor = Box::new(WorkerThreadActionExecutor { func: Box::new(f) }); let raw_executor = Box::into_raw(boxed_executor); - let name = name.into_bytes_with_nul(); + let name = name.to_cstr(); unsafe { BNWorkerInteractiveEnqueueNamed( raw_executor as *mut c_void, diff --git a/rust/src/workflow.rs b/rust/src/workflow.rs index 71a60824..b5023815 100644 --- a/rust/src/workflow.rs +++ b/rust/src/workflow.rs @@ -9,7 +9,7 @@ use crate::low_level_il::function::{LowLevelILFunction, Mutable, NonSSA, NonSSAV use crate::low_level_il::MutableLiftedILFunction; use crate::medium_level_il::MediumLevelILFunction; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; -use crate::string::{BnStrCompatible, BnString}; +use crate::string::{AsCStr, BnString}; use std::ffi::{c_char, c_void}; use std::ptr::NonNull; @@ -108,8 +108,8 @@ impl AnalysisContext { } } - pub fn inform<S: BnStrCompatible>(&self, request: S) -> bool { - let request = request.into_bytes_with_nul(); + pub fn inform<S: AsCStr>(&self, request: S) -> bool { + let request = request.to_cstr(); unsafe { BNAnalysisContextInform( self.handle.as_ptr(), @@ -166,9 +166,9 @@ impl Activity { Ref::new(Self { handle }) } - pub fn new<S: BnStrCompatible>(config: S) -> Ref<Self> { + pub fn new<S: AsCStr>(config: S) -> Ref<Self> { unsafe extern "C" fn cb_action_nop(_: *mut c_void, _: *mut BNAnalysisContext) {} - let config = config.into_bytes_with_nul(); + let config = config.to_cstr(); let result = unsafe { BNCreateActivity( config.as_ref().as_ptr() as *const c_char, @@ -181,7 +181,7 @@ impl Activity { pub fn new_with_action<S, F>(config: S, mut action: F) -> Ref<Self> where - S: BnStrCompatible, + S: AsCStr, F: FnMut(&AnalysisContext), { unsafe extern "C" fn cb_action<F: FnMut(&AnalysisContext)>( @@ -193,7 +193,7 @@ impl Activity { ctxt(&AnalysisContext::from_raw(analysis)) } } - let config = config.into_bytes_with_nul(); + let config = config.to_cstr(); let result = unsafe { BNCreateActivity( config.as_ref().as_ptr() as *const c_char, @@ -250,8 +250,8 @@ impl Workflow { /// Create a new unregistered [Workflow] with no activities. /// /// To get a copy of an existing registered [Workflow] use [Workflow::clone_to]. - pub fn new<S: BnStrCompatible>(name: S) -> Ref<Self> { - let name = name.into_bytes_with_nul(); + pub fn new<S: AsCStr>(name: S) -> Ref<Self> { + let name = name.to_cstr(); let result = unsafe { BNCreateWorkflow(name.as_ref().as_ptr() as *const c_char) }; unsafe { Workflow::ref_from_raw(NonNull::new(result).unwrap()) } } @@ -260,7 +260,7 @@ impl Workflow { /// /// * `name` - the name for the new [Workflow] #[must_use] - pub fn clone_to<S: BnStrCompatible + Clone>(&self, name: S) -> Ref<Workflow> { + pub fn clone_to<S: AsCStr + Clone>(&self, name: S) -> Ref<Workflow> { self.clone_to_with_root(name, "") } @@ -269,13 +269,13 @@ impl Workflow { /// * `name` - the name for the new [Workflow] /// * `root_activity` - perform the clone operation with this activity as the root #[must_use] - pub fn clone_to_with_root<S: BnStrCompatible, A: BnStrCompatible>( + pub fn clone_to_with_root<S: AsCStr, A: AsCStr>( &self, name: S, root_activity: A, ) -> Ref<Workflow> { - let raw_name = name.into_bytes_with_nul(); - let activity = root_activity.into_bytes_with_nul(); + let raw_name = name.to_cstr(); + let activity = root_activity.to_cstr(); unsafe { Self::ref_from_raw( NonNull::new(BNWorkflowClone( @@ -288,10 +288,9 @@ impl Workflow { } } - pub fn instance<S: BnStrCompatible>(name: S) -> Ref<Workflow> { - let result = unsafe { - BNWorkflowInstance(name.into_bytes_with_nul().as_ref().as_ptr() as *const c_char) - }; + pub fn instance<S: AsCStr>(name: S) -> Ref<Workflow> { + let result = + unsafe { BNWorkflowInstance(name.to_cstr().as_ref().as_ptr() as *const c_char) }; unsafe { Workflow::ref_from_raw(NonNull::new(result).unwrap()) } } @@ -317,8 +316,8 @@ impl Workflow { /// Register this [Workflow], making it immutable and available for use. /// /// * `configuration` - a JSON representation of the workflow configuration - pub fn register_with_config<S: BnStrCompatible>(&self, config: S) -> Result<(), ()> { - let config = config.into_bytes_with_nul(); + pub fn register_with_config<S: AsCStr>(&self, config: S) -> Result<(), ()> { + let config = config.to_cstr(); if unsafe { BNRegisterWorkflow( self.handle.as_ptr(), @@ -349,12 +348,9 @@ impl Workflow { ) -> Result<Ref<Activity>, ()> where I: IntoIterator, - I::Item: BnStrCompatible, + I::Item: AsCStr, { - let subactivities_raw: Vec<_> = subactivities - .into_iter() - .map(|x| x.into_bytes_with_nul()) - .collect(); + let subactivities_raw: Vec<_> = subactivities.into_iter().map(|x| x.to_cstr()).collect(); let mut subactivities_ptr: Vec<*const _> = subactivities_raw .iter() .map(|x| x.as_ref().as_ptr() as *const c_char) @@ -372,11 +368,11 @@ impl Workflow { } /// Determine if an Activity exists in this [Workflow]. - pub fn contains<A: BnStrCompatible>(&self, activity: A) -> bool { + pub fn contains<A: AsCStr>(&self, activity: A) -> bool { unsafe { BNWorkflowContains( self.handle.as_ptr(), - activity.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + activity.to_cstr().as_ref().as_ptr() as *const c_char, ) } } @@ -390,11 +386,11 @@ impl Workflow { /// [Workflow], just for the given `activity`. /// /// `activity` - return the configuration for the `activity` - pub fn configuration_with_activity<A: BnStrCompatible>(&self, activity: A) -> String { + pub fn configuration_with_activity<A: AsCStr>(&self, activity: A) -> String { let result = unsafe { BNWorkflowGetConfiguration( self.handle.as_ptr(), - activity.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + activity.to_cstr().as_ref().as_ptr() as *const c_char, ) }; assert!(!result.is_null()); @@ -411,8 +407,8 @@ impl Workflow { } /// Retrieve the Activity object for the specified `name`. - pub fn activity<A: BnStrCompatible>(&self, name: A) -> Option<Ref<Activity>> { - let name = name.into_bytes_with_nul(); + pub fn activity<A: AsCStr>(&self, name: A) -> Option<Ref<Activity>> { + let name = name.to_cstr(); let result = unsafe { BNWorkflowGetActivity( self.handle.as_ptr(), @@ -426,12 +422,12 @@ impl Workflow { /// specified just for the given `activity`. /// /// * `activity` - if specified, return the roots for the `activity` - pub fn activity_roots<A: BnStrCompatible>(&self, activity: A) -> Array<BnString> { + pub fn activity_roots<A: AsCStr>(&self, activity: A) -> Array<BnString> { let mut count = 0; let result = unsafe { BNWorkflowGetActivityRoots( self.handle.as_ptr(), - activity.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + activity.to_cstr().as_ref().as_ptr() as *const c_char, &mut count, ) }; @@ -443,16 +439,12 @@ impl Workflow { /// /// * `activity` - if specified, return the direct children and optionally the descendants of the `activity` (includes `activity`) /// * `immediate` - whether to include only direct children of `activity` or all descendants - pub fn subactivities<A: BnStrCompatible>( - &self, - activity: A, - immediate: bool, - ) -> Array<BnString> { + pub fn subactivities<A: AsCStr>(&self, activity: A, immediate: bool) -> Array<BnString> { let mut count = 0; let result = unsafe { BNWorkflowGetSubactivities( self.handle.as_ptr(), - activity.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + activity.to_cstr().as_ref().as_ptr() as *const c_char, immediate, &mut count, ) @@ -467,14 +459,11 @@ impl Workflow { /// * `activities` - the list of Activities to assign pub fn assign_subactivities<A, I>(&self, activity: A, activities: I) -> bool where - A: BnStrCompatible, + A: AsCStr, I: IntoIterator, - I::Item: BnStrCompatible, + I::Item: AsCStr, { - let input_list: Vec<_> = activities - .into_iter() - .map(|a| a.into_bytes_with_nul()) - .collect(); + let input_list: Vec<_> = activities.into_iter().map(|a| a.to_cstr()).collect(); let mut input_list_ptr: Vec<*const _> = input_list .iter() .map(|x| x.as_ref().as_ptr() as *const c_char) @@ -482,7 +471,7 @@ impl Workflow { unsafe { BNWorkflowAssignSubactivities( self.handle.as_ptr(), - activity.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + activity.to_cstr().as_ref().as_ptr() as *const c_char, input_list_ptr.as_mut_ptr(), input_list.len(), ) @@ -500,14 +489,11 @@ impl Workflow { /// * `activities` - the list of Activities to insert pub fn insert<A, I>(&self, activity: A, activities: I) -> bool where - A: BnStrCompatible, + A: AsCStr, I: IntoIterator, - I::Item: BnStrCompatible, + I::Item: AsCStr, { - let input_list: Vec<_> = activities - .into_iter() - .map(|a| a.into_bytes_with_nul()) - .collect(); + let input_list: Vec<_> = activities.into_iter().map(|a| a.to_cstr()).collect(); let mut input_list_ptr: Vec<*const _> = input_list .iter() .map(|x| x.as_ref().as_ptr() as *const c_char) @@ -515,7 +501,7 @@ impl Workflow { unsafe { BNWorkflowInsert( self.handle.as_ptr(), - activity.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + activity.to_cstr().as_ref().as_ptr() as *const c_char, input_list_ptr.as_mut_ptr(), input_list.len(), ) @@ -528,14 +514,11 @@ impl Workflow { /// * `activities` - the list of Activities to insert pub fn insert_after<A, I>(&self, activity: A, activities: I) -> bool where - A: BnStrCompatible, + A: AsCStr, I: IntoIterator, - I::Item: BnStrCompatible, + I::Item: AsCStr, { - let input_list: Vec<_> = activities - .into_iter() - .map(|a| a.into_bytes_with_nul()) - .collect(); + let input_list: Vec<_> = activities.into_iter().map(|a| a.to_cstr()).collect(); let mut input_list_ptr: Vec<*const _> = input_list .iter() .map(|x| x.as_ref().as_ptr() as *const c_char) @@ -543,7 +526,7 @@ impl Workflow { unsafe { BNWorkflowInsertAfter( self.handle.as_ptr(), - activity.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + activity.to_cstr().as_ref().as_ptr() as *const c_char, input_list_ptr.as_mut_ptr(), input_list.len(), ) @@ -551,11 +534,11 @@ impl Workflow { } /// Remove the specified `activity` - pub fn remove<A: BnStrCompatible>(&self, activity: A) -> bool { + pub fn remove<A: AsCStr>(&self, activity: A) -> bool { unsafe { BNWorkflowRemove( self.handle.as_ptr(), - activity.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + activity.to_cstr().as_ref().as_ptr() as *const c_char, ) } } @@ -564,16 +547,12 @@ impl Workflow { /// /// * `activity` - the Activity to replace /// * `new_activity` - the replacement Activity - pub fn replace<A: BnStrCompatible, N: BnStrCompatible>( - &self, - activity: A, - new_activity: N, - ) -> bool { + pub fn replace<A: AsCStr, N: AsCStr>(&self, activity: A, new_activity: N) -> bool { unsafe { BNWorkflowReplace( self.handle.as_ptr(), - activity.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, - new_activity.into_bytes_with_nul().as_ref().as_ptr() as *const c_char, + activity.to_cstr().as_ref().as_ptr() as *const c_char, + new_activity.to_cstr().as_ref().as_ptr() as *const c_char, ) } } @@ -582,13 +561,13 @@ impl Workflow { /// /// * `activity` - if specified, generate the Flowgraph using `activity` as the root /// * `sequential` - whether to generate a **Composite** or **Sequential** style graph - pub fn graph<A: BnStrCompatible>( + pub fn graph<A: AsCStr>( &self, activity: A, sequential: Option<bool>, ) -> Option<Ref<FlowGraph>> { let sequential = sequential.unwrap_or(false); - let activity_name = activity.into_bytes_with_nul(); + let activity_name = activity.to_cstr(); let graph = unsafe { BNWorkflowGetGraph( self.handle.as_ptr(), |
