[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 Context_leak of Localise.error_desc * L.ml_loc
exception Custom_error of string * Localise.error_desc
exception Dangling_pointer_dereference of
@ -167,14 +165,6 @@ let recognize_exception exn =
; severity= Low
; kind= None
; 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) ->
let visibility = if Config.analysis_stops then Exn_user else Exn_developer in
{ 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 Context_leak of Localise.error_desc * Logging.ml_loc
exception Custom_error of string * Localise.error_desc
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 ] }
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 mutex_str = Format.sprintf "Mutex %s" object_str 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 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_custom_error : Location.t -> error_desc

@ -63,11 +63,6 @@ let hpred_is_open_resource tenv prop = function
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 *)
let explain_deallocate_stack_var pvar ra =
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
(** 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
(** 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 ()
(** 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,
and check if the address of a stack variable is left in the result *)
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 pre, post = Prop.extract_spec prop'' 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' =
if Prover.check_inconsistency_base tenv prop then None
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'
(** 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 Normalize = struct
(** 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
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.
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.
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 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
(** 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} *)
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 context_leak = from_string "CONTEXT_LEAK"
let create_intent_from_uri = from_string "CREATE_INTENT_FROM_URI"
let cross_site_scripting = from_string "CROSS_SITE_SCRIPTING"

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

@ -15,7 +15,6 @@ type 'a formatter =
; monospaced_to_string: string -> string
; wrap_code: (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a -> unit
; pp_code: Format.formatter -> string -> unit
; code_to_string: string -> string
; wrap_bold: (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a -> unit
; pp_bold: Format.formatter -> string -> unit
; bold_to_string: string -> string }
@ -33,7 +32,6 @@ end = struct
; monospaced_to_string= Fn.id
; wrap_code= wrap_simple
; pp_code= pp_simple
; code_to_string= Fn.id
; wrap_bold= wrap_simple
; pp_bold= pp_simple
; 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 code_to_string s = Format.asprintf "%a" pp_code s
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
@ -67,7 +63,6 @@ end = struct
; monospaced_to_string
; wrap_code
; pp_code
; code_to_string
; wrap_bold
; pp_bold
; bold_to_string }
@ -91,8 +86,6 @@ let wrap_code = formatter.wrap_code
let pp_code = formatter.pp_code
let code_to_string = formatter.code_to_string
let wrap_bold = formatter.wrap_bold
let pp_bold = formatter.pp_bold

@ -26,9 +26,6 @@ val pp_code : Format.formatter -> string -> unit
[@@warning "-32"]
(** 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
[@@warning "-32"]
(** 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_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_fragment tenv tname =

@ -16,12 +16,6 @@ val drawable_prefix : string
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
(** 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.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/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, 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]

@ -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.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/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, 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]

Loading…
Cancel
Save