[checkers] allow custom sources and sinks in annotation reachability

Reviewed By: jvillard

Differential Revision: D4558975

fbshipit-source-id: 5243236
master
Sam Blackshear 8 years ago committed by Facebook Github Bot
parent 61e4e6e1ed
commit 5cdee51ed5

@ -508,6 +508,13 @@ and angelic_execution =
CLOpt.mk_bool ~deprecated:["angelic_execution"] ~long:"angelic-execution" ~default:true
"Angelic execution, where the analysis ignores errors caused by unknown procedure calls"
and annotation_reachability =
CLOpt.mk_json ~long:"annotation-reachability"
~parse_mode:CLOpt.(Infer [Analysis])
"Specify custom sources/sink for the annotation reachability checker\n\
Example format: for custom annotations com.my.annotation.{Source1,Source2,Sink1}\n\
{ \"sources\" : [\"Source1\", \"Source2\"], \"sink\" : \"Sink1\" }"
and array_level =
CLOpt.mk_int ~deprecated:["arraylevel"] ~long:"array-level" ~default:0
~meta:"int" "Level of treating the array indexing and pointer arithmetic:\n\
@ -1439,6 +1446,7 @@ and analysis_suppress_errors_options =
IList.map (fun (a, b) -> (a, !b)) analysis_suppress_errors_options
and analysis_stops = !analysis_stops
and angelic_execution = !angelic_execution
and annotation_reachability = !annotation_reachability
and array_level = !array_level
and ast_file = !ast_file
and blacklist = !blacklist

@ -148,6 +148,7 @@ val analysis_stops : bool
val analysis_suppress_errors : analyzer -> string list
val analyzer : analyzer
val angelic_execution : bool
val annotation_reachability : Yojson.Basic.json
val array_level : int
val ast_file : string option
val blacklist : string option

@ -20,15 +20,24 @@ let dummy_constructor_annot = "__infer_is_constructor"
let annotation_of_str annot_str =
{ Annot.class_name = annot_str; parameters = []; }
(* TODO: read custom source/sink pairs from user code here *)
let src_snk_pairs () =
(* parse user-defined specs from .inferconfig *)
let parse_user_defined_specs = function
| `List user_specs ->
let parse_user_spec json =
let open Yojson.Basic.Util in
let sources = member "sources" json |> to_list |> List.map ~f:to_string in
let sinks = member "sink" json |> to_string in
sources, sinks in
List.map ~f:parse_user_spec user_specs
| _ ->
[] in
let specs =
[
([Annotations.performance_critical], Annotations.expensive);
([Annotations.no_allocation], dummy_constructor_annot);
([Annotations.any_thread; Annotations.for_non_ui_thread], Annotations.ui_thread);
([Annotations.ui_thread; Annotations.for_ui_thread], Annotations.for_non_ui_thread);
] in
([Annotations.performance_critical], Annotations.expensive) ::
([Annotations.no_allocation], dummy_constructor_annot) ::
([Annotations.any_thread; Annotations.for_non_ui_thread], Annotations.ui_thread) ::
([Annotations.ui_thread; Annotations.for_ui_thread], Annotations.for_non_ui_thread) ::
(parse_user_defined_specs Config.annotation_reachability) in
IList.map
(fun (src_annot_str_list, snk_annot_str) ->
IList.map annotation_of_str src_annot_str_list, annotation_of_str snk_annot_str)

@ -10,5 +10,11 @@
"class": "android.view.View",
"method": "findViewById"
}
],
"annotation-reachability": [
{
"sources": ["UserDefinedSource1", "UserDefinedSource2"],
"sink": "UserDefinedSink"
}
]
}

@ -0,0 +1,60 @@
/*
* Copyright (c) 2017 - 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.checkers;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.CLASS)
@interface UserDefinedSource1 {
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.CLASS)
@interface UserDefinedSource2 {
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.CLASS)
@interface UserDefinedSink {
}
class CustomAnnotations {
@UserDefinedSource1
void source1Bad() {
sink();
}
@UserDefinedSource2
void source2Bad() {
sink();
}
@UserDefinedSink
void sink() {
}
@UserDefinedSource1
void source1Ok() {
safeMethod();
}
@UserDefinedSource2
void source2Ok() {
safeMethod();
}
void safeMethod() {
}
}

@ -1,3 +1,5 @@
codetoanalyze/java/checkers/CustomAnnotations.java, void CustomAnnotations.source1Bad(), 1, CHECKERS_ANNOTATION_REACHABILITY_ERROR, []
codetoanalyze/java/checkers/CustomAnnotations.java, void CustomAnnotations.source2Bad(), 1, CHECKERS_ANNOTATION_REACHABILITY_ERROR, []
codetoanalyze/java/checkers/ExpensiveCallExample.java, View ExpensiveCallExample.callsFindViewByIdFromActivity(FragmentActivity,int), 1, CHECKERS_CALLS_EXPENSIVE_METHOD, []
codetoanalyze/java/checkers/ExpensiveCallExample.java, View ExpensiveCallExample.callsFindViewByIdFromView(ImageView,int), 1, CHECKERS_CALLS_EXPENSIVE_METHOD, []
codetoanalyze/java/checkers/ExpensiveCallExample.java, void ExpensiveCallExample.annotatedPerformanceCriticalInInterface(), 1, CHECKERS_CALLS_EXPENSIVE_METHOD, []

Loading…
Cancel
Save