@@ -10,21 +10,77 @@ pub mod symbol_utils;
1010
1111use crate :: prelude:: * ;
1212
13+ use std:: { env, fs, path} ;
14+
15+ use anyhow:: bail;
16+
17+ const ENV_CWE_CHECKER_CONFIGS_PATH : & str = "CWE_CHECKER_CONFIGS_PATH" ;
18+ const ENV_CWE_CHECKER_GHIDRA_PLUGINS_PATH : & str = "CWE_CHECKER_GHIDRA_PLUGINS_PATH" ;
19+
1320/// Get the contents of a configuration file.
21+ ///
22+ /// We first search the file in our config directory. Then, we fall back to
23+ /// the CWE_CHECKER_CONFIG environment variable.
1424pub fn read_config_file ( filename : & str ) -> Result < serde_json:: Value , Error > {
15- let project_dirs = directories:: ProjectDirs :: from ( "" , "" , "cwe_checker" )
16- . context ( "Could not discern location of configuration files." ) ?;
25+ let config_path = if let Some ( config_path) = get_config_path_from_project_dir ( filename) {
26+ config_path
27+ } else if let Some ( config_path) = get_path_from_env ( ENV_CWE_CHECKER_CONFIGS_PATH , filename) {
28+ config_path
29+ } else {
30+ bail ! ( "Unable to find configuration file: {}." , filename)
31+ } ;
32+ let config_file = fs:: read_to_string ( config_path)
33+ . context ( format ! ( "Could not read configuration file: {}" , filename) ) ?;
34+ Ok ( serde_json:: from_str ( & config_file) ?)
35+ }
36+
37+ fn get_config_path_from_project_dir ( filename : & str ) -> Option < path:: PathBuf > {
38+ let project_dirs = directories:: ProjectDirs :: from ( "" , "" , "cwe_checker" ) ?;
1739 let config_dir = project_dirs. config_dir ( ) ;
1840 let config_path = config_dir. join ( filename) ;
19- let config_file =
20- std:: fs:: read_to_string ( config_path) . context ( "Could not read configuration file" ) ?;
21- Ok ( serde_json:: from_str ( & config_file) ?)
41+
42+ if config_path. exists ( ) {
43+ Some ( config_path)
44+ } else {
45+ None
46+ }
47+ }
48+
49+ /// Get the path to a Ghidra plugin that is bundled with the cwe_checker.
50+ ///
51+ /// We first search the plugin in our data directory, then we fall back to
52+ /// the CWE_CHECKER_GHIDRA_PLUGIN_PATH environment variable.
53+ pub fn get_ghidra_plugin_path ( plugin_name : & str ) -> Result < path:: PathBuf , Error > {
54+ if let Some ( ghidra_plugin_path) = get_ghidra_plugin_path_from_project_dirs ( plugin_name) {
55+ Ok ( ghidra_plugin_path)
56+ } else if let Some ( ghidra_plugin_path) =
57+ get_path_from_env ( ENV_CWE_CHECKER_GHIDRA_PLUGINS_PATH , plugin_name)
58+ {
59+ Ok ( ghidra_plugin_path)
60+ } else {
61+ bail ! ( "Unable to find Ghidra plugin: {}" , plugin_name)
62+ }
2263}
2364
24- /// Get the folder path to a Ghidra plugin bundled with the cwe_checker.
25- pub fn get_ghidra_plugin_path ( plugin_name : & str ) -> std:: path:: PathBuf {
26- let project_dirs = directories:: ProjectDirs :: from ( "" , "" , "cwe_checker" )
27- . expect ( "Could not discern location of data directory." ) ;
65+ fn get_ghidra_plugin_path_from_project_dirs ( plugin_name : & str ) -> Option < path:: PathBuf > {
66+ let project_dirs = directories:: ProjectDirs :: from ( "" , "" , "cwe_checker" ) ?;
2867 let data_dir = project_dirs. data_dir ( ) ;
29- data_dir. join ( "ghidra" ) . join ( plugin_name)
68+ let plugin_path = data_dir. join ( "ghidra" ) . join ( plugin_name) ;
69+
70+ if plugin_path. exists ( ) {
71+ Some ( plugin_path)
72+ } else {
73+ None
74+ }
75+ }
76+
77+ fn get_path_from_env ( var : & str , filename : & str ) -> Option < path:: PathBuf > {
78+ let val = env:: var ( var) . ok ( ) ?;
79+ let path = path:: PathBuf :: from ( val) . join ( filename) ;
80+
81+ if path. exists ( ) {
82+ Some ( path)
83+ } else {
84+ None
85+ }
3086}
0 commit comments