[sledge] Protect Trace.parse from invalid user input

Summary:
Trace.parse is exposed across a module boundary, so handle its own
exceptions and return an `error`.

Reviewed By: mbouaziz

Differential Revision: D14081602

fbshipit-source-id: 4087c5d5b
master
Josh Berdine 6 years ago committed by Facebook Github Bot
parent 5a3718a098
commit 65c446f0fb

@ -9,8 +9,9 @@
let trace_conv = let trace_conv =
let parse s = let parse s =
try Ok (Trace.parse s).trace_mods_funs with _ -> match Trace.parse s with
Error (`Msg ("Invalid trace spec: " ^ s)) | Ok c -> Ok c.trace_mods_funs
| Error err -> Error err
in in
let print fs c = let print fs c =
let pf fmt = Format.fprintf fs fmt in let pf fmt = Format.fprintf fs fmt in

@ -24,53 +24,55 @@ let all = {none with trace_all= true}
let config : config ref = ref none let config : config ref = ref none
let parse s = let parse s =
let default = Map.empty (module String) in try
let index_from s i = let default = Map.empty (module String) in
Option.merge ~f:min let index_from s i =
(String.index_from s i '+') Option.merge ~f:min
(String.index_from s i '-') (String.index_from s i '+')
in (String.index_from s i '-')
let rec split s rev_parts i = in
match index_from s (i + 1) with let rec split s rev_parts i =
| Some j when j = i -> split s rev_parts j match index_from s (i + 1) with
| Some j -> split s (String.sub s ~pos:i ~len:(j - i) :: rev_parts) j | Some j when j = i -> split s rev_parts j
| _ -> List.rev (String.subo s ~pos:i :: rev_parts) | Some j -> split s (String.sub s ~pos:i ~len:(j - i) :: rev_parts) j
in | _ -> List.rev (String.subo s ~pos:i :: rev_parts)
let parts = split s [] 0 in in
let trace_mods_funs = let parts = split s [] 0 in
List.fold parts ~init:default ~f:(fun m part -> let trace_mods_funs =
let parse_part part = List.fold parts ~init:default ~f:(fun m part ->
let sign, rest = let parse_part part =
match part.[0] with let sign, rest =
| '-' -> (false, String.subo part ~pos:1) match part.[0] with
| '+' -> (true, String.subo part ~pos:1) | '-' -> (false, String.subo part ~pos:1)
| _ -> (true, part) | '+' -> (true, String.subo part ~pos:1)
in | _ -> (true, part)
assert (not (String.is_empty rest)) ;
assert (Char.is_uppercase rest.[0]) ;
match String.lsplit2 rest ~on:'.' with
| Some (mod_name, fun_name) ->
assert (Char.is_lowercase fun_name.[0]) ;
(mod_name, Some fun_name, sign)
| None -> (rest, None, sign)
in
match parse_part part with
| mod_name, Some fun_name, enabled ->
let {trace_mod; trace_funs} =
match Map.find m mod_name with
| Some c -> c
| None -> {trace_mod= None; trace_funs= default}
in in
Map.set m ~key:mod_name assert (not (String.is_empty rest)) ;
~data: assert (Char.is_uppercase rest.[0]) ;
{ trace_mod match String.lsplit2 rest ~on:'.' with
; trace_funs= Map.set trace_funs ~key:fun_name ~data:enabled | Some (mod_name, fun_name) ->
} assert (Char.is_lowercase fun_name.[0]) ;
| mod_name, None, enabled -> (mod_name, Some fun_name, sign)
Map.set m ~key:mod_name | None -> (rest, None, sign)
~data:{trace_mod= Some enabled; trace_funs= default} ) in
in match parse_part part with
{none with trace_mods_funs} | mod_name, Some fun_name, enabled ->
let {trace_mod; trace_funs} =
match Map.find m mod_name with
| Some c -> c
| None -> {trace_mod= None; trace_funs= default}
in
Map.set m ~key:mod_name
~data:
{ trace_mod
; trace_funs=
Map.set trace_funs ~key:fun_name ~data:enabled }
| mod_name, None, enabled ->
Map.set m ~key:mod_name
~data:{trace_mod= Some enabled; trace_funs= default} )
in
Ok {none with trace_mods_funs}
with Assert_failure _ -> Error (`Msg ("Invalid trace spec: " ^ s))
let init ?(margin = 300) ~config:c () = let init ?(margin = 300) ~config:c () =
Format.set_margin margin ; Format.set_margin margin ;

@ -23,7 +23,7 @@ type config =
val none : config val none : config
val all : config val all : config
val parse : string -> config val parse : string -> (config, [> `Msg of string]) result
val init : ?margin:int -> config:config -> unit -> unit val init : ?margin:int -> config:config -> unit -> unit
(** Initialize the configuration of debug tracing. *) (** Initialize the configuration of debug tracing. *)

Loading…
Cancel
Save