Skip to content

Commit 42c2e7a

Browse files
authored
short-circuits evaluation of terms in Bap_main.init (#1349)
Now, if a plugin reports an error (by returning Error or raising an exception) we are not evaluating the commands. Before this change, the command was evaluated even if some plugins failed their evaluation.
1 parent d26adc2 commit 42c2e7a

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

lib/bap_main/bap_main.ml

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -976,9 +976,25 @@ end = struct
976976
let describe man =
977977
plugin_page := man @ !plugin_page
978978

979-
let (>>>) t1 t2 = Term.(const (fun t1 t2 -> match t1 with
980-
| Error _ as err -> err
981-
| Ok () -> t2) $ t1 $ t2)
979+
type term = (unit,error) Result.t Term.t
980+
981+
(* We can short-circuit the term evaluation, only
982+
via Term.(ret,term_result,cli_parse_result), which
983+
do not give us an option to pass the error value.
984+
Therefore, we had to rely on the ugly hack and keep
985+
it in a reference variable.
986+
*)
987+
988+
let term_evaluation_result = ref (Ok ())
989+
990+
(** [t1 >>> t2] evaluates [t1] and if succeeds evaluates [t2] *)
991+
let (>>>) : term -> term -> term = fun t1 t2 ->
992+
let f = Term.(const (function
993+
| Error _ as err ->
994+
term_evaluation_result := err;
995+
Error (`Msg "this message is ignored")
996+
| Ok () -> Ok (fun x -> x)) $ t1) in
997+
Term.(term_result f $ t2)
982998

983999
let concat_plugins () =
9841000
Hashtbl.fold plugin_specs ~init:unit ~f:(fun ~key:_ ~data:t1 t2 ->
@@ -1073,7 +1089,8 @@ end = struct
10731089
Term.(const serve_manpage $ served $ make_help_option plugin))
10741090

10751091
let eval ?(man="") ?(name=progname) ?version ?env
1076-
?(help=Format.std_formatter) ?default ?command ?err argv =
1092+
?(help=Format.std_formatter) ?default ?command
1093+
?err:(usr_err=Format.err_formatter) argv =
10771094
let plugin_names = Plugins.list () |> List.map ~f:Plugin.name in
10781095
let disabled_plugins = no_plugin_options plugin_names in
10791096
let plugin_options = concat_plugins () in
@@ -1102,12 +1119,20 @@ end = struct
11021119
then argv
11031120
else Array.of_list (prog::cmd::arg::rest)
11041121
| [_] | [] -> argv in
1105-
match Term.eval_choice ~catch:false ?env ~help ?err ~argv
1106-
(main,main_info) commands with
1122+
let buf = Buffer.create 64 in
1123+
let err = Format.formatter_of_buffer buf in
1124+
match Term.eval_choice (main,main_info) commands
1125+
?env ~help ~err ~argv ~catch:false with
1126+
| `Error `Exn -> assert false (*^^^^^^^^^^^ that's why*)
11071127
| `Ok (Ok ()) -> Ok ()
11081128
| `Ok (Error _ as err) -> err
11091129
| `Version | `Help -> Ok ()
1110-
| `Error _ -> Error Error.Configuration
1130+
| `Error (`Parse|`Term) -> match !term_evaluation_result with
1131+
| Ok () ->
1132+
Format.pp_print_flush err ();
1133+
Format.fprintf usr_err "%s@." (Buffer.contents buf);
1134+
Error Error.Configuration
1135+
| Error _ as err -> err
11111136
end
11121137

11131138
module Extension = struct

0 commit comments

Comments
 (0)