[infer][java] make the translation and analysis of abstract methods and native methods consistent

Summary: With this, we can now get now get inter-procedural issues involving native methods.

Reviewed By: sblackshear

Differential Revision: D5730638

fbshipit-source-id: 3bdbdbd
master
Jeremy Dubreil 7 years ago committed by Facebook Github Bot
parent a03f765d8f
commit 1a221e798c

@ -39,6 +39,13 @@ let is_active, add_active, remove_active =
in
(is_active, add_active, remove_active)
let should_create_summary proc_name proc_attributes =
match proc_name with
| Typ.Procname.Java _
-> true
| _
-> proc_attributes.ProcAttributes.is_defined
let should_be_analyzed proc_name proc_attributes =
let already_analyzed () =
match Specs.get_summary proc_name with
@ -47,12 +54,9 @@ let should_be_analyzed proc_name proc_attributes =
| None
-> false
in
proc_attributes.ProcAttributes.is_defined
(* we have the implementation *)
&& not (is_active proc_name) && (* avoid infinite loops *)
not (already_analyzed ())
(* avoid re-analysis of the same procedure *)
should_create_summary proc_name proc_attributes && not (is_active proc_name)
&& (* avoid infinite loops *)
not (already_analyzed ())
let procedure_should_be_analyzed proc_name =
match Specs.proc_resolve_attributes proc_name with
@ -135,8 +139,13 @@ let run_proc_analysis analyze_proc curr_pdesc callee_pdesc =
let old_state = save_global_state () in
let initial_summary = preprocess () in
try
let summary = analyze_proc initial_summary callee_pdesc |> postprocess in
restore_global_state old_state ; summary
let attributes = Procdesc.get_attributes callee_pdesc in
let summary =
if attributes.ProcAttributes.is_defined then analyze_proc initial_summary callee_pdesc
else initial_summary
in
let final_summary = postprocess summary in
restore_global_state old_state ; final_summary
with exn ->
L.internal_error "@\nONDEMAND EXCEPTION %a %s@.@.BACK TRACE@.%s@?" Typ.Procname.pp callee_pname
(Exn.to_string exn) (Printexc.get_backtrace ()) ;

