[cleanup] sunset Context leaks

Reviewed By: jeremydubreil

Differential Revision: D6843300

fbshipit-source-id: 938125b
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent e90e6c8bf0
commit 80b3d080ce

@ -65,8 +65,6 @@ exception Comparing_floats_for_equality of Localise.error_desc * L.ml_loc
exception Condition_always_true_false of Localise.error_desc * bool * L.ml_loc exception Condition_always_true_false of Localise.error_desc * bool * L.ml_loc
exception Context_leak of Localise.error_desc * L.ml_loc
exception Custom_error of string * Localise.error_desc exception Custom_error of string * Localise.error_desc
exception Dangling_pointer_dereference of exception Dangling_pointer_dereference of
@ -167,14 +165,6 @@ let recognize_exception exn =
; severity= Low ; severity= Low
; kind= None ; kind= None
; category= Nocat } ; category= Nocat }
| Context_leak (desc, _) ->
{ name= IssueType.context_leak
; description= desc
; ml_loc= None
; visibility= Exn_user
; severity= High
; kind= None
; category= Nocat }
| Analysis_stops (desc, ml_loc_opt) -> | Analysis_stops (desc, ml_loc_opt) ->
let visibility = if Config.analysis_stops then Exn_user else Exn_developer in let visibility = if Config.analysis_stops then Exn_user else Exn_developer in
{ name= IssueType.analysis_stops { name= IssueType.analysis_stops

@ -63,8 +63,6 @@ exception Comparing_floats_for_equality of Localise.error_desc * Logging.ml_loc
exception Condition_always_true_false of Localise.error_desc * bool * Logging.ml_loc exception Condition_always_true_false of Localise.error_desc * bool * Logging.ml_loc
exception Context_leak of Localise.error_desc * Logging.ml_loc
exception Custom_error of string * Localise.error_desc exception Custom_error of string * Localise.error_desc
exception Dangling_pointer_dereference of exception Dangling_pointer_dereference of

@ -434,44 +434,6 @@ let java_unchecked_exn_desc proc_name exn_name pre_str : error_desc =
; "whenever " ^ pre_str ] } ; "whenever " ^ pre_str ] }
let desc_context_leak pname context_typ fieldname leak_path : error_desc =
let fld_str = Typ.Fieldname.to_string fieldname in
let leak_root = "Static field " ^ fld_str ^ " |->\n" in
let leak_path_entry_to_str acc entry =
let entry_str =
match entry with
| Some fld, _ ->
Typ.Fieldname.to_string fld
| None, typ ->
Typ.to_string typ
in
(* intentionally omit space; [typ_to_string] adds an extra space *)
acc ^ entry_str ^ " |->\n"
in
let context_str = Typ.to_string context_typ in
let path_str =
let path_prefix =
if List.is_empty leak_path then "Leaked "
else List.fold ~f:leak_path_entry_to_str ~init:"" leak_path ^ "Leaked "
in
path_prefix ^ context_str
in
let preamble =
let pname_str =
match pname with
| Typ.Procname.Java pname_java ->
MF.monospaced_to_string
(Printf.sprintf "%s.%s"
(Typ.Procname.Java.get_class_name pname_java)
(Typ.Procname.Java.get_method pname_java))
| _ ->
""
in
"Context " ^ context_str ^ " may leak during method " ^ pname_str ^ ":\n"
in
{no_desc with descriptions= [preamble ^ MF.code_to_string (leak_root ^ path_str)]}
let desc_double_lock pname_opt object_str loc = let desc_double_lock pname_opt object_str loc =
let mutex_str = Format.sprintf "Mutex %s" object_str in let mutex_str = Format.sprintf "Mutex %s" object_str in
let tags = Tags.create () in let tags = Tags.create () in

@ -164,9 +164,6 @@ val desc_null_test_after_dereference : string -> int -> Location.t -> error_desc
val java_unchecked_exn_desc : Typ.Procname.t -> Typ.Name.t -> string -> error_desc val java_unchecked_exn_desc : Typ.Procname.t -> Typ.Name.t -> string -> error_desc
val desc_context_leak :
Typ.Procname.t -> Typ.t -> Typ.Fieldname.t -> (Typ.Fieldname.t option * Typ.t) list -> error_desc
val desc_fragment_retains_view : Typ.t -> Typ.Fieldname.t -> Typ.t -> Typ.Procname.t -> error_desc val desc_fragment_retains_view : Typ.t -> Typ.Fieldname.t -> Typ.t -> Typ.Procname.t -> error_desc
val desc_custom_error : Location.t -> error_desc val desc_custom_error : Location.t -> error_desc

