Moving printf args checker into Infer

Summary: public Refactoring Printfargs checker a bit to
make it callable from symbolic executor, then calling it.

Reviewed By: jeremydubreil

Differential Revision: D2361286

fb-gh-sync-id: 4b73855
master
Sam Blackshear 9 years ago committed by facebook-github-bot-7
parent 286d27be10
commit 04f92614e8

@ -281,7 +281,8 @@ def should_report(analyzer, row):
'RETAIN_CYCLE',
'ASSERTION_FAILURE',
'ACTIVITY_LEAK',
'BAD_POINTER_COMPARISON'
'BAD_POINTER_COMPARISON',
'CHECKERS_PRINTF_ARGS'
]
if analyzer in [ERADICATE, CHECKERS, TRACING]:

@ -826,6 +826,9 @@ let normalize_params pdesc prop actual_params =
let prop, args = IList.fold_left norm_arg (prop, []) actual_params in
(prop, IList.rev args)
let do_error_checks node instr pname pdesc =
if !Config.curr_language = Config.Java then PrintfArgs.check_printf_args_ok node instr pname pdesc
(** Execute [instr] with a symbolic heap [prop].*)
let rec sym_exec cfg tenv pdesc _instr (_prop: Prop.normal Prop.t) path
: (Prop.normal Prop.t * Paths.Path.t) list =
@ -948,6 +951,7 @@ let rec sym_exec cfg tenv pdesc _instr (_prop: Prop.normal Prop.t) path
sym_exe_builtin cfg pdesc instr tenv _prop path ret_ids args callee_pname loc
| Sil.Call (ret_ids, Sil.Const (Sil.Cfun callee_pname), actual_params, loc, call_flags) ->
(** Generic fun call with known name *)
do_error_checks (Paths.Path.curr_node path) instr pname pdesc;
let (prop_r, _n_actual_params) = normalize_params pname _prop actual_params in
let fn, n_actual_params = handle_special_cases_call tenv cfg callee_pname _n_actual_params in
let resolved_pname =

@ -122,13 +122,11 @@ let rec format_string_type_names
let printf_args_name = "CHECKERS_PRINTF_ARGS"
let callback_printf_args
(all_procs : Procname.t list)
(get_proc_desc: Procname.t -> Cfg.Procdesc.t option)
(idenv: Idenv.t)
(tenv: Sil.tenv)
let check_printf_args_ok
(node: Cfg.Node.t)
(instr: Sil.instr)
(proc_name: Procname.t)
(proc_desc : Cfg.Procdesc.t) : unit =
(proc_desc: Cfg.Procdesc.t): unit =
(* Check if format string lines up with arguments *)
let rec check_type_names instr_loc n_arg instr_proc_name fmt_type_names arg_type_names =
@ -184,44 +182,49 @@ let callback_printf_args
| Sil.Const c -> PatternMatch.java_get_const_type_name c
| _ -> raise (Failure "Could not resolve fixed type name") in
let do_instr
(node: Cfg.Node.t)
(instr: Sil.instr): unit =
match instr with
| Sil.Call (_, Sil.Const (Sil.Cfun pn), args, cl, _) -> (
match printf_like_function pn with
| Some printf -> (
try
let fmt, fixed_nvars, array_nvar = format_arguments printf args in
let instrs = Cfg.Node.get_instrs node in
let fixed_nvar_type_names = IList.map (fixed_nvar_type_name instrs) fixed_nvars in
let vararg_ivar_type_names = match array_nvar with
| Some nvar -> (
let ivar = array_ivar instrs nvar in
PatternMatch.get_vararg_type_names node ivar)
| None -> [] in
match fmt with
| Some fmt ->
check_type_names
cl
(printf.format_pos + 1)
pn
(format_string_type_names fmt 0)
(fixed_nvar_type_names@ vararg_ivar_type_names)
| None ->
Checkers.ST.report_error
proc_name
proc_desc
printf_args_name
cl
"Format string must be string literal"
with e ->
L.stderr
"%s Exception when analyzing %s: %s@."
printf_args_name
(Procname.to_string proc_name)
(Printexc.to_string e))
| None -> ())
| _ -> () in
Cfg.Procdesc.iter_instrs do_instr proc_desc
match instr with
| Sil.Call (_, Sil.Const (Sil.Cfun pn), args, cl, _) -> (
match printf_like_function pn with
| Some printf -> (
try
let fmt, fixed_nvars, array_nvar = format_arguments printf args in
let instrs = Cfg.Node.get_instrs node in
let fixed_nvar_type_names = IList.map (fixed_nvar_type_name instrs) fixed_nvars in
let vararg_ivar_type_names = match array_nvar with
| Some nvar -> (
let ivar = array_ivar instrs nvar in
PatternMatch.get_vararg_type_names node ivar)
| None -> [] in
match fmt with
| Some fmt ->
check_type_names
cl
(printf.format_pos + 1)
pn
(format_string_type_names fmt 0)
(fixed_nvar_type_names@ vararg_ivar_type_names)
| None ->
Checkers.ST.report_error
proc_name
proc_desc
printf_args_name
cl
"Format string must be string literal"
with e ->
L.stderr
"%s Exception when analyzing %s: %s@."
printf_args_name
(Procname.to_string proc_name)
(Printexc.to_string e))
| None -> ())
| _ -> ()
let callback_printf_args
(all_procs : Procname.t list)
(get_proc_desc: Procname.t -> Cfg.Procdesc.t option)
(idenv: Idenv.t)
(tenv: Sil.tenv)
(proc_name: Procname.t)
(proc_desc : Cfg.Procdesc.t) : unit =
Cfg.Procdesc.iter_instrs (fun n i -> check_printf_args_ok n i proc_name proc_desc) proc_desc

@ -17,5 +17,6 @@ type printf_signature = {
val add_printf_like_function : printf_signature -> unit
val check_printf_args_ok : Cfg.Node.t -> Sil.instr -> Procname.t -> Cfg.Procdesc.t -> unit
val callback_printf_args: Callbacks.proc_callback_t

Loading…
Cancel
Save