[thread-safety] separate warning type for interfaces called in non-threadsafe context

Reviewed By: jeremydubreil

Differential Revision: D5878497

fbshipit-source-id: ccb644b
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent a706b8aa6c
commit b3e8e972d6

@ -202,6 +202,8 @@ let _global_variable_initialized_with_function_or_method_call =
let inherently_dangerous_function = from_string "INHERENTLY_DANGEROUS_FUNCTION" let inherently_dangerous_function = from_string "INHERENTLY_DANGEROUS_FUNCTION"
let interface_not_thread_safe = from_string "INTERFACE_NOT_THREAD_SAFE"
let internal_error = from_string "Internal_error" let internal_error = from_string "Internal_error"
let leak_after_array_abstraction = from_string "Leak_after_array_abstraction" let leak_after_array_abstraction = from_string "Leak_after_array_abstraction"

@ -133,6 +133,8 @@ val field_not_null_checked : t
val inherently_dangerous_function : t val inherently_dangerous_function : t
val interface_not_thread_safe : t
val internal_error : t val internal_error : t
val leak_after_array_abstraction : t val leak_after_array_abstraction : t

@ -1189,7 +1189,7 @@ let make_trace_with_conflicts conflicts original_path pdesc =
| [] | []
-> original_trace -> original_trace
let report_thread_safety_violation tenv pdesc ~make_description ~conflicts access = let report_thread_safety_violation tenv pdesc issue_type ~make_description ~conflicts access =
let open ThreadSafetyDomain in let open ThreadSafetyDomain in
let pname = Procdesc.get_proc_name pdesc in let pname = Procdesc.get_proc_name pdesc in
let report_one_path (_, sinks as path) = let report_one_path (_, sinks as path) =
@ -1199,9 +1199,10 @@ let report_thread_safety_violation tenv pdesc ~make_description ~conflicts acces
let final_sink_site = PathDomain.Sink.call_site final_sink in let final_sink_site = PathDomain.Sink.call_site final_sink in
let loc = CallSite.loc initial_sink_site in let loc = CallSite.loc initial_sink_site in
let ltr = make_trace_with_conflicts conflicts path pdesc in let ltr = make_trace_with_conflicts conflicts path pdesc in
let msg = IssueType.thread_safety_violation.unique_id in
let description = make_description tenv pname final_sink_site initial_sink_site final_sink in let description = make_description tenv pname final_sink_site initial_sink_site final_sink in
let exn = Exceptions.Checkers (msg, Localise.verbatim_desc description) in let exn =
Exceptions.Checkers (issue_type.IssueType.unique_id, Localise.verbatim_desc description)
in
Reporting.log_error_deprecated ~store_summary:true pname ~loc ~ltr exn Reporting.log_error_deprecated ~store_summary:true pname ~loc ~ltr exn
in in
let trace_of_pname = trace_of_pname access pdesc in let trace_of_pname = trace_of_pname access pdesc in
@ -1213,10 +1214,11 @@ let report_unannotated_interface_violation tenv pdesc access reported_pname =
-> let class_name = Typ.Procname.java_get_class_name java_pname in -> let class_name = Typ.Procname.java_get_class_name java_pname in
let make_description _ _ _ _ _ = let make_description _ _ _ _ _ =
F.asprintf F.asprintf
"Unprotected call to method of un-annotated interface %s. Consider annotating the class with %a or adding a lock" "Unprotected call to method of un-annotated interface %s. Consider annotating the class with %a, adding a lock, or using an interface that is known to be thread-safe."
class_name MF.pp_monospaced "@ThreadSafe" class_name MF.pp_monospaced "@ThreadSafe"
in in
report_thread_safety_violation tenv pdesc ~make_description ~conflicts:[] access report_thread_safety_violation tenv pdesc IssueType.interface_not_thread_safe
~make_description ~conflicts:[] access
| _ | _
-> (* skip reporting on C++ *) -> (* skip reporting on C++ *)
() ()
@ -1361,7 +1363,7 @@ let report_unsafe_accesses aggregated_access_map =
-> if threaded then reported_acc -> if threaded then reported_acc
else ( else (
(* unprotected write. warn. *) (* unprotected write. warn. *)
report_thread_safety_violation tenv pdesc report_thread_safety_violation tenv pdesc IssueType.thread_safety_violation
~make_description:make_unprotected_write_description ~conflicts:[] access ; ~make_description:make_unprotected_write_description ~conflicts:[] access ;
update_reported access pname reported_acc ) update_reported access pname reported_acc )
| _ | _
@ -1390,7 +1392,7 @@ let report_unsafe_accesses aggregated_access_map =
in in
if List.is_empty all_writes then reported_acc if List.is_empty all_writes then reported_acc
else ( else (
report_thread_safety_violation tenv pdesc report_thread_safety_violation tenv pdesc IssueType.thread_safety_violation
~make_description:(make_read_write_race_description all_writes) ~make_description:(make_read_write_race_description all_writes)
~conflicts:(List.map ~f:(fun (access, _, _, _, _) -> access) all_writes) ~conflicts:(List.map ~f:(fun (access, _, _, _, _) -> access) all_writes)
access ; access ;
@ -1423,7 +1425,7 @@ let report_unsafe_accesses aggregated_access_map =
if List.is_empty conflicting_writes then reported_acc if List.is_empty conflicting_writes then reported_acc
else ( else (
(* protected read with conflicting unprotected write(s). warn. *) (* protected read with conflicting unprotected write(s). warn. *)
report_thread_safety_violation tenv pdesc report_thread_safety_violation tenv pdesc IssueType.thread_safety_violation
~make_description:(make_read_write_race_description conflicting_writes) ~make_description:(make_read_write_race_description conflicting_writes)
~conflicts:(List.map ~f:(fun (access, _, _, _, _) -> access) conflicting_writes) ~conflicts:(List.map ~f:(fun (access, _, _, _, _) -> access) conflicting_writes)
access ; access ;

@ -45,8 +45,8 @@ codetoanalyze/java/threadsafety/Containers.java, void Containers.mapPutBad(Strin
codetoanalyze/java/threadsafety/Containers.java, void Containers.mapRemoveBad(String), 1, THREAD_SAFETY_VIOLATION, [Write to container `&this.codetoanalyze.java.checkers.Containers.mMap` via call to `remove`] codetoanalyze/java/threadsafety/Containers.java, void Containers.mapRemoveBad(String), 1, THREAD_SAFETY_VIOLATION, [Write to container `&this.codetoanalyze.java.checkers.Containers.mMap` via call to `remove`]
codetoanalyze/java/threadsafety/Containers.java, void Containers.mapSubclassWriteBad(HashMap,String), 1, THREAD_SAFETY_VIOLATION, [Write to container `&m` via call to `remove`] codetoanalyze/java/threadsafety/Containers.java, void Containers.mapSubclassWriteBad(HashMap,String), 1, THREAD_SAFETY_VIOLATION, [Write to container `&m` via call to `remove`]
codetoanalyze/java/threadsafety/Containers.java, void Containers.poolBad(), 5, THREAD_SAFETY_VIOLATION, [Write to container `&this.codetoanalyze.java.checkers.Containers.simplePool` via call to `release`] codetoanalyze/java/threadsafety/Containers.java, void Containers.poolBad(), 5, THREAD_SAFETY_VIOLATION, [Write to container `&this.codetoanalyze.java.checkers.Containers.simplePool` via call to `release`]
codetoanalyze/java/threadsafety/Dispatch.java, void Dispatch.callUnannotatedInterfaceBad(UnannotatedInterface), 1, THREAD_SAFETY_VIOLATION, [Call to un-annotated interface method void UnannotatedInterface.foo()1] codetoanalyze/java/threadsafety/Dispatch.java, void Dispatch.callUnannotatedInterfaceBad(UnannotatedInterface), 1, INTERFACE_NOT_THREAD_SAFE, [Call to un-annotated interface method void UnannotatedInterface.foo()1]
codetoanalyze/java/threadsafety/Dispatch.java, void Dispatch.callUnannotatedInterfaceIndirectBad(NotThreadSafe,UnannotatedInterface), 1, THREAD_SAFETY_VIOLATION, [call to void NotThreadSafe.notThreadSafeOk(UnannotatedInterface),Call to un-annotated interface method void UnannotatedInterface.foo()1] codetoanalyze/java/threadsafety/Dispatch.java, void Dispatch.callUnannotatedInterfaceIndirectBad(NotThreadSafe,UnannotatedInterface), 1, INTERFACE_NOT_THREAD_SAFE, [call to void NotThreadSafe.notThreadSafeOk(UnannotatedInterface),Call to un-annotated interface method void UnannotatedInterface.foo()1]
codetoanalyze/java/threadsafety/Locks.java, void Locks.FP_unlockOneLock(), 4, THREAD_SAFETY_VIOLATION, [access to `codetoanalyze.java.checkers.Locks.f`] codetoanalyze/java/threadsafety/Locks.java, void Locks.FP_unlockOneLock(), 4, THREAD_SAFETY_VIOLATION, [access to `codetoanalyze.java.checkers.Locks.f`]
codetoanalyze/java/threadsafety/Locks.java, void Locks.afterReentrantLockUnlockBad(), 3, THREAD_SAFETY_VIOLATION, [access to `codetoanalyze.java.checkers.Locks.f`] codetoanalyze/java/threadsafety/Locks.java, void Locks.afterReentrantLockUnlockBad(), 3, THREAD_SAFETY_VIOLATION, [access to `codetoanalyze.java.checkers.Locks.f`]
codetoanalyze/java/threadsafety/Locks.java, void Locks.afterUnlockBad(), 3, THREAD_SAFETY_VIOLATION, [access to `codetoanalyze.java.checkers.Locks.f`] codetoanalyze/java/threadsafety/Locks.java, void Locks.afterUnlockBad(), 3, THREAD_SAFETY_VIOLATION, [access to `codetoanalyze.java.checkers.Locks.f`]

Loading…
Cancel
Save