@ -63,11 +63,6 @@ let hpred_is_open_resource tenv prop = function
None None
(** Produce a description of a persistent reference to an Android Context *)
let explain_context_leak pname context_typ fieldname error_path =
Localise.desc_context_leak pname context_typ fieldname error_path
(** Explain a deallocate stack variable error *) (** Explain a deallocate stack variable error *)
let explain_deallocate_stack_var pvar ra = let explain_deallocate_stack_var pvar ra =
let pvar_str = Pvar.to_string pvar in let pvar_str = Pvar.to_string pvar in

@ -38,11 +38,6 @@ val find_boolean_assignment : Procdesc.Node.t -> Pvar.t -> bool -> Procdesc.Node
val exp_rv_dexp : Tenv.t -> Procdesc.Node.t -> Exp.t -> DecompiledExp.t option val exp_rv_dexp : Tenv.t -> Procdesc.Node.t -> Exp.t -> DecompiledExp.t option
(** describe rvalue [e] as a dexp *) (** describe rvalue [e] as a dexp *)
val explain_context_leak :
Typ.Procname.t -> Typ.t -> Typ.Fieldname.t -> (Typ.Fieldname.t option * Typ.t) list
-> Localise.error_desc
(** Produce a description of a persistent reference to an Android Context *)
val explain_allocation_mismatch : PredSymb.res_action -> PredSymb.res_action -> Localise.error_desc val explain_allocation_mismatch : PredSymb.res_action -> PredSymb.res_action -> Localise.error_desc
(** Produce a description of a mismatch between an allocation function and a deallocation function *) (** Produce a description of a mismatch between an allocation function and a deallocation function *)

