[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
master
Artem Pianykh 5 years ago committed by Facebook Github Bot
parent 7219cb1eff
commit 3859f178fa

@ -54,7 +54,9 @@ let get tenv field_name class_typ =
in in
let is_enum_value = is_enum_value tenv ~class_typ field_info in let is_enum_value = is_enum_value tenv ~class_typ field_info in
let nullability = 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 in
let corrected_nullability = let corrected_nullability =
if Nullability.is_nonnullish (AnnotatedNullability.get_nullability nullability) && is_enum_value if Nullability.is_nonnullish (AnnotatedNullability.get_nullability nullability) && is_enum_value

@ -102,7 +102,7 @@ let pp fmt t =
F.fprintf fmt "StrictNonnull[%s]" (string_of_nonnull_origin origin) 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 if not (PatternMatch.type_is_class typ) then StrictNonnull PrimitiveType
else if Annotations.ia_is_nullable annotations then else if Annotations.ia_is_nullable annotations then
let nullable_origin = let nullable_origin =
@ -118,6 +118,9 @@ let of_type_and_annotation ~nullsafe_mode ~is_third_party typ annotations =
LocallyCheckedNonnull LocallyCheckedNonnull
| NullsafeMode.Default -> | NullsafeMode.Default ->
if is_third_party then ThirdPartyNonnull if is_third_party then ThirdPartyNonnull
else if Annotations.ia_is_nonnull annotations then UncheckedNonnull AnnotatedNonnull else
(* Currently, we treat not annotated types as nonnull *) let preliminary_nullability =
else UncheckedNonnull ImplicitlyNonnull if Annotations.ia_is_nonnull annotations then UncheckedNonnull AnnotatedNonnull
else UncheckedNonnull ImplicitlyNonnull
in
if is_trusted_callee then LocallyCheckedNonnull else preliminary_nullability

@ -55,9 +55,15 @@ and strict_nonnull_origin =
val get_nullability : t -> Nullability.t val get_nullability : t -> Nullability.t
val of_type_and_annotation : 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 (** 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 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 val pp : Format.formatter -> t -> unit

@ -35,11 +35,11 @@ and model_source = InternalModel | ThirdPartyRepo of {filename: string; line_num
[@@deriving compare] [@@deriving compare]
(* get nullability of method's return type given its annotations and information about its params *) (* 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 let nullability_for_return ~is_trusted_callee ~nullsafe_mode ~is_third_party ret_type
~has_propagates_nullable_in_param = ret_annotations ~has_propagates_nullable_in_param =
let nullability = let nullability =
AnnotatedNullability.of_type_and_annotation ~nullsafe_mode ~is_third_party ret_type AnnotatedNullability.of_type_and_annotation ~is_trusted_callee ~nullsafe_mode ~is_third_party
ret_annotations ret_type ret_annotations
in in
(* if any param is annotated with propagates nullable, then the result is nullable *) (* if any param is annotated with propagates nullable, then the result is nullable *)
match nullability with 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 (* Given annotations for method signature, extract nullability information
for return type and params *) 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 = param_annotated_types =
let params_nullability = let params_nullability =
List.map param_annotated_types ~f:(fun (typ, annotations) -> 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 in
let has_propagates_nullable_in_param = let has_propagates_nullable_in_param =
List.exists params_nullability ~f:(function List.exists params_nullability ~f:(function
@ -69,13 +69,13 @@ let extract_nullability ~nullsafe_mode ~is_third_party ret_type ret_annotations
false ) false )
in in
let return_nullability = let return_nullability =
nullability_for_return ret_type ret_annotations ~nullsafe_mode ~is_third_party nullability_for_return ~is_trusted_callee ~nullsafe_mode ~is_third_party ret_type
~has_propagates_nullable_in_param ret_annotations ~has_propagates_nullable_in_param
in in
(return_nullability, params_nullability) (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} = let Annot.Method.{return= ret_annotation; params= original_params_annotation} =
proc_attributes.ProcAttributes.method_annotation proc_attributes.ProcAttributes.method_annotation
in in
@ -110,7 +110,8 @@ let get ~nullsafe_mode proc_attributes : t =
List.map params_with_annotations ~f:(fun ((_, typ), annotations) -> (typ, annotations)) List.map params_with_annotations ~f:(fun ((_, typ), annotations) -> (typ, annotations))
in in
let return_nullability, params_nullability = 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 in
let ret = let ret =
{ ret_annotation_deprecated= ret_annotation { ret_annotation_deprecated= ret_annotation

@ -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 (** Override nullability for a function signature given its modelled nullability (for ret value and
params) *) 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. *) (** Get a method signature with annotations from a proc_attributes. *)
val pp : Procname.t -> Format.formatter -> t -> unit val pp : Procname.t -> Format.formatter -> t -> unit

@ -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 PatternMatch.method_is_initializer tenv proc_attributes
|| ||
let ia = 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 .ret_annotation_deprecated
in in
Annotations.ia_is_initializer ia Annotations.ia_is_initializer ia

@ -29,21 +29,25 @@ module Trust = struct
let* trust_classes = extract_trust_list trust_list in let* trust_classes = extract_trust_list trust_list in
match trust_all with match trust_all with
| None -> | None ->
return none return (Only trust_classes)
| Some (Annot.Bool trust_all') -> | Some (Annot.Bool trust_all') ->
if trust_all' then return All else return (Only trust_classes) if trust_all' then return All else return (Only trust_classes)
| _ -> | _ ->
None 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 = let pp fmt t =
match t with match t with
| All -> | All ->
F.fprintf fmt "all" F.fprintf fmt "all"
| Only [] -> | Only [] ->
F.fprintf fmt "none" F.fprintf fmt "none"
| Only names -> | Only _names ->
F.fprintf fmt "[%a]" (F.pp_print_list ~pp_sep:F.pp_print_space Typ.Name.pp) names F.fprintf fmt "selected"
end end
type t = Default | Local of Trust.t | Strict [@@deriving compare, equal] type t = Default | Local of Trust.t | Strict [@@deriving compare, equal]
@ -93,4 +97,19 @@ let of_class tenv typ_name =
Default 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 let severity = function Strict | Local _ -> Exceptions.Error | Default -> Exceptions.Warning

@ -32,6 +32,12 @@ val of_annot : Annot.t -> t option
val of_class : Tenv.t -> Typ.name -> t val of_class : Tenv.t -> Typ.name -> t
(** Extracts mode information from class annotations *) (** 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 val severity : t -> Exceptions.severity
(** Provides a default choice of issue severity for a particular mode *) (** Provides a default choice of issue severity for a particular mode *)

@ -124,14 +124,22 @@ module MkCallback (Extension : ExtensionT) : CallBackT = struct
let duplicate_nodes = find_duplicate_nodes node in let duplicate_nodes = find_duplicate_nodes node in
try Procdesc.NodeSet.min_elt duplicate_nodes with Caml.Not_found -> node try Procdesc.NodeSet.min_elt duplicate_nodes with Caml.Not_found -> node
in in
let caller_nullsafe_mode = NullsafeMode.of_procname tenv curr_pname in
let typecheck_proc do_checks pname pdesc proc_details_opt = let typecheck_proc do_checks pname pdesc proc_details_opt =
let ann_sig, loc, idenv_pn = let ann_sig, loc, idenv_pn =
match proc_details_opt with match proc_details_opt with
| Some (ann_sig, loc, idenv_pn) -> | Some (ann_sig, loc, idenv_pn) ->
(ann_sig, loc, idenv_pn) (ann_sig, loc, idenv_pn)
| None -> | 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 = 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 in
let loc = Procdesc.get_loc pdesc in let loc = Procdesc.get_loc pdesc in
(ann_sig, loc, Idenv.create pdesc) (ann_sig, loc, Idenv.create pdesc)
@ -199,7 +207,9 @@ module MkCallback (Extension : ExtensionT) : CallBackT = struct
then None then None
else else
let annotated_signature = 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 in
Some annotated_signature Some annotated_signature
in in

@ -140,7 +140,8 @@ let check_field_assignment ~nullsafe_mode tenv find_canonical_duplicate curr_pde
in in
let field_is_in_cleanup_context () = let field_is_in_cleanup_context () =
let AnnotatedSignature.{ret_annotation_deprecated} = 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 in
Annotations.ia_is_cleanup ret_annotation_deprecated Annotations.ia_is_cleanup ret_annotation_deprecated
in 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 = let check_if_base_signature_matches_current base_proc_name =
match PatternMatch.lookup_attributes tenv base_proc_name with match PatternMatch.lookup_attributes tenv base_proc_name with
| Some base_attributes -> | 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 check_inheritance_rule_for_signature
~nullsafe_mode:annotated_signature.AnnotatedSignature.nullsafe_mode ~nullsafe_mode:annotated_signature.AnnotatedSignature.nullsafe_mode
find_canonical_duplicate tenv loc ~base_proc_name ~overridden_proc_name:proc_name find_canonical_duplicate tenv loc ~base_proc_name ~overridden_proc_name:proc_name

@ -34,7 +34,8 @@ let table_has_procedure table proc_name =
let get_modelled_annotated_signature_for_biabduction proc_attributes = let get_modelled_annotated_signature_for_biabduction proc_attributes =
let proc_name = proc_attributes.ProcAttributes.proc_name in let proc_name = proc_attributes.ProcAttributes.proc_name in
let annotated_signature = let annotated_signature =
AnnotatedSignature.get ~nullsafe_mode:NullsafeMode.Default proc_attributes AnnotatedSignature.get ~is_trusted_callee:false ~nullsafe_mode:NullsafeMode.Default
proc_attributes
in in
let proc_id = Procname.to_unique_id proc_name in let proc_id = Procname.to_unique_id proc_name in
let lookup_models_nullable ann_sig = 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 (** Return the annotated signature of the procedure, taking into account models. External models
take precedence over internal ones. *) 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 proc_name = proc_attributes.ProcAttributes.proc_name in
let nullsafe_mode = let nullsafe_mode =
Procname.get_class_type_name proc_name Procname.get_class_type_name proc_name
|> Option.value_map ~default:NullsafeMode.Default ~f:(NullsafeMode.of_class tenv) |> Option.value_map ~default:NullsafeMode.Default ~f:(NullsafeMode.of_class tenv)
in 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 let proc_id = Procname.to_unique_id proc_name in
(* Look in the infer internal models *) (* Look in the infer internal models *)
let correct_by_internal_models ann_sig = let correct_by_internal_models ann_sig =

@ -19,7 +19,10 @@ module ComplexExpressions = struct
let is_annotated_with predicate tenv procname = let is_annotated_with predicate tenv procname =
match PatternMatch.lookup_attributes tenv procname with match PatternMatch.lookup_attributes tenv procname with
| Some proc_attributes -> | 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 let AnnotatedSignature.{ret_annotation_deprecated} = annotated_signature.ret in
predicate ret_annotation_deprecated predicate ret_annotation_deprecated
| None -> | None ->
@ -1016,7 +1019,17 @@ let typecheck_sil_call_function find_canonical_duplicate checks tenv instr_ref t
in in
List.fold_right ~f:handle_et etl ~init:([], typestate) List.fold_right ~f:handle_et etl ~init:([], typestate)
in 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 = let signature_params =
drop_unchecked_signature_params callee_attributes callee_annotated_signature drop_unchecked_signature_params callee_attributes callee_annotated_signature
in in

@ -26,6 +26,8 @@ public class NullsafeMode {
} }
static class NonNullsafe extends VariousMethods { static class NonNullsafe extends VariousMethods {
public String valField = "OK";
String OK_passUncheckedToLocal(String arg) { String OK_passUncheckedToLocal(String arg) {
return new TrustAllNullsafe().acceptVal(arg); return new TrustAllNullsafe().acceptVal(arg);
} }
@ -42,6 +44,11 @@ public class NullsafeMode {
new ThirdPartyTestClass().paramUnspecified(returnNull()); new ThirdPartyTestClass().paramUnspecified(returnNull());
return; return;
} }
@Override
public String returnVal() {
return super.returnVal();
}
} }
static class AnotherNonNullsafe extends VariousMethods {} static class AnotherNonNullsafe extends VariousMethods {}
@ -120,22 +127,26 @@ public class NullsafeMode {
return "OK"; return "OK";
} }
String FP_OK_returnFromNonNullsafe() { String OK_returnFromTrustedNonNullsafe() {
return new NonNullsafe().returnVal(); return new NonNullsafe().returnVal();
} }
String BAD_returnFromAnotherNonNullsafe() { String BAD_returnFromUntrustedNonNullsafe() {
return new AnotherNonNullsafe().returnVal(); return new AnotherNonNullsafe().returnVal();
} }
@Nullable @Nullable
String OK_returnFromAnotherNonNullsafeAsNullable() { String OK_returnFromUntrustedNonNullsafeAsNullable() {
return new AnotherNonNullsafe().returnVal(); return new AnotherNonNullsafe().returnVal();
} }
String BAD_returnNullFromNonNulsafe() { String BAD_returnNullFromNonNulsafe() {
return new NonNullsafe().returnNull(); return new NonNullsafe().returnNull();
} }
String FP_OK_accessFieldFromNonNullsafe() {
return new NonNullsafe().valField;
}
} }
@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({})) @Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))

@ -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.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.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/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$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 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_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$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$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 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_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 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_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 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_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 82.] 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 90.] 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$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$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_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_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 137.] 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_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.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_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$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.<init>(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$ConstructorCall.<init>(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.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.] 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.]

Loading…
Cancel
Save