@@ -31,6 +31,7 @@ use std::sync::mpsc::Sender;
3131use std:: sync:: Mutex ;
3232use std:: thread:: JoinHandle ;
3333use std:: time:: Duration ;
34+ use crate :: settings:: Settings ;
3435
3536static MAIN_THREAD_HANDLE : Mutex < Option < JoinHandle < ( ) > > > = Mutex :: new ( None ) ;
3637
@@ -49,13 +50,13 @@ pub enum InitializationError {
4950 NoLicenseFound ,
5051}
5152
52- /// Loads plugins, core architecture, platform, etc.
53+ /// Loads core plugins, core architecture, platform, etc.
5354///
5455/// ⚠️ Important! Must be called at the beginning of scripts. Plugins do not need to call this. ⚠️
5556///
5657/// You can instead call this through [`Session`].
5758///
58- /// If you need to customize initialization, use [`init_with_opts`] instead.
59+ /// If you need to customize initialization, use [`init_with_opts`] instead, for example to set [`InitializationOptions::with_user_plugins`] .
5960pub fn init ( ) -> Result < ( ) , InitializationError > {
6061 let options = InitializationOptions :: default ( ) ;
6162 init_with_opts ( options)
@@ -172,6 +173,21 @@ impl Default for InitializationOptions {
172173 }
173174}
174175
176+ /// Adjust settings temporarily so that we can screw with the core settings and not impact user settings.
177+ fn init_adjusted_settings ( options : & InitializationOptions , cb : impl FnOnce ( & mut Settings ) ) {
178+ let mut settings = Settings :: new ( ) ;
179+ let is_python_enabled = settings. get_bool ( "corePlugins.python" ) ;
180+ // Because we don't ship core python plugins, we don't need to load
181+ // python if we are not loading user plugins.
182+ settings. set_bool ( "corePlugins.python" , options. user_plugins ) ;
183+ if options. repo_plugins {
184+ settings. set_bool ( "corePlugins.python" , options. repo_plugins ) ;
185+ }
186+ cb ( & mut settings) ;
187+ // Reset the settings to the previous value.
188+ settings. set_bool ( "corePlugins.python" , is_python_enabled) ;
189+ }
190+
175191/// This initializes the core with the given [`InitializationOptions`].
176192pub fn init_with_opts ( options : InitializationOptions ) -> Result < ( ) , InitializationError > {
177193 // If we are the main thread that means there is no main thread, we should register a main thread handler.
@@ -207,20 +223,22 @@ pub fn init_with_opts(options: InitializationOptions) -> Result<(), Initializati
207223 _ => { }
208224 }
209225
210- if let Some ( license) = options. license {
226+ if let Some ( license) = options. license . clone ( ) {
211227 // We were given a license override, use it!
212228 set_license ( Some ( license) ) ;
213229 }
214230
215- set_bundled_plugin_directory ( options. bundled_plugin_directory ) ;
231+ set_bundled_plugin_directory ( & options. bundled_plugin_directory ) ;
216232
217- unsafe {
218- BNInitPlugins ( options. user_plugins ) ;
219- if options. repo_plugins {
220- // We are allowed to initialize repo plugins, so do it!
221- BNInitRepoPlugins ( ) ;
233+ init_adjusted_settings ( & options, |_| {
234+ unsafe {
235+ BNInitPlugins ( options. user_plugins ) ;
236+ if options. repo_plugins {
237+ // We are allowed to initialize repo plugins, so do it!
238+ BNInitRepoPlugins ( ) ;
239+ }
222240 }
223- }
241+ } ) ;
224242
225243 if !is_license_validated ( ) {
226244 // Unfortunately you must have a valid license to use Binary Ninja.
@@ -291,6 +309,9 @@ impl Session {
291309 ///
292310 /// If you cannot otherwise provide a license via `BN_LICENSE_FILE` environment variable or the Binary Ninja user directory
293311 /// you can call [`Session::new_with_opts`] instead of this function.
312+ ///
313+ /// If you need to use a user plugin you should call [`Session::new_with_opts`] instead, as by default
314+ /// [`Session::new`] will only initialize core plugins.
294315 pub fn new ( ) -> Result < Self , InitializationError > {
295316 if license_location ( ) . is_some ( ) {
296317 // We were able to locate a license, continue with initialization.
0 commit comments