From 3859f178faf6f24043169cfe78f22e399a8d529f Mon Sep 17 00:00:00 2001 From: Artem Pianykh Date: Tue, 25 Feb 2020 02:31:30 -0800 Subject: [PATCH] [nullsafe] Properly handle method calls on trusted classes under NullsafeLocal mode Summary: Now when typechecking a class `A` marked with `Nullsafe(LOCAL)`, classes from trusted list are properly recognized and nullability of method params and return value are refined to `LocallyCheckedNonnull` in a context of class `A`. NOTE: refininng nullability when **accessing fields** on trusted classes is **not implemented yet**, because the whole business of handling fields in nullsafe is somewhat convoluted. This should not be a huge issue though, since in Java fields are commonly accessed via getters any way. Reviewed By: mityal Differential Revision: D20056158 fbshipit-source-id: 496433d90 --- infer/src/nullsafe/AnnotatedField.ml | 4 ++- infer/src/nullsafe/AnnotatedNullability.ml | 11 +++++--- infer/src/nullsafe/AnnotatedNullability.mli | 10 +++++-- infer/src/nullsafe/AnnotatedSignature.ml | 23 ++++++++-------- infer/src/nullsafe/AnnotatedSignature.mli | 2 +- infer/src/nullsafe/Initializers.ml | 4 ++- infer/src/nullsafe/NullsafeMode.ml | 25 +++++++++++++++--- infer/src/nullsafe/NullsafeMode.mli | 6 +++++ infer/src/nullsafe/eradicate.ml | 14 ++++++++-- infer/src/nullsafe/eradicateChecks.ml | 9 +++++-- infer/src/nullsafe/models.ml | 9 ++++--- infer/src/nullsafe/typeCheck.ml | 17 ++++++++++-- .../java/nullsafe-default/NullsafeMode.java | 17 +++++++++--- .../java/nullsafe-default/issues.exp | 26 +++++++++---------- 14 files changed, 129 insertions(+), 48 deletions(-) diff --git a/infer/src/nullsafe/AnnotatedField.ml b/infer/src/nullsafe/AnnotatedField.ml index 18c66446a..4e6817f62 100644 --- a/infer/src/nullsafe/AnnotatedField.ml +++ b/infer/src/nullsafe/AnnotatedField.ml @@ -54,7 +54,9 @@ let get tenv field_name class_typ = in let is_enum_value = is_enum_value tenv ~class_typ field_info in let nullability = - AnnotatedNullability.of_type_and_annotation ~nullsafe_mode ~is_third_party field_typ annotations + (* TODO(T62825735): support trusted callees for fields *) + AnnotatedNullability.of_type_and_annotation ~is_trusted_callee:false ~nullsafe_mode + ~is_third_party field_typ annotations in let corrected_nullability = if Nullability.is_nonnullish (AnnotatedNullability.get_nullability nullability) && is_enum_value diff --git a/infer/src/nullsafe/AnnotatedNullability.ml b/infer/src/nullsafe/AnnotatedNullability.ml index 412a02a29..382aa0a8c 100644 --- a/infer/src/nullsafe/AnnotatedNullability.ml +++ b/infer/src/nullsafe/AnnotatedNullability.ml @@ -102,7 +102,7 @@ let pp fmt t = F.fprintf fmt "StrictNonnull[%s]" (string_of_nonnull_origin origin) -let of_type_and_annotation ~nullsafe_mode ~is_third_party typ annotations = +let of_type_and_annotation ~is_trusted_callee ~nullsafe_mode ~is_third_party typ annotations = if not (PatternMatch.type_is_class typ) then StrictNonnull PrimitiveType else if Annotations.ia_is_nullable annotations then let nullable_origin = @@ -118,6 +118,9 @@ let of_type_and_annotation ~nullsafe_mode ~is_third_party typ annotations = LocallyCheckedNonnull | NullsafeMode.Default -> if is_third_party then ThirdPartyNonnull - else if Annotations.ia_is_nonnull annotations then UncheckedNonnull AnnotatedNonnull - (* Currently, we treat not annotated types as nonnull *) - else UncheckedNonnull ImplicitlyNonnull + else + let preliminary_nullability = + if Annotations.ia_is_nonnull annotations then UncheckedNonnull AnnotatedNonnull + else UncheckedNonnull ImplicitlyNonnull + in + if is_trusted_callee then LocallyCheckedNonnull else preliminary_nullability diff --git a/infer/src/nullsafe/AnnotatedNullability.mli b/infer/src/nullsafe/AnnotatedNullability.mli index 19072069d..9a67e2aee 100644 --- a/infer/src/nullsafe/AnnotatedNullability.mli +++ b/infer/src/nullsafe/AnnotatedNullability.mli @@ -55,9 +55,15 @@ and strict_nonnull_origin = val get_nullability : t -> Nullability.t val of_type_and_annotation : - nullsafe_mode:NullsafeMode.t -> is_third_party:bool -> Typ.t -> Annot.Item.t -> t + is_trusted_callee:bool + -> nullsafe_mode:NullsafeMode.t + -> is_third_party:bool + -> Typ.t + -> Annot.Item.t + -> t (** Given the type and its annotations, returns its nullability. NOTE: it does not take into account models etc., so this is intended to be used as a helper function for more high-level annotation - processing. *) + processing. [is_trusted_callee] defines whether the callee class is in the caller's trust list + and therefore whether its nullability should be refined. *) val pp : Format.formatter -> t -> unit diff --git a/infer/src/nullsafe/AnnotatedSignature.ml b/infer/src/nullsafe/AnnotatedSignature.ml index 7da116ce0..6af6307c8 100644 --- a/infer/src/nullsafe/AnnotatedSignature.ml +++ b/infer/src/nullsafe/AnnotatedSignature.ml @@ -35,11 +35,11 @@ and model_source = InternalModel | ThirdPartyRepo of {filename: string; line_num [@@deriving compare] (* get nullability of method's return type given its annotations and information about its params *) -let nullability_for_return ret_type ret_annotations ~nullsafe_mode ~is_third_party - ~has_propagates_nullable_in_param = +let nullability_for_return ~is_trusted_callee ~nullsafe_mode ~is_third_party ret_type + ret_annotations ~has_propagates_nullable_in_param = let nullability = - AnnotatedNullability.of_type_and_annotation ~nullsafe_mode ~is_third_party ret_type - ret_annotations + AnnotatedNullability.of_type_and_annotation ~is_trusted_callee ~nullsafe_mode ~is_third_party + ret_type ret_annotations in (* if any param is annotated with propagates nullable, then the result is nullable *) match nullability with @@ -54,12 +54,12 @@ let nullability_for_return ret_type ret_annotations ~nullsafe_mode ~is_third_par (* Given annotations for method signature, extract nullability information for return type and params *) -let extract_nullability ~nullsafe_mode ~is_third_party ret_type ret_annotations +let extract_nullability ~is_trusted_callee ~nullsafe_mode ~is_third_party ret_type ret_annotations param_annotated_types = let params_nullability = List.map param_annotated_types ~f:(fun (typ, annotations) -> - AnnotatedNullability.of_type_and_annotation typ annotations ~nullsafe_mode ~is_third_party - ) + AnnotatedNullability.of_type_and_annotation ~is_trusted_callee ~nullsafe_mode + ~is_third_party typ annotations ) in let has_propagates_nullable_in_param = List.exists params_nullability ~f:(function @@ -69,13 +69,13 @@ let extract_nullability ~nullsafe_mode ~is_third_party ret_type ret_annotations false ) in let return_nullability = - nullability_for_return ret_type ret_annotations ~nullsafe_mode ~is_third_party - ~has_propagates_nullable_in_param + nullability_for_return ~is_trusted_callee ~nullsafe_mode ~is_third_party ret_type + ret_annotations ~has_propagates_nullable_in_param in (return_nullability, params_nullability) -let get ~nullsafe_mode proc_attributes : t = +let get ~is_trusted_callee ~nullsafe_mode proc_attributes : t = let Annot.Method.{return= ret_annotation; params= original_params_annotation} = proc_attributes.ProcAttributes.method_annotation in @@ -110,7 +110,8 @@ let get ~nullsafe_mode proc_attributes : t = List.map params_with_annotations ~f:(fun ((_, typ), annotations) -> (typ, annotations)) in let return_nullability, params_nullability = - extract_nullability ~nullsafe_mode ~is_third_party ret_type ret_annotation param_annotated_types + extract_nullability ~is_trusted_callee ~nullsafe_mode ~is_third_party ret_type ret_annotation + param_annotated_types in let ret = { ret_annotation_deprecated= ret_annotation diff --git a/infer/src/nullsafe/AnnotatedSignature.mli b/infer/src/nullsafe/AnnotatedSignature.mli index f5867c28b..8cfc99840 100644 --- a/infer/src/nullsafe/AnnotatedSignature.mli +++ b/infer/src/nullsafe/AnnotatedSignature.mli @@ -35,7 +35,7 @@ val set_modelled_nullability : Procname.t -> t -> model_source -> bool * bool li (** Override nullability for a function signature given its modelled nullability (for ret value and params) *) -val get : nullsafe_mode:NullsafeMode.t -> ProcAttributes.t -> t +val get : is_trusted_callee:bool -> nullsafe_mode:NullsafeMode.t -> ProcAttributes.t -> t (** Get a method signature with annotations from a proc_attributes. *) val pp : Procname.t -> Format.formatter -> t -> unit diff --git a/infer/src/nullsafe/Initializers.ml b/infer/src/nullsafe/Initializers.ml index 3c08e2c99..0808f41fc 100644 --- a/infer/src/nullsafe/Initializers.ml +++ b/infer/src/nullsafe/Initializers.ml @@ -111,7 +111,9 @@ let final_initializer_typestates_lazy tenv curr_pname curr_pdesc get_procs_in_fi PatternMatch.method_is_initializer tenv proc_attributes || let ia = - (Models.get_modelled_annotated_signature tenv proc_attributes).AnnotatedSignature.ret + (* TODO(T62825735): support trusted callees for fields *) + (Models.get_modelled_annotated_signature ~is_trusted_callee:false tenv proc_attributes) + .AnnotatedSignature.ret .ret_annotation_deprecated in Annotations.ia_is_initializer ia diff --git a/infer/src/nullsafe/NullsafeMode.ml b/infer/src/nullsafe/NullsafeMode.ml index 84a41e64e..b7dd8dd4e 100644 --- a/infer/src/nullsafe/NullsafeMode.ml +++ b/infer/src/nullsafe/NullsafeMode.ml @@ -29,21 +29,25 @@ module Trust = struct let* trust_classes = extract_trust_list trust_list in match trust_all with | None -> - return none + return (Only trust_classes) | Some (Annot.Bool trust_all') -> if trust_all' then return All else return (Only trust_classes) | _ -> None + let is_trusted_name t name = + match t with All -> true | Only classes -> List.exists classes ~f:(Typ.Name.equal name) + + let pp fmt t = match t with | All -> F.fprintf fmt "all" | Only [] -> F.fprintf fmt "none" - | Only names -> - F.fprintf fmt "[%a]" (F.pp_print_list ~pp_sep:F.pp_print_space Typ.Name.pp) names + | Only _names -> + F.fprintf fmt "selected" end type t = Default | Local of Trust.t | Strict [@@deriving compare, equal] @@ -93,4 +97,19 @@ let of_class tenv typ_name = Default +let of_procname tenv pname = + let class_name = + match pname with + | Procname.Java jn -> + Procname.Java.get_class_type_name jn + | _ -> + Logging.die InternalError "Unexpected non-Java procname %a" Procname.pp pname + in + of_class tenv class_name + + +let is_trusted_name t name = + match t with Strict -> false | Default -> true | Local trust -> Trust.is_trusted_name trust name + + let severity = function Strict | Local _ -> Exceptions.Error | Default -> Exceptions.Warning diff --git a/infer/src/nullsafe/NullsafeMode.mli b/infer/src/nullsafe/NullsafeMode.mli index 13ccf6c4f..dbd4ad911 100644 --- a/infer/src/nullsafe/NullsafeMode.mli +++ b/infer/src/nullsafe/NullsafeMode.mli @@ -32,6 +32,12 @@ val of_annot : Annot.t -> t option val of_class : Tenv.t -> Typ.name -> t (** Extracts mode information from class annotations *) +val of_procname : Tenv.t -> Procname.t -> t +(** Extracts mode information from a class where procname is defined *) + +val is_trusted_name : t -> Typ.name -> bool +(** Check whether [Typ.name] can be trusted under a given mode *) + val severity : t -> Exceptions.severity (** Provides a default choice of issue severity for a particular mode *) diff --git a/infer/src/nullsafe/eradicate.ml b/infer/src/nullsafe/eradicate.ml index 2f0c3884f..ad2a6eeb5 100644 --- a/infer/src/nullsafe/eradicate.ml +++ b/infer/src/nullsafe/eradicate.ml @@ -124,14 +124,22 @@ module MkCallback (Extension : ExtensionT) : CallBackT = struct let duplicate_nodes = find_duplicate_nodes node in try Procdesc.NodeSet.min_elt duplicate_nodes with Caml.Not_found -> node in + let caller_nullsafe_mode = NullsafeMode.of_procname tenv curr_pname in let typecheck_proc do_checks pname pdesc proc_details_opt = let ann_sig, loc, idenv_pn = match proc_details_opt with | Some (ann_sig, loc, idenv_pn) -> (ann_sig, loc, idenv_pn) | None -> + let is_trusted_callee = + let callee_class = Procname.get_class_type_name pname in + Option.value_map callee_class + ~f:(NullsafeMode.is_trusted_name caller_nullsafe_mode) + ~default:false + in let ann_sig = - Models.get_modelled_annotated_signature tenv (Procdesc.get_attributes pdesc) + Models.get_modelled_annotated_signature ~is_trusted_callee tenv + (Procdesc.get_attributes pdesc) in let loc = Procdesc.get_loc pdesc in (ann_sig, loc, Idenv.create pdesc) @@ -199,7 +207,9 @@ module MkCallback (Extension : ExtensionT) : CallBackT = struct then None else let annotated_signature = - Models.get_modelled_annotated_signature tenv (Procdesc.get_attributes proc_desc) + (* TODO(T62825735): fully support trusted callees; this could benefit from refactoring *) + Models.get_modelled_annotated_signature ~is_trusted_callee:false tenv + (Procdesc.get_attributes proc_desc) in Some annotated_signature in diff --git a/infer/src/nullsafe/eradicateChecks.ml b/infer/src/nullsafe/eradicateChecks.ml index 76d3a936b..9df7a574b 100644 --- a/infer/src/nullsafe/eradicateChecks.ml +++ b/infer/src/nullsafe/eradicateChecks.ml @@ -140,7 +140,8 @@ let check_field_assignment ~nullsafe_mode tenv find_canonical_duplicate curr_pde in let field_is_in_cleanup_context () = let AnnotatedSignature.{ret_annotation_deprecated} = - (Models.get_modelled_annotated_signature tenv curr_pattrs).ret + (* TODO(T62825735): support trusted callees for fields *) + (Models.get_modelled_annotated_signature ~is_trusted_callee:false tenv curr_pattrs).ret in Annotations.ia_is_cleanup ret_annotation_deprecated in @@ -558,7 +559,11 @@ let check_overridden_annotations find_canonical_duplicate tenv proc_name proc_de let check_if_base_signature_matches_current base_proc_name = match PatternMatch.lookup_attributes tenv base_proc_name with | Some base_attributes -> - let base_signature = Models.get_modelled_annotated_signature tenv base_attributes in + let base_signature = + (* TODO(T62825735): fully support trusted callees. Note that for inheritance + rule it doesn't make much difference, but would be nice to refactor anyway. *) + Models.get_modelled_annotated_signature ~is_trusted_callee:false tenv base_attributes + in check_inheritance_rule_for_signature ~nullsafe_mode:annotated_signature.AnnotatedSignature.nullsafe_mode find_canonical_duplicate tenv loc ~base_proc_name ~overridden_proc_name:proc_name diff --git a/infer/src/nullsafe/models.ml b/infer/src/nullsafe/models.ml index 45d3479eb..bb66f6516 100644 --- a/infer/src/nullsafe/models.ml +++ b/infer/src/nullsafe/models.ml @@ -34,7 +34,8 @@ let table_has_procedure table proc_name = let get_modelled_annotated_signature_for_biabduction proc_attributes = let proc_name = proc_attributes.ProcAttributes.proc_name in let annotated_signature = - AnnotatedSignature.get ~nullsafe_mode:NullsafeMode.Default proc_attributes + AnnotatedSignature.get ~is_trusted_callee:false ~nullsafe_mode:NullsafeMode.Default + proc_attributes in let proc_id = Procname.to_unique_id proc_name in let lookup_models_nullable ann_sig = @@ -66,13 +67,15 @@ let to_modelled_nullability ThirdPartyMethod.{ret_nullability; param_nullability (** Return the annotated signature of the procedure, taking into account models. External models take precedence over internal ones. *) -let get_modelled_annotated_signature tenv proc_attributes = +let get_modelled_annotated_signature ~is_trusted_callee tenv proc_attributes = let proc_name = proc_attributes.ProcAttributes.proc_name in let nullsafe_mode = Procname.get_class_type_name proc_name |> Option.value_map ~default:NullsafeMode.Default ~f:(NullsafeMode.of_class tenv) in - let annotated_signature = AnnotatedSignature.get ~nullsafe_mode proc_attributes in + let annotated_signature = + AnnotatedSignature.get ~is_trusted_callee ~nullsafe_mode proc_attributes + in let proc_id = Procname.to_unique_id proc_name in (* Look in the infer internal models *) let correct_by_internal_models ann_sig = diff --git a/infer/src/nullsafe/typeCheck.ml b/infer/src/nullsafe/typeCheck.ml index b929fa561..1873aa9a7 100644 --- a/infer/src/nullsafe/typeCheck.ml +++ b/infer/src/nullsafe/typeCheck.ml @@ -19,7 +19,10 @@ module ComplexExpressions = struct let is_annotated_with predicate tenv procname = match PatternMatch.lookup_attributes tenv procname with | Some proc_attributes -> - let annotated_signature = Models.get_modelled_annotated_signature tenv proc_attributes in + let annotated_signature = + (* TODO(T62825735): fully support trusted callees *) + Models.get_modelled_annotated_signature ~is_trusted_callee:false tenv proc_attributes + in let AnnotatedSignature.{ret_annotation_deprecated} = annotated_signature.ret in predicate ret_annotation_deprecated | None -> @@ -1016,7 +1019,17 @@ let typecheck_sil_call_function find_canonical_duplicate checks tenv instr_ref t in List.fold_right ~f:handle_et etl ~init:([], typestate) in - let callee_annotated_signature = Models.get_modelled_annotated_signature tenv callee_attributes in + let pname = callee_attributes.ProcAttributes.proc_name in + let is_trusted_callee = + let caller_nullsafe_mode = NullsafeMode.of_procname tenv curr_pname in + let callee_class = Procname.get_class_type_name pname in + Option.value_map callee_class + ~f:(NullsafeMode.is_trusted_name caller_nullsafe_mode) + ~default:false + in + let callee_annotated_signature = + Models.get_modelled_annotated_signature ~is_trusted_callee tenv callee_attributes + in let signature_params = drop_unchecked_signature_params callee_attributes callee_annotated_signature in diff --git a/infer/tests/codetoanalyze/java/nullsafe-default/NullsafeMode.java b/infer/tests/codetoanalyze/java/nullsafe-default/NullsafeMode.java index 4b4d1347b..f44cfdd6a 100644 --- a/infer/tests/codetoanalyze/java/nullsafe-default/NullsafeMode.java +++ b/infer/tests/codetoanalyze/java/nullsafe-default/NullsafeMode.java @@ -26,6 +26,8 @@ public class NullsafeMode { } static class NonNullsafe extends VariousMethods { + public String valField = "OK"; + String OK_passUncheckedToLocal(String arg) { return new TrustAllNullsafe().acceptVal(arg); } @@ -42,6 +44,11 @@ public class NullsafeMode { new ThirdPartyTestClass().paramUnspecified(returnNull()); return; } + + @Override + public String returnVal() { + return super.returnVal(); + } } static class AnotherNonNullsafe extends VariousMethods {} @@ -120,22 +127,26 @@ public class NullsafeMode { return "OK"; } - String FP_OK_returnFromNonNullsafe() { + String OK_returnFromTrustedNonNullsafe() { return new NonNullsafe().returnVal(); } - String BAD_returnFromAnotherNonNullsafe() { + String BAD_returnFromUntrustedNonNullsafe() { return new AnotherNonNullsafe().returnVal(); } @Nullable - String OK_returnFromAnotherNonNullsafeAsNullable() { + String OK_returnFromUntrustedNonNullsafeAsNullable() { return new AnotherNonNullsafe().returnVal(); } String BAD_returnNullFromNonNulsafe() { return new NonNullsafe().returnNull(); } + + String FP_OK_accessFieldFromNonNullsafe() { + return new NonNullsafe().valField; + } } @Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({})) diff --git a/infer/tests/codetoanalyze/java/nullsafe-default/issues.exp b/infer/tests/codetoanalyze/java/nullsafe-default/issues.exp index 5e1bef934..b6a157c4b 100644 --- a/infer/tests/codetoanalyze/java/nullsafe-default/issues.exp +++ b/infer/tests/codetoanalyze/java/nullsafe-default/issues.exp @@ -151,19 +151,19 @@ codetoanalyze/java/nullsafe-default/NullMethodCall.java, codetoanalyze.java.null codetoanalyze/java/nullsafe-default/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall.testSystemGetenvBad():int, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`envValue` is nullable and is not locally checked for null when calling `length()`: call to System.getenv(...) at line 240 (nullable according to nullsafe internal models).] codetoanalyze/java/nullsafe-default/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall.withConditionalAssignemnt(codetoanalyze.java.nullsafe_default.NullMethodCall$AnotherI,boolean,java.lang.Object,java.lang.Object):void, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`i` is nullable and is not locally checked for null when calling `withObjectParameter(...)`.] codetoanalyze/java/nullsafe-default/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall.withConjuction(codetoanalyze.java.nullsafe_default.NullMethodCall$AnotherI,boolean,boolean):void, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`i` is nullable and is not locally checked for null when calling `withBooleanParameter(...)`.] -codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$NullsafeWithStrictMode.BAD_returnFromNonStrict():java.lang.String, 0, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$VariousMethods.returnVal()`: `@NullsafeStrict` mode prohibits using values coming from non-strict classes without a check. Result of this call is used at line 164. Either add a local check for null or assertion, or make NullsafeMode$VariousMethods nullsafe strict.] -codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$StrictNullsafe.BAD_passThirdPartyToUnchecked():codetoanalyze.java.nullsafe_default.NullsafeMode$UncheckedParams, 0, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.getUncheckedLong(...)`: `@NullsafeStrict` mode prohibits using values coming from not vetted third party methods without a check. Result of this call is used at line 203. Either add a local check for null or assertion, or add the correct signature to nullsafe-default/third-party-signatures/some.test.pckg.sig.] -codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$StrictNullsafe.BAD_returnFromNonNullsafe():java.lang.String, 0, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$VariousMethods.returnVal()`: `@NullsafeStrict` mode prohibits using values coming from non-strict classes without a check. Result of this call is used at line 187. Either add a local check for null or assertion, or make NullsafeMode$VariousMethods nullsafe strict.] -codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustAllNullsafe.BAD_passThirdPartyToUnchecked():codetoanalyze.java.nullsafe_default.NullsafeMode$UncheckedParams, 0, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.getUncheckedLong(...)`: `@NullsafeLocal(trust=all)` mode prohibits using values coming from not vetted third party methods without a check. Result of this call is used at line 106. Either add a local check for null or assertion, or add the correct signature to nullsafe-default/third-party-signatures/some.test.pckg.sig.] -codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustAllNullsafe.BAD_returnFromUnvettedThirdParty():java.lang.String, 0, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.returnUnspecified()`: `@NullsafeLocal(trust=all)` mode prohibits using values coming from not vetted third party methods without a check. Result of this call is used at line 86. Either add a local check for null or assertion, or add the correct signature to nullsafe-default/third-party-signatures/some.test.pckg.sig.] -codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustAllNullsafe.BAD_returnNonNullableFieldFromThirdParty():java.lang.String, 0, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.nonNullableField`: `@NullsafeLocal(trust=all)` mode prohibits using values coming from third-party classes without a check. This field is used at line 94. Either add a local check for null or assertion, or access `nonNullableField` via a nullsafe getter.] -codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustAllNullsafe.BAD_returnNullFromNonNulsafe():java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, ERROR, [`BAD_returnNullFromNonNulsafe()`: return type is declared non-nullable but the method returns a nullable value: call to returnNull() at line 82.] -codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustAllNullsafe.BAD_returnNullableFieldFromThirdParty():java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, ERROR, [`BAD_returnNullableFieldFromThirdParty()`: return type is declared non-nullable but the method returns a nullable value: field nullableField at line 90.] -codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustNoneNullsafe.BAD_returnFromNonNullsafe():java.lang.String, 0, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$VariousMethods.returnVal()`: `@NullsafeLocal(trust=none)` mode prohibits using values coming from non-nullsafe classes without a check. Result of this call is used at line 144. Either add a local check for null or assertion, or make NullsafeMode$VariousMethods nullsafe.] -codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustSomeNullsafe.BAD_returnFromAnotherNonNullsafe():java.lang.String, 0, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$VariousMethods.returnVal()`: `@NullsafeLocal(trust=none)` mode prohibits using values coming from non-nullsafe classes without a check. Result of this call is used at line 128. Either add a local check for null or assertion, or make NullsafeMode$VariousMethods nullsafe.] -codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustSomeNullsafe.BAD_returnNullFromNonNulsafe():java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, ERROR, [`BAD_returnNullFromNonNulsafe()`: return type is declared non-nullable but the method returns a nullable value: call to returnNull() at line 137.] -codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustSomeNullsafe.FP_OK_returnFromNonNullsafe():java.lang.String, 0, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$VariousMethods.returnVal()`: `@NullsafeLocal(trust=none)` mode prohibits using values coming from non-nullsafe classes without a check. Result of this call is used at line 124. Either add a local check for null or assertion, or make NullsafeMode$VariousMethods nullsafe.] -codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustSomeNullsafe.OK_returnFromAnotherNonNullsafeAsNullable():java.lang.String, 0, ERADICATE_RETURN_OVER_ANNOTATED, no_bucket, WARNING, [Method `OK_returnFromAnotherNonNullsafeAsNullable()` is annotated with `@Nullable` but never returns null.] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$NullsafeWithStrictMode.BAD_returnFromNonStrict():java.lang.String, 0, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$VariousMethods.returnVal()`: `@NullsafeStrict` mode prohibits using values coming from non-strict classes without a check. Result of this call is used at line 175. Either add a local check for null or assertion, or make NullsafeMode$VariousMethods nullsafe strict.] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$StrictNullsafe.BAD_passThirdPartyToUnchecked():codetoanalyze.java.nullsafe_default.NullsafeMode$UncheckedParams, 0, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.getUncheckedLong(...)`: `@NullsafeStrict` mode prohibits using values coming from not vetted third party methods without a check. Result of this call is used at line 214. Either add a local check for null or assertion, or add the correct signature to nullsafe-default/third-party-signatures/some.test.pckg.sig.] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$StrictNullsafe.BAD_returnFromNonNullsafe():java.lang.String, 0, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$NonNullsafe.returnVal()`: `@NullsafeStrict` mode prohibits using values coming from non-strict classes without a check. Result of this call is used at line 198. Either add a local check for null or assertion, or make NullsafeMode$NonNullsafe nullsafe strict.] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustAllNullsafe.BAD_passThirdPartyToUnchecked():codetoanalyze.java.nullsafe_default.NullsafeMode$UncheckedParams, 0, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.getUncheckedLong(...)`: `@NullsafeLocal(trust=all)` mode prohibits using values coming from not vetted third party methods without a check. Result of this call is used at line 113. Either add a local check for null or assertion, or add the correct signature to nullsafe-default/third-party-signatures/some.test.pckg.sig.] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustAllNullsafe.BAD_returnFromUnvettedThirdParty():java.lang.String, 0, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.returnUnspecified()`: `@NullsafeLocal(trust=all)` mode prohibits using values coming from not vetted third party methods without a check. Result of this call is used at line 93. Either add a local check for null or assertion, or add the correct signature to nullsafe-default/third-party-signatures/some.test.pckg.sig.] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustAllNullsafe.BAD_returnNonNullableFieldFromThirdParty():java.lang.String, 0, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.nonNullableField`: `@NullsafeLocal(trust=all)` mode prohibits using values coming from third-party classes without a check. This field is used at line 101. Either add a local check for null or assertion, or access `nonNullableField` via a nullsafe getter.] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustAllNullsafe.BAD_returnNullFromNonNulsafe():java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, ERROR, [`BAD_returnNullFromNonNulsafe()`: return type is declared non-nullable but the method returns a nullable value: call to returnNull() at line 89.] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustAllNullsafe.BAD_returnNullableFieldFromThirdParty():java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, ERROR, [`BAD_returnNullableFieldFromThirdParty()`: return type is declared non-nullable but the method returns a nullable value: field nullableField at line 97.] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustNoneNullsafe.BAD_returnFromNonNullsafe():java.lang.String, 0, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$NonNullsafe.returnVal()`: `@NullsafeLocal(trust=none)` mode prohibits using values coming from non-nullsafe classes without a check. Result of this call is used at line 155. Either add a local check for null or assertion, or make NullsafeMode$NonNullsafe nullsafe.] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustSomeNullsafe.BAD_returnFromUntrustedNonNullsafe():java.lang.String, 0, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$VariousMethods.returnVal()`: `@NullsafeLocal(trust=selected)` mode prohibits using values coming from non-nullsafe classes without a check. Result of this call is used at line 135. Either add a local check for null or assertion, or make NullsafeMode$VariousMethods nullsafe.] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustSomeNullsafe.BAD_returnNullFromNonNulsafe():java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, ERROR, [`BAD_returnNullFromNonNulsafe()`: return type is declared non-nullable but the method returns a nullable value: call to returnNull() at line 144.] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustSomeNullsafe.FP_OK_accessFieldFromNonNullsafe():java.lang.String, 0, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$NonNullsafe.valField`: `@NullsafeLocal(trust=selected)` mode prohibits using values coming from non-nullsafe classes without a check. This field is used at line 148. Either add a local check for null or assertion, or make NullsafeMode$NonNullsafe nullsafe.] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustSomeNullsafe.OK_returnFromUntrustedNonNullsafeAsNullable():java.lang.String, 0, ERADICATE_RETURN_OVER_ANNOTATED, no_bucket, WARNING, [Method `OK_returnFromUntrustedNonNullsafeAsNullable()` is annotated with `@Nullable` but never returns null.] codetoanalyze/java/nullsafe-default/ParameterNotNullable.java, codetoanalyze.java.nullsafe_default.ParameterNotNullable$ConstructorCall.(codetoanalyze.java.nullsafe_default.ParameterNotNullable,int), 0, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`ParameterNotNullable$ConstructorCall(...)`: parameter #2(`s`) is declared non-nullable but the argument is `null`.] codetoanalyze/java/nullsafe-default/ParameterNotNullable.java, codetoanalyze.java.nullsafe_default.ParameterNotNullable.callNull():void, 1, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`ParameterNotNullable.test(...)`: parameter #1(`s`) is declared non-nullable but the argument `s` is `null`: null constant at line 39.] codetoanalyze/java/nullsafe-default/ParameterNotNullable.java, codetoanalyze.java.nullsafe_default.ParameterNotNullable.callNullable(java.lang.String):void, 0, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`ParameterNotNullable.test(...)`: parameter #1(`s`) is declared non-nullable but the argument `s` is nullable.]