@ -514,93 +514,6 @@ let forward_tabulate tenv proc_cfg wl =
L.d_ln () L.d_ln ()
(** if possible, produce a (fieldname, typ) path from one of the [src_exps] to [sink_exp] using
[reachable_hpreds]. *)
let get_fld_typ_path_opt src_exps sink_exp_ reachable_hpreds_ =
let strexp_matches target_exp = function
| Sil.Eexp (e, _) ->
Exp.equal target_exp e
| _ ->
false
in
let extend_path hpred (sink_exp, path, reachable_hpreds) =
match hpred with
| Sil.Hpointsto (lhs, Sil.Estruct (flds, _), Exp.Sizeof {typ}) ->
List.find ~f:(function _, se -> strexp_matches sink_exp se) flds
|> Option.value_map
~f:(function
| fld, _ ->
let reachable_hpreds' = Sil.HpredSet.remove hpred reachable_hpreds in
(lhs, (Some fld, typ) :: path, reachable_hpreds'))
~default:(sink_exp, path, reachable_hpreds)
| Sil.Hpointsto (lhs, Sil.Earray (_, elems, _), Exp.Sizeof {typ}) ->
if List.exists ~f:(function _, se -> strexp_matches sink_exp se) elems then
let reachable_hpreds' = Sil.HpredSet.remove hpred reachable_hpreds in
(* None means "no field name" ~=~ nameless array index *)
(lhs, (None, typ) :: path, reachable_hpreds')
else (sink_exp, path, reachable_hpreds)
| _ ->
(sink_exp, path, reachable_hpreds)
in
(* terminates because [reachable_hpreds] is shrinking on each recursive call *)
let rec get_fld_typ_path sink_exp path reachable_hpreds =
let sink_exp', path', reachable_hpreds' =
Sil.HpredSet.fold extend_path reachable_hpreds (sink_exp, path, reachable_hpreds)
in
if Exp.Set.mem sink_exp' src_exps then Some path'
else if Sil.HpredSet.cardinal reachable_hpreds' >= Sil.HpredSet.cardinal reachable_hpreds then
None (* can't find a path from [src_exps] to [sink_exp] *)
else get_fld_typ_path sink_exp' path' reachable_hpreds'
in
get_fld_typ_path sink_exp_ [] reachable_hpreds_
(** report an error if any Context is reachable from a static field *)
let report_context_leaks pname sigma tenv =
(* report an error if an expression in [context_exps] is reachable from [field_strexp] *)
let check_reachable_context_from_fld (fld_name, fld_strexp) context_exps =
let fld_exps = Prop.strexp_get_exps fld_strexp in
let reachable_hpreds, reachable_exps = Prop.compute_reachable_hpreds sigma fld_exps in
(* raise an error if any Context expression is in [reachable_exps] *)
List.iter
~f:(fun (context_exp, name) ->
if Exp.Set.mem context_exp reachable_exps then
match get_fld_typ_path_opt fld_exps context_exp reachable_hpreds with
| None ->
() (* TODO (T21871205): the underlying issue still need to be fixed *)
| Some leak_path ->
let err_desc =
Errdesc.explain_context_leak pname (Typ.mk (Tstruct name)) fld_name leak_path
in
let exn = Exceptions.Context_leak (err_desc, __POS__) in
Reporting.log_error_deprecated pname exn )
context_exps
in
(* get the set of pointed-to expressions of type T <: Context *)
let context_exps =
List.fold
~f:(fun exps hpred ->
match hpred with
| Sil.Hpointsto (_, Eexp (exp, _), Sizeof {typ= {desc= Tptr ({desc= Tstruct name}, _)}})
when not (Exp.is_null_literal exp) && AndroidFramework.is_context tenv name
&& not (AndroidFramework.is_application tenv name) ->
(exp, name) :: exps
| _ ->
exps )
~init:[] sigma
in
List.iter
~f:(function
| Sil.Hpointsto (Exp.Lvar pv, Sil.Estruct (static_flds, _), _) when Pvar.is_global pv ->
List.iter
~f:(fun (f_name, f_strexp) ->
check_reachable_context_from_fld (f_name, f_strexp) context_exps )
static_flds
| _ ->
())
sigma
(** Remove locals and formals, (** Remove locals and formals,
and check if the address of a stack variable is left in the result *) and check if the address of a stack variable is left in the result *)
let remove_locals_formals_and_check tenv proc_cfg p = let remove_locals_formals_and_check tenv proc_cfg p =
@ -674,8 +587,6 @@ let extract_specs tenv pdesc pathset : Prop.normal Specs.spec list =
let prop'' = Abs.abstract pname tenv prop' in let prop'' = Abs.abstract pname tenv prop' in
let pre, post = Prop.extract_spec prop'' in let pre, post = Prop.extract_spec prop'' in
let pre' = Prop.normalize tenv (Prop.prop_sub (`Exp sub) pre) in let pre' = Prop.normalize tenv (Prop.prop_sub (`Exp sub) pre) in
if Language.curr_language_is Java && Procdesc.get_access pdesc <> PredSymb.Private then
report_context_leaks pname post.Prop.sigma tenv ;
let post' = let post' =
if Prover.check_inconsistency_base tenv prop then None if Prover.check_inconsistency_base tenv prop then None
else Some (Prop.normalize tenv (Prop.prop_sub (`Exp sub) post), path) else Some (Prop.normalize tenv (Prop.prop_sub (`Exp sub) post), path)

@ -588,54 +588,6 @@ let prop_sigma_star (p: 'a t) (sigma: sigma) : exposed t =
set p ~sigma:sigma' set p ~sigma:sigma'
(** return the set of subexpressions of [strexp] *)
let strexp_get_exps strexp =
let rec strexp_get_exps_rec exps (se: Sil.strexp) =
match se with
| Eexp (Exn e, _) ->
Exp.Set.add e exps
| Eexp (e, _) ->
Exp.Set.add e exps
| Estruct (flds, _) ->
List.fold ~f:(fun exps (_, strexp) -> strexp_get_exps_rec exps strexp) ~init:exps flds
| Earray (_, elems, _) ->
List.fold ~f:(fun exps (_, strexp) -> strexp_get_exps_rec exps strexp) ~init:exps elems
in
strexp_get_exps_rec Exp.Set.empty strexp
(** get the set of expressions on the righthand side of [hpred] *)
let hpred_get_targets (hpred: Sil.hpred) =
match hpred with
| Hpointsto (_, rhs, _) ->
strexp_get_exps rhs
| Hlseg (_, _, _, e, el) ->
List.fold ~f:(fun exps e -> Exp.Set.add e exps) ~init:Exp.Set.empty (e :: el)
| Hdllseg (_, _, _, oB, oF, iB, el) ->
(* only one direction supported for now *)
List.fold ~f:(fun exps e -> Exp.Set.add e exps) ~init:Exp.Set.empty (oB :: oF :: iB :: el)
(** return the set of hpred's and exp's in [sigma] that are reachable from an expression in
[exps] *)
let compute_reachable_hpreds sigma exps =
let rec compute_reachable_hpreds_rec sigma (reach, exps) =
let add_hpred_if_reachable (reach, exps) (hpred: Sil.hpred) =
match hpred with
| Hpointsto (lhs, _, _) as hpred when Exp.Set.mem lhs exps ->
let reach' = Sil.HpredSet.add hpred reach in
let reach_exps = hpred_get_targets hpred in
(reach', Exp.Set.union exps reach_exps)
| _ ->
(reach, exps)
in
let reach', exps' = List.fold ~f:add_hpred_if_reachable ~init:(reach, exps) sigma in
if Int.equal (Sil.HpredSet.cardinal reach) (Sil.HpredSet.cardinal reach') then (reach, exps)
else compute_reachable_hpreds_rec sigma (reach', exps')
in
compute_reachable_hpreds_rec sigma (Sil.HpredSet.empty, exps)
(* Module for normalization *) (* Module for normalization *)
module Normalize = struct module Normalize = struct
(** Eliminates all empty lsegs from sigma, and collect equalities (** Eliminates all empty lsegs from sigma, and collect equalities
@ -1416,8 +1368,8 @@ module Normalize = struct
(** Captured variables in the closures consist of expressions and variables, with the implicit (** Captured variables in the closures consist of expressions and variables, with the implicit
assumption that these two values are in the relation &var -> id. However, after bi-abduction, etc. assumption that these two values are in the relation &var -> id. However, after bi-abduction, etc.
the constraint may not hold anymore, so this function ensures that it is always kept. the constraint may not hold anymore, so this function ensures that it is always kept.
In particular, we have &var -> id iff we also have the pair (id, var) as part of captured variables. *) In particular, we have &var -> id iff we also have the pair (id, var) as part of captured variables. *)
let make_captured_in_closures_consistent sigma = let make_captured_in_closures_consistent sigma =
let open Sil in let open Sil in

@ -350,13 +350,6 @@ val prop_iter_make_id_primed : Tenv.t -> Ident.t -> 'a prop_iter -> 'a prop_iter
val prop_iter_gc_fields : unit prop_iter -> unit prop_iter val prop_iter_gc_fields : unit prop_iter -> unit prop_iter
(** Collect garbage fields. *) (** Collect garbage fields. *)
val strexp_get_exps : Sil.strexp -> Exp.Set.t
(** return the set of subexpressions of [strexp] *)
val compute_reachable_hpreds : hpred list -> Exp.Set.t -> Sil.HpredSet.t * Exp.Set.t
(** return the set of hpred's and exp's in [sigma] that are reachable from an expression in
[exps] *)
(** {2 Internal modules} *) (** {2 Internal modules} *)
module Metrics : sig module Metrics : sig

@ -132,8 +132,6 @@ let condition_always_false = from_string ~enabled:false "CONDITION_ALWAYS_FALSE"
let condition_always_true = from_string ~enabled:false "CONDITION_ALWAYS_TRUE" let condition_always_true = from_string ~enabled:false "CONDITION_ALWAYS_TRUE"
let context_leak = from_string "CONTEXT_LEAK"
let create_intent_from_uri = from_string "CREATE_INTENT_FROM_URI" let create_intent_from_uri = from_string "CREATE_INTENT_FROM_URI"
let cross_site_scripting = from_string "CROSS_SITE_SCRIPTING" let cross_site_scripting = from_string "CROSS_SITE_SCRIPTING"

@ -87,8 +87,6 @@ val condition_always_false : t
val condition_always_true : t val condition_always_true : t
val context_leak : t
val create_intent_from_uri : t val create_intent_from_uri : t
val cross_site_scripting : t val cross_site_scripting : t

@ -15,7 +15,6 @@ type 'a formatter =
; monospaced_to_string: string -> string ; monospaced_to_string: string -> string
; wrap_code: (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a -> unit ; wrap_code: (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a -> unit
; pp_code: Format.formatter -> string -> unit ; pp_code: Format.formatter -> string -> unit
; code_to_string: string -> string
; wrap_bold: (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a -> unit ; wrap_bold: (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a -> unit
; pp_bold: Format.formatter -> string -> unit ; pp_bold: Format.formatter -> string -> unit
; bold_to_string: string -> string } ; bold_to_string: string -> string }
@ -33,7 +32,6 @@ end = struct
; monospaced_to_string= Fn.id ; monospaced_to_string= Fn.id
; wrap_code= wrap_simple ; wrap_code= wrap_simple
; pp_code= pp_simple ; pp_code= pp_simple
; code_to_string= Fn.id
; wrap_bold= wrap_simple ; wrap_bold= wrap_simple
; pp_bold= pp_simple ; pp_bold= pp_simple
; bold_to_string= Fn.id } ; bold_to_string= Fn.id }
@ -53,8 +51,6 @@ end = struct
let pp_code fmt s = wrap_code Format.pp_print_string fmt s let pp_code fmt s = wrap_code Format.pp_print_string fmt s
let code_to_string s = Format.asprintf "%a" pp_code s
let wrap_bold pp fmt x = Format.fprintf fmt "**%a**" pp x let wrap_bold pp fmt x = Format.fprintf fmt "**%a**" pp x
let pp_bold fmt s = wrap_bold Format.pp_print_string fmt s let pp_bold fmt s = wrap_bold Format.pp_print_string fmt s
@ -67,7 +63,6 @@ end = struct
; monospaced_to_string ; monospaced_to_string
; wrap_code ; wrap_code
; pp_code ; pp_code
; code_to_string
; wrap_bold ; wrap_bold
; pp_bold ; pp_bold
; bold_to_string } ; bold_to_string }
@ -91,8 +86,6 @@ let wrap_code = formatter.wrap_code
let pp_code = formatter.pp_code let pp_code = formatter.pp_code
let code_to_string = formatter.code_to_string
let wrap_bold = formatter.wrap_bold let wrap_bold = formatter.wrap_bold
let pp_bold = formatter.pp_bold let pp_bold = formatter.pp_bold

@ -26,9 +26,6 @@ val pp_code : Format.formatter -> string -> unit
[@@warning "-32"] [@@warning "-32"]
(** pp to wrap into a code block *) (** pp to wrap into a code block *)
val code_to_string : string -> string
(** wrap into a code block *)
val wrap_bold : (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a -> unit val wrap_bold : (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a -> unit
[@@warning "-32"] [@@warning "-32"]
(** used to combine pp together, wrap content into a bold block *) (** used to combine pp together, wrap content into a bold block *)

@ -35,10 +35,6 @@ let is_subtype_package_class tenv tname package classname =
let is_autocloseable tenv tname = is_subtype_package_class tenv tname "java.lang" "AutoCloseable" let is_autocloseable tenv tname = is_subtype_package_class tenv tname "java.lang" "AutoCloseable"
let is_context tenv tname = is_subtype_package_class tenv tname "android.content" "Context"
let is_application tenv tname = is_subtype_package_class tenv tname "android.app" "Application"
let is_view tenv tname = is_subtype_package_class tenv tname "android.view" "View" let is_view tenv tname = is_subtype_package_class tenv tname "android.view" "View"
let is_fragment tenv tname = let is_fragment tenv tname =

@ -16,12 +16,6 @@ val drawable_prefix : string
val is_autocloseable : Tenv.t -> Typ.Name.t -> bool val is_autocloseable : Tenv.t -> Typ.Name.t -> bool
val is_context : Tenv.t -> Typ.Name.t -> bool
(** return true if [typename] <: android.content.Context *)
val is_application : Tenv.t -> Typ.Name.t -> bool
(** return true if [typename] <: android.app.Application *)
val is_view : Tenv.t -> Typ.Name.t -> bool val is_view : Tenv.t -> Typ.Name.t -> bool
(** return true if [typename] <: android.view.View *) (** return true if [typename] <: android.view.View *)

@ -11,12 +11,6 @@ codetoanalyze/java/infer/CloseableAsResourceExample.java, void CloseableAsResour
codetoanalyze/java/infer/CloseableAsResourceExample.java, void CloseableAsResourceExample.notClosingWrapper(), 2, RESOURCE_LEAK, [start of procedure notClosingWrapper(),start of procedure Resource(),return from a call to Resource.<init>(),start of procedure Sub(...),start of procedure Wrapper(...),return from a call to Wrapper.<init>(Resource),return from a call to Sub.<init>(Resource),start of procedure close(),return from a call to void Resource.close()] codetoanalyze/java/infer/CloseableAsResourceExample.java, void CloseableAsResourceExample.notClosingWrapper(), 2, RESOURCE_LEAK, [start of procedure notClosingWrapper(),start of procedure Resource(),return from a call to Resource.<init>(),start of procedure Sub(...),start of procedure Wrapper(...),return from a call to Wrapper.<init>(Resource),return from a call to Sub.<init>(Resource),start of procedure close(),return from a call to void Resource.close()]
codetoanalyze/java/infer/CloseableAsResourceExample.java, void CloseableAsResourceExample.skippedVritualCallDoesNotCloseResourceOnReceiver(), 2, RESOURCE_LEAK, [start of procedure skippedVritualCallDoesNotCloseResourceOnReceiver(),start of procedure SomeResource(),return from a call to SomeResource.<init>(),Skipping foo(...): method has no implementation,Definition of foo(...)] codetoanalyze/java/infer/CloseableAsResourceExample.java, void CloseableAsResourceExample.skippedVritualCallDoesNotCloseResourceOnReceiver(), 2, RESOURCE_LEAK, [start of procedure skippedVritualCallDoesNotCloseResourceOnReceiver(),start of procedure SomeResource(),return from a call to SomeResource.<init>(),Skipping foo(...): method has no implementation,Definition of foo(...)]
codetoanalyze/java/infer/CloseableAsResourceExample.java, void CloseableAsResourceExample.withException(), 4, RESOURCE_LEAK, [start of procedure withException(),start of procedure SomeResource(),return from a call to SomeResource.<init>(),start of procedure doSomething(),Skipping star(): method has no implementation,Definition of star(),Taking true branch,start of procedure LocalException(),return from a call to LocalException.<init>(),exception codetoanalyze.java.infer.LocalException,return from a call to void SomeResource.doSomething()] codetoanalyze/java/infer/CloseableAsResourceExample.java, void CloseableAsResourceExample.withException(), 4, RESOURCE_LEAK, [start of procedure withException(),start of procedure SomeResource(),return from a call to SomeResource.<init>(),start of procedure doSomething(),Skipping star(): method has no implementation,Definition of star(),Taking true branch,start of procedure LocalException(),return from a call to LocalException.<init>(),exception codetoanalyze.java.infer.LocalException,return from a call to void SomeResource.doSomething()]
codetoanalyze/java/infer/ContextLeaks.java, ContextLeaks$Singleton ContextLeaks$Singleton.getInstance(Context), 4, CONTEXT_LEAK, [start of procedure getInstance(...),Taking false branch,return from a call to ContextLeaks$Singleton ContextLeaks$Singleton.getInstance(Context)]
codetoanalyze/java/infer/ContextLeaks.java, ContextLeaks$Singleton ContextLeaks.singletonLeak(), 1, CONTEXT_LEAK, [start of procedure singletonLeak(),start of procedure getInstance(...),Taking false branch,return from a call to ContextLeaks$Singleton ContextLeaks$Singleton.getInstance(Context),return from a call to ContextLeaks$Singleton ContextLeaks.singletonLeak()]
codetoanalyze/java/infer/ContextLeaks.java, void ContextLeaks.directLeak(), 2, CONTEXT_LEAK, [start of procedure directLeak(),return from a call to void ContextLeaks.directLeak()]
codetoanalyze/java/infer/ContextLeaks.java, void ContextLeaks.indirectLeak(), 4, CONTEXT_LEAK, [start of procedure indirectLeak(),start of procedure ContextLeaks$Obj(),return from a call to ContextLeaks$Obj.<init>(),return from a call to void ContextLeaks.indirectLeak()]
codetoanalyze/java/infer/ContextLeaks.java, void ContextLeaks.leakAfterInstanceFieldWrite(), 3, CONTEXT_LEAK, [start of procedure leakAfterInstanceFieldWrite(),return from a call to void ContextLeaks.leakAfterInstanceFieldWrite()]
codetoanalyze/java/infer/ContextLeaks.java, void ContextLeaks.nonStaticInnerClassLeak(), 2, CONTEXT_LEAK, [start of procedure nonStaticInnerClassLeak(),start of procedure ContextLeaks$NonStaticInner(...),return from a call to ContextLeaks$NonStaticInner.<init>(ContextLeaks),return from a call to void ContextLeaks.nonStaticInnerClassLeak()]
codetoanalyze/java/infer/CursorLeaks.java, Object CursorLeaks.cursorClosedCheckNullCheckClosed_FP(SQLiteDatabase), 13, RESOURCE_LEAK, [start of procedure cursorClosedCheckNullCheckClosed_FP(...),Taking false branch,Skipping getString(...): unknown method,Taking true branch,Taking false branch] codetoanalyze/java/infer/CursorLeaks.java, Object CursorLeaks.cursorClosedCheckNullCheckClosed_FP(SQLiteDatabase), 13, RESOURCE_LEAK, [start of procedure cursorClosedCheckNullCheckClosed_FP(...),Taking false branch,Skipping getString(...): unknown method,Taking true branch,Taking false branch]
codetoanalyze/java/infer/CursorLeaks.java, int CursorLeaks.completeDownloadNotClosed(DownloadManager), 8, RESOURCE_LEAK, [start of procedure completeDownloadNotClosed(...),Taking false branch,Skipping getColumnIndex(...): unknown method] codetoanalyze/java/infer/CursorLeaks.java, int CursorLeaks.completeDownloadNotClosed(DownloadManager), 8, RESOURCE_LEAK, [start of procedure completeDownloadNotClosed(...),Taking false branch,Skipping getColumnIndex(...): unknown method]
codetoanalyze/java/infer/CursorLeaks.java, int CursorLeaks.cursorNotClosed(SQLiteDatabase), 4, RESOURCE_LEAK, [start of procedure cursorNotClosed(...),Skipping getCount(): unknown method] codetoanalyze/java/infer/CursorLeaks.java, int CursorLeaks.cursorNotClosed(SQLiteDatabase), 4, RESOURCE_LEAK, [start of procedure cursorNotClosed(...),Skipping getCount(): unknown method]

@ -1,121 +0,0 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package codetoanalyze.java.infer;
import java.lang.ref.WeakReference;
import android.content.Context;
import android.app.Activity;
public class ContextLeaks extends Activity {
static Object sFld;
void directLeak() {
sFld = this;
}
public void leakThenFix() {
sFld = this;
sFld = null;
}
public void nonActivityNoLeak() {
sFld = new Object();
}
static class Obj {
public Object f;
}
public void indirectLeak() {
Obj o = new Obj();
o.f = this;
sFld = o;
}
public void indirectLeakThenFix() {
Obj o = new Obj();
o.f = this;
sFld = o;
o.f = null;
}
class NonStaticInner {
}
public void nonStaticInnerClassLeak() {
sFld = new NonStaticInner();
}
public void nonStaticInnerClassLeakThenFix() {
sFld = new NonStaticInner();
sFld = null;
}
private Object o;
public void leakAfterInstanceFieldWrite() {
this.o = new Object();
sFld = this;
}
public static class Singleton {
private static Singleton instance;
private Context context;
private Singleton(Context context) {
this.context = context;
}
public static Singleton getInstance(Context context) {
if (instance == null) {
instance = new Singleton(context);
}
return instance;
}
}
public Singleton singletonLeak() {
return Singleton.getInstance(this);
}
public Singleton singletonNoLeak() {
return Singleton.getInstance(this.getApplicationContext());
}
// testing that we don't report on static field -> ... -> Context paths broken by weak refs
static WeakReference<Context> sDirectWeakReference;
static WeakReference<Obj> sIndirectWeakReference1;
static Obj sIndirectWeakReference2;
// sDirectWeakReference |-> WeakReference.referent |-> Context
public void directWeakReferenceOk() {
sDirectWeakReference = new WeakReference(this);
}
// sIndirectWeakReference1 |-> WeakReference.referent |-> Obj.f |-> Context
public void indirectWeakReferenceOk1() {
Obj obj = new Obj();
obj.f = this;
sIndirectWeakReference1 = new WeakReference(obj);
}
// sIndirectWeakReference2.|-> Obj.f |-> WeakReference.referent |-> Context
public void indirectWeakReferenceOk2() {
Obj obj = new Obj();
obj.f = new WeakReference(this);
sIndirectWeakReference2 = obj;
}
}

@ -30,12 +30,6 @@ codetoanalyze/java/infer/CloseableAsResourceExample.java, void CloseableAsResour
codetoanalyze/java/infer/CloseableAsResourceExample.java, void CloseableAsResourceExample.notClosingWrapper(), 2, RESOURCE_LEAK, [start of procedure notClosingWrapper(),start of procedure Resource(),return from a call to Resource.<init>(),start of procedure Sub(...),start of procedure Wrapper(...),return from a call to Wrapper.<init>(Resource),return from a call to Sub.<init>(Resource),start of procedure close(),return from a call to void Resource.close()] codetoanalyze/java/infer/CloseableAsResourceExample.java, void CloseableAsResourceExample.notClosingWrapper(), 2, RESOURCE_LEAK, [start of procedure notClosingWrapper(),start of procedure Resource(),return from a call to Resource.<init>(),start of procedure Sub(...),start of procedure Wrapper(...),return from a call to Wrapper.<init>(Resource),return from a call to Sub.<init>(Resource),start of procedure close(),return from a call to void Resource.close()]
codetoanalyze/java/infer/CloseableAsResourceExample.java, void CloseableAsResourceExample.skippedVritualCallDoesNotCloseResourceOnReceiver(), 2, RESOURCE_LEAK, [start of procedure skippedVritualCallDoesNotCloseResourceOnReceiver(),start of procedure SomeResource(),return from a call to SomeResource.<init>(),Skipping foo(...): method has no implementation,Definition of foo(...)] codetoanalyze/java/infer/CloseableAsResourceExample.java, void CloseableAsResourceExample.skippedVritualCallDoesNotCloseResourceOnReceiver(), 2, RESOURCE_LEAK, [start of procedure skippedVritualCallDoesNotCloseResourceOnReceiver(),start of procedure SomeResource(),return from a call to SomeResource.<init>(),Skipping foo(...): method has no implementation,Definition of foo(...)]
codetoanalyze/java/infer/CloseableAsResourceExample.java, void CloseableAsResourceExample.withException(), 4, RESOURCE_LEAK, [start of procedure withException(),start of procedure SomeResource(),return from a call to SomeResource.<init>(),start of procedure doSomething(),Skipping star(): method has no implementation,Definition of star(),Taking true branch,start of procedure LocalException(),return from a call to LocalException.<init>(),exception codetoanalyze.java.infer.LocalException,return from a call to void SomeResource.doSomething()] codetoanalyze/java/infer/CloseableAsResourceExample.java, void CloseableAsResourceExample.withException(), 4, RESOURCE_LEAK, [start of procedure withException(),start of procedure SomeResource(),return from a call to SomeResource.<init>(),start of procedure doSomething(),Skipping star(): method has no implementation,Definition of star(),Taking true branch,start of procedure LocalException(),return from a call to LocalException.<init>(),exception codetoanalyze.java.infer.LocalException,return from a call to void SomeResource.doSomething()]
codetoanalyze/java/infer/ContextLeaks.java, ContextLeaks$Singleton ContextLeaks$Singleton.getInstance(Context), 4, CONTEXT_LEAK, [start of procedure getInstance(...),Taking false branch,return from a call to ContextLeaks$Singleton ContextLeaks$Singleton.getInstance(Context)]
codetoanalyze/java/infer/ContextLeaks.java, ContextLeaks$Singleton ContextLeaks.singletonLeak(), 1, CONTEXT_LEAK, [start of procedure singletonLeak(),start of procedure getInstance(...),Taking false branch,return from a call to ContextLeaks$Singleton ContextLeaks$Singleton.getInstance(Context),return from a call to ContextLeaks$Singleton ContextLeaks.singletonLeak()]
codetoanalyze/java/infer/ContextLeaks.java, void ContextLeaks.directLeak(), 2, CONTEXT_LEAK, [start of procedure directLeak(),return from a call to void ContextLeaks.directLeak()]
codetoanalyze/java/infer/ContextLeaks.java, void ContextLeaks.indirectLeak(), 4, CONTEXT_LEAK, [start of procedure indirectLeak(),start of procedure ContextLeaks$Obj(),return from a call to ContextLeaks$Obj.<init>(),return from a call to void ContextLeaks.indirectLeak()]
codetoanalyze/java/infer/ContextLeaks.java, void ContextLeaks.leakAfterInstanceFieldWrite(), 3, CONTEXT_LEAK, [start of procedure leakAfterInstanceFieldWrite(),return from a call to void ContextLeaks.leakAfterInstanceFieldWrite()]
codetoanalyze/java/infer/ContextLeaks.java, void ContextLeaks.nonStaticInnerClassLeak(), 2, CONTEXT_LEAK, [start of procedure nonStaticInnerClassLeak(),start of procedure ContextLeaks$NonStaticInner(...),return from a call to ContextLeaks$NonStaticInner.<init>(ContextLeaks),return from a call to void ContextLeaks.nonStaticInnerClassLeak()]
codetoanalyze/java/infer/CursorLeaks.java, Object CursorLeaks.cursorClosedCheckNullCheckClosed_FP(SQLiteDatabase), 13, RESOURCE_LEAK, [start of procedure cursorClosedCheckNullCheckClosed_FP(...),Taking false branch,Skipping getString(...): unknown method,Taking true branch,Taking false branch] codetoanalyze/java/infer/CursorLeaks.java, Object CursorLeaks.cursorClosedCheckNullCheckClosed_FP(SQLiteDatabase), 13, RESOURCE_LEAK, [start of procedure cursorClosedCheckNullCheckClosed_FP(...),Taking false branch,Skipping getString(...): unknown method,Taking true branch,Taking false branch]
codetoanalyze/java/infer/CursorLeaks.java, int CursorLeaks.completeDownloadNotClosed(DownloadManager), 8, RESOURCE_LEAK, [start of procedure completeDownloadNotClosed(...),Taking false branch,Skipping getColumnIndex(...): unknown method] codetoanalyze/java/infer/CursorLeaks.java, int CursorLeaks.completeDownloadNotClosed(DownloadManager), 8, RESOURCE_LEAK, [start of procedure completeDownloadNotClosed(...),Taking false branch,Skipping getColumnIndex(...): unknown method]
codetoanalyze/java/infer/CursorLeaks.java, int CursorLeaks.cursorNotClosed(SQLiteDatabase), 4, RESOURCE_LEAK, [start of procedure cursorNotClosed(...),Skipping getCount(): unknown method] codetoanalyze/java/infer/CursorLeaks.java, int CursorLeaks.cursorNotClosed(SQLiteDatabase), 4, RESOURCE_LEAK, [start of procedure cursorNotClosed(...),Skipping getCount(): unknown method]

Loading…
Cancel
Save