@ -275,6 +275,16 @@ let trans_access = function
| `Protected
-> PredSymb.Protected
let create_empty_cfg proc_name source_file procdesc =
let start_kind = Procdesc.Node.Start_node proc_name in
let start_node = Procdesc.create_node procdesc (Location.none source_file) start_kind [] in
let exit_kind = Procdesc.Node.Exit_node proc_name in
let exit_node = Procdesc.create_node procdesc (Location.none source_file) exit_kind [] in
Procdesc.node_set_succs_exn procdesc start_node [exit_node] [exit_node] ;
Procdesc.set_start_node procdesc start_node ;
Procdesc.set_exit_node procdesc exit_node ;
procdesc
let create_am_procdesc source_file program icfg am proc_name : Procdesc.t =
let cfg = icfg.JContext.cfg in
let tenv = icfg.JContext.tenv in
@ -290,7 +300,6 @@ let create_am_procdesc source_file program icfg am proc_name : Procdesc.t =
; formals
; is_abstract= true
; is_bridge_method= am.Javalib.am_bridge
; is_defined= true
; is_model= Config.models_mode
; is_synthetic_method= am.Javalib.am_synthetic
; method_annotation
@ -299,14 +308,7 @@ let create_am_procdesc source_file program icfg am proc_name : Procdesc.t =
in
Cfg.create_proc_desc cfg proc_attributes
in
let start_kind = Procdesc.Node.Start_node proc_name in
let start_node = Procdesc.create_node procdesc (Location.none source_file) start_kind [] in
let exit_kind = Procdesc.Node.Exit_node proc_name in
let exit_node = Procdesc.create_node procdesc (Location.none source_file) exit_kind [] in
Procdesc.node_set_succs_exn procdesc start_node [exit_node] [exit_node] ;
Procdesc.set_start_node procdesc start_node ;
Procdesc.set_exit_node procdesc exit_node ;
procdesc
create_empty_cfg proc_name source_file procdesc
let create_native_procdesc source_file program icfg cm proc_name =
let cfg = icfg.JContext.cfg in
@ -315,19 +317,22 @@ let create_native_procdesc source_file program icfg cm proc_name =
let cn, ms = JBasics.cms_split (Javalib.get_class_method_signature m) in
let formals = formals_from_signature program tenv cn ms (JTransType.get_method_kind m) in
let method_annotation = JAnnotation.translate_method cm.Javalib.cm_annotations in
let proc_attributes =
{ (ProcAttributes.default proc_name Config.Java) with
ProcAttributes.access= trans_access cm.Javalib.cm_access
; exceptions= List.map ~f:JBasics.cn_name cm.Javalib.cm_exceptions
; formals
; is_bridge_method= cm.Javalib.cm_bridge
; is_model= Config.models_mode
; is_synthetic_method= cm.Javalib.cm_synthetic
; method_annotation
; ret_type= JTransType.return_type program tenv ms
; loc= Location.none source_file }
let procdesc =
let proc_attributes =
{ (ProcAttributes.default proc_name Config.Java) with
ProcAttributes.access= trans_access cm.Javalib.cm_access
; exceptions= List.map ~f:JBasics.cn_name cm.Javalib.cm_exceptions
; formals
; is_bridge_method= cm.Javalib.cm_bridge
; is_model= Config.models_mode
; is_synthetic_method= cm.Javalib.cm_synthetic
; method_annotation
; ret_type= JTransType.return_type program tenv ms
; loc= Location.none source_file }
in
Cfg.create_proc_desc cfg proc_attributes
in
Cfg.create_proc_desc cfg proc_attributes
create_empty_cfg proc_name source_file procdesc
(** Creates a procedure description. *)
let create_cm_procdesc source_file program linereader icfg cm proc_name =

@ -1,4 +1,5 @@
infer/tests/build_systems/genrule/module1/Class1.java, void Class1.localNPE1(), 2, NULL_DEREFERENCE, [start of procedure localNPE1()]
infer/tests/build_systems/genrule/module2/Class2.java, void Class2.interTargetAbstractNPE(Class1), 2, NULL_DEREFERENCE, [start of procedure interTargetAbstractNPE(...),Skipping abstractMayReturnNull(): function or method not found]
infer/tests/build_systems/genrule/module2/Class2.java, void Class2.interTargetNPE(), 2, NULL_DEREFERENCE, [start of procedure interTargetNPE(),start of procedure returnsNull(),return from a call to String Class1.returnsNull()]
infer/tests/build_systems/genrule/module2/Class2.java, void Class2.interTargetNativeNPE(Class1), 2, NULL_DEREFERENCE, [start of procedure interTargetNativeNPE(...),Skipping nativeMayReturnNull(): function or method not found]
infer/tests/build_systems/genrule/module2/Class2.java, void Class2.localNPE2(), 2, NULL_DEREFERENCE, [start of procedure localNPE2()]

@ -28,7 +28,7 @@ public class Class2 {
obj.toString();
}
void FN_interTargetNativeNPE(Class1 class1) {
void interTargetNativeNPE(Class1 class1) {
Object obj = class1.nativeMayReturnNull();
obj.toString();
}

@ -73,7 +73,7 @@ public abstract class UnknownCode {
propagateFootprint((String) InferTaint.inferSecretSource());
}
static void FN_propagateViaInterfaceCodeBad(Interface i) {
static void propagateViaInterfaceCodeBad(Interface i) {
Object source = InferTaint.inferSecretSource();
Object launderedSource = i.interfaceMethod(source);
InferTaint.inferSensitiveSink(launderedSource);

@ -220,6 +220,7 @@ codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.callPropagateFoot
codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.callUnknownSetterBad(Intent), 4, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateEmptyBad(), 6, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateEmptyBad(), 7, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateViaInterfaceCodeBad(UnknownCode$Interface), 3, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateViaUnknownAbstractCodeBad(), 3, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateViaUnknownConstructorBad(), 4, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/UnknownCode.java, void UnknownCode.propagateViaUnknownNativeCodeBad(), 3, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)]

Loading…
Cancel
Save