[config] normalize all paths options

Summary:
If the project root contains ".." then it doesn't work as expected, eg

  infer --project-root .. -- clang hello.c

doesn't report at all. Now it works.

Reviewed By: jeremydubreil

Differential Revision: D4125489

fbshipit-source-id: 06b10ad
master
Jules Villard 8 years ago committed by Facebook Github Bot
parent 15ddf8b921
commit 2f5d132734

@ -394,7 +394,7 @@ let should_report (issue_kind: Exceptions.err_kind) issue_type error_desc =>
};
let is_file source_file =>
switch (Unix.stat (DB.source_file_to_string source_file)) {
switch (Unix.stat (DB.source_file_to_abs_path source_file)) {
| {st_kind: S_REG | S_LNK} => true
| _ => false
| exception Unix.Unix_error _ => false
@ -496,17 +496,17 @@ let module IssuesJson = {
} else {
file
};
let make_cpp_models_path_relative file =>
if (Utils.string_is_prefix Config.cpp_models_dir file) {
let make_cpp_models_path_relative file => {
let abs_file = DB.source_file_to_abs_path file;
if (Utils.string_is_prefix Config.cpp_models_dir abs_file) {
if (Config.debug_mode || Config.debug_exceptions) {
Some (
DB.source_file_to_rel_path (DB.rel_source_file_from_abs_path Config.cpp_models_dir file)
)
Some (DB.rel_source_file_from_abs_path Config.cpp_models_dir abs_file)
} else {
None
}
} else {
Some file
}
};
/** Write bug report in JSON format */
@ -529,8 +529,7 @@ let module IssuesJson = {
| Some proc_loc => proc_loc.Location.file
| None => loc.Location.file
};
let file = DB.source_file_to_string source_file;
let file_opt = make_cpp_models_path_relative file;
let file_opt = make_cpp_models_path_relative source_file;
if (
in_footprint &&
error_filter source_file error_desc error_name &&
@ -539,7 +538,7 @@ let module IssuesJson = {
let kind = Exceptions.err_kind_string ekind;
let bug_type = Localise.to_string error_name;
let procedure_id = Procname.to_filename procname;
let file = expand_links_under_buck_out (Option.get file_opt);
let file = expand_links_under_buck_out (DB.source_file_to_string (Option.get file_opt));
let json_ml_loc =
switch ml_loc_opt {
| Some (file, lnum, cnum, enum) when Config.reports_include_ml_loc =>

@ -322,23 +322,6 @@ let mk_string ~default ?(f=fun s -> s) ?(deprecated=[]) ~long ?short ?exes ?(met
~decode_json:(string_json_decoder ~long)
~mk_spec:(fun set -> Arg.String set)
let mk_path ~default ?(deprecated=[]) ~long ?short ?exes ?(meta="") doc =
mk ~deprecated ~long ?short ~default ?exes ~meta doc
~default_to_string:(fun s -> s)
~mk_setter:(fun var str ->
if Filename.is_relative str then (
(* Replace relative paths with absolute ones on the fly in the args being parsed. This
assumes that [!arg_being_parsed] points at the option name position in
[!args_to_parse], as is the case e.g. when calling [Arg.parse_argv_dynamic
~current:arg_being_parsed !args_to_parse ...]. *)
let abs_path = Sys.getcwd () // str in
var := abs_path;
(!args_to_parse).(!arg_being_parsed + 1) <- abs_path;
) else
var := str)
~decode_json:(string_json_decoder ~long)
~mk_spec:(fun set -> Arg.String set)
let mk_string_opt ?default ?(f=fun s -> s) ?(deprecated=[]) ~long ?short ?exes ?(meta="") doc =
let default_to_string = function Some s -> s | None -> "" in
let f s = Some (f s) in
@ -352,6 +335,43 @@ let mk_string_list ?(default=[]) ?(f=fun s -> s)
~decode_json:(list_json_decoder (string_json_decoder ~long))
~mk_spec:(fun set -> Arg.String set)
let mk_path_helper ~setter ~default_to_string
~default ~deprecated ~long ~short ~exes ~meta doc =
let normalize_path_in_args_being_parsed str =
if Filename.is_relative str then (
(* Replace relative paths with absolute ones on the fly in the args being parsed. This assumes
that [!arg_being_parsed] points at the option name position in [!args_to_parse], as is the
case e.g. when calling
[Arg.parse_argv_dynamic ~current:arg_being_parsed !args_to_parse ...]. *)
let abs_path = filename_to_absolute str in
(!args_to_parse).(!arg_being_parsed + 1) <- abs_path;
abs_path
) else
str in
mk ~deprecated ~long ?short ~default ?exes ~meta doc
~default_to_string
~mk_setter:(fun var str ->
let abs_path = normalize_path_in_args_being_parsed str in
setter var abs_path)
~decode_json:(string_json_decoder ~long)
~mk_spec:(fun set -> Arg.String set)
let mk_path ~default ?(deprecated=[]) ~long ?short ?exes ?(meta="path") =
mk_path_helper ~setter:(fun var x -> var := x) ~default_to_string:(fun s -> s)
~default ~deprecated ~long ~short ~exes ~meta
let mk_path_opt ?default ?(deprecated=[]) ~long ?short ?exes ?(meta="path") =
mk_path_helper
~setter:(fun var x -> var := Some x)
~default_to_string:(function Some s -> s | None -> "")
~default ~deprecated ~long ~short ~exes ~meta
let mk_path_list ?(default=[]) ?(deprecated=[]) ~long ?short ?exes ?(meta="path") =
mk_path_helper
~setter:(fun var x -> var := x :: !var)
~default_to_string:(String.concat ", ")
~default ~deprecated ~long ~short ~exes ~meta
let mk_symbol ~default ~symbols ?(deprecated=[]) ~long ?short ?exes ?(meta="") doc =
let strings = IList.map fst symbols in
let sym_to_str = IList.map (fun (x,y) -> (y,x)) symbols in

@ -66,8 +66,6 @@ val mk_float : default:float -> float ref t
val mk_string : default:string -> ?f:(string -> string) -> string ref t
val mk_path : default:string -> string ref t
val mk_string_opt : ?default:string -> ?f:(string -> string) -> string option ref t
(** [mk_string_list] defines a [string list ref], initialized to [[]] unless overridden by
@ -76,6 +74,16 @@ val mk_string_opt : ?default:string -> ?f:(string -> string) -> string option re
val mk_string_list :
?default:string list -> ?f:(string -> string) -> string list ref t
(** like [mk_string] but will resolve the string into an absolute path so that children processes
agree on the absolute path that the option represents *)
val mk_path : default:string -> string ref t
(** analogous of [mk_string_opt] with the extra feature of [mk_path] *)
val mk_path_opt : ?default:string -> string option ref t
(** analogous of [mk_string_list] with the extra feature of [mk_path] *)
val mk_path_list : ?default:string list -> string list ref t
(** [mk_symbol long symbols] defines a command line flag [--long <symbol>] where [(<symbol>,_)] is
an element of [symbols]. *)
val mk_symbol : default:'a -> symbols:(string * 'a) list -> 'a ref t

@ -411,11 +411,7 @@ let init_work_dir, is_originator =
(** Resolve relative paths passed as command line options, i.e., with respect to the working
directory of the initial invocation of infer. *)
let resolve path =
if Filename.is_relative path then
init_work_dir // path
else
path
let resolve = filename_to_absolute
(** Command Line options *)
@ -424,13 +420,12 @@ let resolve path =
let inferconfig_home =
let all_exes = IList.map snd CLOpt.exes in
CLOpt.mk_string_opt ~long:"inferconfig-home"
CLOpt.mk_path_opt ~long:"inferconfig-home"
~exes:all_exes ~meta:"dir" "Path to the .inferconfig file"
and project_root =
CLOpt.mk_string ~deprecated:["project_root"; "-project_root"] ~long:"project-root" ~short:"pr"
CLOpt.mk_path ~deprecated:["project_root"; "-project_root"] ~long:"project-root" ~short:"pr"
~default:init_work_dir
~f:resolve
~exes:CLOpt.[Analyze;Clang;Java;Print;Toplevel]
~meta:"dir" "Specify the root directory of the project"
@ -587,7 +582,7 @@ and array_level =
- 2 = assumes that all heap dereferences via array indexing and pointer \
arithmetic are correct"
and ast_file =
CLOpt.mk_string_opt ~long:"ast-file" ~short:"ast"
CLOpt.mk_path_opt ~long:"ast-file" ~short:"ast"
~meta:"file" "AST file for the translation"
and blacklist =
@ -607,45 +602,45 @@ and buck_build_args =
"Pass values as command-line arguments to invocations of `buck build` (Buck flavors only)"
and buck_out =
CLOpt.mk_string_opt ~long:"buck-out"
CLOpt.mk_path_opt ~long:"buck-out"
~exes:CLOpt.[Toplevel] ~meta:"dir" "Specify the root directory of buck-out"
and bugs_csv =
CLOpt.mk_string_opt ~deprecated:["bugs"] ~long:"issues-csv"
CLOpt.mk_path_opt ~deprecated:["bugs"] ~long:"issues-csv"
~exes:CLOpt.[Toplevel;Print]
~meta:"file" "Write a list of issues in CSV format to a file"
and bugs_json =
CLOpt.mk_string_opt ~deprecated:["bugs_json"] ~long:"issues-json"
CLOpt.mk_path_opt ~deprecated:["bugs_json"] ~long:"issues-json"
~exes:CLOpt.[Toplevel;Print]
~meta:"file" "Write a list of issues in JSON format to a file"
and bugs_tests =
CLOpt.mk_string_opt ~long:"issues-tests"
CLOpt.mk_path_opt ~long:"issues-tests"
~exes:CLOpt.[Toplevel;Print]
~meta:"file"
"Write a list of issues in a format suitable for tests to a file"
and bugs_txt =
CLOpt.mk_string_opt ~deprecated:["bugs_txt"] ~long:"issues-txt"
CLOpt.mk_path_opt ~deprecated:["bugs_txt"] ~long:"issues-txt"
~exes:CLOpt.[Toplevel;Print]
~meta:"file"
"Write a list of issues in TXT format to a file"
and bugs_xml =
CLOpt.mk_string_opt ~deprecated:["bugs_xml"] ~long:"issues-xml"
CLOpt.mk_path_opt ~deprecated:["bugs_xml"] ~long:"issues-xml"
~exes:CLOpt.[Toplevel;Print]
~meta:"file"
"Write a list of issues in XML format to a file"
and calls_csv =
CLOpt.mk_string_opt ~deprecated:["calls"] ~long:"calls-csv"
CLOpt.mk_path_opt ~deprecated:["calls"] ~long:"calls-csv"
~exes:CLOpt.[Toplevel;Print]
~meta:"file"
"Write individual calls in CSV format to a file"
and changed_files_index =
CLOpt.mk_string_opt ~long:"changed-files-index" ~exes:CLOpt.[Toplevel] ~meta:"file"
CLOpt.mk_path_opt ~long:"changed-files-index" ~exes:CLOpt.[Toplevel] ~meta:"file"
"Specify the file containing the list of files from which reactive analysis should start"
and check_duplicate_symbols =
@ -680,11 +675,11 @@ and checkers_repeated_calls =
"Check for repeated calls"
and clang_biniou_file =
CLOpt.mk_string_opt ~long:"clang-biniou-file" ~exes:CLOpt.[Clang] ~meta:"file"
CLOpt.mk_path_opt ~long:"clang-biniou-file" ~exes:CLOpt.[Clang] ~meta:"file"
"Specify a file containing the AST of the program, in biniou format"
and clang_compilation_database =
CLOpt.mk_string_opt ~long:"clang-compilation-database"
CLOpt.mk_path_opt ~long:"clang-compilation-database"
~exes:CLOpt.[BuckCompilationDatabase] ~meta:"file"
"Specify a json file containing a clang compilation database to be used for the analysis"
@ -705,7 +700,7 @@ and _ =
~meta:"path" "Specify where to find user class files and annotation processors"
and cluster =
CLOpt.mk_string_opt ~deprecated:["cluster"] ~long:"cluster"
CLOpt.mk_path_opt ~deprecated:["cluster"] ~long:"cluster"
~meta:"file" "Specify a .cluster file to be analyzed"
(** Continue the capture for reactive mode:
@ -887,7 +882,7 @@ and failures_allowed =
"Fail if at least one of the translations fails (clang only)"
and fcp_apple_clang =
CLOpt.mk_string_opt ~long:"fcp-apple-clang"
CLOpt.mk_path_opt ~long:"fcp-apple-clang"
~meta:"path" "Specify the path to Apple Clang"
and fcp_syntax_only =
@ -924,7 +919,7 @@ and headers =
"Analyze code in header files"
and infer_cache =
CLOpt.mk_string_opt ~deprecated:["infer_cache"; "-infer_cache"] ~long:"infer-cache" ~f:resolve
CLOpt.mk_path_opt ~deprecated:["infer_cache"; "-infer_cache"] ~long:"infer-cache"
~meta:"dir" "Select a directory to contain the infer cache (Buck and Java only)"
and iterations =
@ -934,7 +929,7 @@ and iterations =
symbolic operations and a multiple of seconds of elapsed time"
and java_jar_compiler =
CLOpt.mk_string_opt
CLOpt.mk_path_opt
~long:"java-jar-compiler"
~exes:CLOpt.[Java]
~meta:"path" "Specifify the Java compiler jar used to generate the bytecode"
@ -950,12 +945,12 @@ and join_cond =
- 1 = use the least aggressive join for preconditions"
and latex =
CLOpt.mk_string_opt ~deprecated:["latex"] ~long:"latex"
CLOpt.mk_path_opt ~deprecated:["latex"] ~long:"latex"
~meta:"file"
"Write a latex report of the analysis results to a file"
and linters_def_file =
CLOpt.mk_string_opt ~long:"linters-def-file" ~exes:CLOpt.[Clang]
CLOpt.mk_path_opt ~long:"linters-def-file" ~exes:CLOpt.[Clang]
~meta:"file" "Specify the file containing linters definition"
and load_average =
@ -965,13 +960,13 @@ and load_average =
make only)"
and load_results =
CLOpt.mk_string_opt ~deprecated:["load_results"] ~long:"load-results"
CLOpt.mk_path_opt ~deprecated:["load_results"] ~long:"load-results"
~exes:CLOpt.[Print]
~meta:"file.iar" "Load analysis results from Infer Analysis Results file file.iar"
(** name of the makefile to create with clusters and dependencies *)
and makefile =
CLOpt.mk_string ~deprecated:["makefile"] ~long:"makefile" ~default:""
CLOpt.mk_path ~deprecated:["makefile"] ~long:"makefile" ~default:""
~meta:"file" ""
and margin =
@ -995,7 +990,7 @@ and ml_buckets =
~symbols:ml_bucket_symbols
and models_file =
CLOpt.mk_string_opt ~deprecated:["models"] ~long:"models" ~f:resolve
CLOpt.mk_path_opt ~deprecated:["models"] ~long:"models"
~exes:CLOpt.[Analyze;Java] ~meta:"jar file" "Specify a jar file containing the Java models"
and models_mode =
@ -1003,7 +998,7 @@ and models_mode =
"Mode for analyzing the models"
and modified_targets =
CLOpt.mk_string_opt ~deprecated:["modified_targets"] ~long:"modified-targets"
CLOpt.mk_path_opt ~deprecated:["modified_targets"] ~long:"modified-targets"
~meta:"file" "Read the file of Buck targets modified since the last analysis"
and monitor_prop_size =
@ -1028,7 +1023,7 @@ and optimistic_cast =
"Allow cast of undefined values"
and out_file =
CLOpt.mk_string ~deprecated:["out_file"] ~long:"out-file" ~default:""
CLOpt.mk_path ~deprecated:["out_file"] ~long:"out-file" ~default:""
~meta:"file" "Specify the file for the non-error logs of the analyzer"
and (
@ -1065,11 +1060,11 @@ and print_using_diff =
"Highlight the difference w.r.t. the previous prop when printing symbolic execution debug info"
and procs_csv =
CLOpt.mk_string_opt ~deprecated:["procs"] ~long:"procs-csv"
CLOpt.mk_path_opt ~deprecated:["procs"] ~long:"procs-csv"
~meta:"file" "Write statistics for each procedure in CSV format to a file"
and procs_xml =
CLOpt.mk_string_opt ~deprecated:["procs_xml"] ~long:"procs-xml"
CLOpt.mk_path_opt ~deprecated:["procs_xml"] ~long:"procs-xml"
~meta:"file"
"Write statistics for each procedure in XML format to a file (as a path relative to \
--results-dir)"
@ -1089,7 +1084,7 @@ and reactive =
"Reactive mode: the analysis starts from the files captured since the `infer` command started"
and report =
CLOpt.mk_string_opt ~deprecated:["report"] ~long:"report"
CLOpt.mk_path_opt ~deprecated:["report"] ~long:"report"
~meta:"file" "Write a report of the analysis results to a file"
and report_custom_error =
@ -1103,7 +1098,7 @@ and results_dir =
~meta:"dir" "Write results and internal files in the specified directory"
and save_results =
CLOpt.mk_string_opt ~deprecated:["save_results"] ~long:"save-results"
CLOpt.mk_path_opt ~deprecated:["save_results"] ~long:"save-results"
~meta:"file.iar" "Save analysis results to Infer Analysis Results file file.iar"
and seconds_per_iteration =
@ -1137,7 +1132,7 @@ and spec_abs_level =
and specs_library =
let specs_library =
CLOpt.mk_string_list ~long:"specs-library" ~short:"lib" ~f:resolve
CLOpt.mk_path_list ~long:"specs-library" ~short:"lib"
~meta:"dir|jar" "Search for .spec files in given directory or jar file" in
let _ =
(* Given a filename with a list of paths, convert it into a list of string iff they are
@ -1163,13 +1158,13 @@ and specs_library =
specs_library
and stacktrace =
CLOpt.mk_string_opt ~long:"stacktrace" ~short:"st" ~f:resolve ~exes:CLOpt.[Toplevel]
CLOpt.mk_path_opt ~long:"stacktrace" ~short:"st" ~exes:CLOpt.[Toplevel]
~meta:"file" "File path containing a json-encoded Java crash stacktrace. Used to guide the \
analysis (only with '-a crashcontext'). See \
tests/codetoanalyze/java/crashcontext/*.json for examples of the expected format."
and stacktraces_dir =
CLOpt.mk_string_opt ~long:"stacktraces-dir" ~f:resolve ~exes:CLOpt.[Toplevel]
CLOpt.mk_path_opt ~long:"stacktraces-dir" ~exes:CLOpt.[Toplevel]
~meta:"dir" "Directory path containing multiple json-encoded Java crash stacktraces. \
Used to guide the analysis (only with '-a crashcontext'). See \
tests/codetoanalyze/java/crashcontext/*.json for examples of the expected format."
@ -1183,7 +1178,7 @@ and subtype_multirange =
(* Path to list of collected @SuppressWarnings annotations *)
and suppress_warnings_out =
CLOpt.mk_string_opt ~deprecated:["suppress_warnings_out"] ~long:suppress_warnings_annotations_long
CLOpt.mk_path_opt ~deprecated:["suppress_warnings_out"] ~long:suppress_warnings_annotations_long
~meta:"path" ""
and svg =
@ -1240,7 +1235,7 @@ and use_compilation_database =
(** Set the path to the javac verbose output *)
and verbose_out =
CLOpt.mk_string ~deprecated:["verbose_out"] ~long:"verbose-out" ~default:""
CLOpt.mk_path ~deprecated:["verbose_out"] ~long:"verbose-out" ~default:""
~meta:"file" ""
and version =
@ -1275,7 +1270,7 @@ and worklist_mode =
var
and xcode_developer_dir =
CLOpt.mk_string_opt ~long:"xcode-developer-dir"
CLOpt.mk_path_opt ~long:"xcode-developer-dir"
~exes:CLOpt.[Toplevel]
~meta:"XCODE_DEVELOPER_DIR" "Specify the path to Xcode developer directory (Buck flavors only)"

@ -88,13 +88,12 @@ let of_string s =
make exception_name parsed
| [] -> failwith "Empty stack trace"
let of_json json =
let of_json filename json =
let exception_name_key = "exception_type" in
let frames_key = "stack_trace" in
let extract_json_member key =
match Yojson.Basic.Util.member key json with
| `Null -> failwith ("Missing key in supplied JSON \
data: " ^ key)
| `Null -> failwithf "Missing key in supplied JSON data: %s (in file %s)" key filename
| item -> item in
let exception_name =
Yojson.Basic.Util.to_string (extract_json_member exception_name_key) in
@ -107,7 +106,8 @@ let of_json json =
make exception_name frames
let of_json_file filename =
match Utils.read_optional_json_file filename with
| Ok json -> of_json json
| Error msg -> failwith (Printf.sprintf "Could not read or parse the supplied JSON \
stacktrace file %s :\n %s" filename msg)
try
of_json filename (Yojson.Basic.from_file filename)
with Sys_error msg | Yojson.Json_error msg ->
failwithf "Could not read or parse the supplied JSON stacktrace file %s :\n %s"
filename msg

Loading…
Cancel
Save