diff --git a/infer/src/quandary/ClangTrace.ml b/infer/src/quandary/ClangTrace.ml index 523c24d88..b82dd867d 100644 --- a/infer/src/quandary/ClangTrace.ml +++ b/infer/src/quandary/ClangTrace.ml @@ -140,7 +140,8 @@ module SinkKind = struct (QuandaryConfig.Sink.of_json Config.quandary_sinks) (* taint the nth parameter (0-indexed) *) - let taint_nth n kind = Some (kind, IntSet.singleton n) + let taint_nth n kind actuals = + if n < List.length actuals then Some (kind, IntSet.singleton n) else None let taint_all actuals kind = Some (kind, IntSet.of_list (List.mapi ~f:(fun actual_num _ -> actual_num) actuals)) @@ -154,7 +155,7 @@ module SinkKind = struct let kind = of_string kind in try let n = int_of_string index in - taint_nth n kind + taint_nth n kind actuals with Failure _ -> (* couldn't parse the index, just taint everything *) taint_all actuals kind diff --git a/infer/src/quandary/JavaTrace.ml b/infer/src/quandary/JavaTrace.ml index 91df8b7c8..cbdd98313 100644 --- a/infer/src/quandary/JavaTrace.ml +++ b/infer/src/quandary/JavaTrace.ml @@ -221,7 +221,7 @@ module SinkKind = struct (* taint the nth non-"this" parameter (0-indexed) *) let taint_nth n kind = let first_index = if Typ.Procname.java_is_static pname then n else n + 1 in - Some (kind, IntSet.singleton first_index) + if first_index < List.length actuals then Some (kind, IntSet.singleton first_index) else None in match pname with | Typ.Procname.Java java_pname -> ( diff --git a/infer/src/quandary/TaintAnalysis.ml b/infer/src/quandary/TaintAnalysis.ml index a8fe9b18e..b915c6e5a 100644 --- a/infer/src/quandary/TaintAnalysis.ml +++ b/infer/src/quandary/TaintAnalysis.ml @@ -254,10 +254,9 @@ module Make (TaintSpecification : TaintSpec.S) = struct | None -> access_tree_acc ) | None - -> Logging.internal_error + -> failwithf "Taint is supposed to flow into sink %a at index %d, but the index is out of bounds@\n" - CallSite.pp callee_site sink_index ; - access_tree_acc + CallSite.pp callee_site sink_index | _ -> access_tree_acc in @@ -466,7 +465,10 @@ module Make (TaintSpecification : TaintSpec.S) = struct in let analyze_call astate_acc callee_pname = let call_site = CallSite.make callee_pname callee_loc in - let sink = TraceDomain.Sink.get call_site actuals proc_data.ProcData.tenv in + let sink = + if List.is_empty actuals then None + else TraceDomain.Sink.get call_site actuals proc_data.ProcData.tenv + in let astate_with_sink = match sink with | Some sink diff --git a/infer/tests/codetoanalyze/java/quandary/ExternalSpecs.java b/infer/tests/codetoanalyze/java/quandary/ExternalSpecs.java index 11247a98a..96e213466 100644 --- a/infer/tests/codetoanalyze/java/quandary/ExternalSpecs.java +++ b/infer/tests/codetoanalyze/java/quandary/ExternalSpecs.java @@ -102,5 +102,16 @@ public class ExternalSpecs { return sanitized; } + // if theres' a procedure with the same name defined in .inferconfig as a sink on parameter 1, + // we shouldn't crash + public static void loggingSink1() {} + + // we shouldn't fail when calling this either + public static void loggingSink1(Object notASink) { } + + void callLoggingSink1sOk(Object o) { + loggingSink1(); + loggingSink1(o); + } }