[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
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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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 *)

@ -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

@ -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

@ -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 =

@ -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

@ -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({}))

@ -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.<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.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