Summary:
The problem is that in `AnnotatedField.special_case_nullability` we
first check the _generic_ nullability and if it is `nonnullish` we
apply refinements for enums, synthetic fields, etc.
The problem is that the definition of `is_nonnullish` changed in
D25186043 (7dcbacf693) to a stricter one `UncheckedNonnull`, but generic
nullability stayed the same `ThirdPartyNonnull`.
Therefore enum elements were not considered `nonnullish` under
`--no-nullsafe-optimistic-third-party-in-default-mode` and the enum
refinements were not applied, which led to bogus errors.
**Example:**
There's a third-party enum
```
enum EnumClass {
ENUM_ELEMENT
}
```
`ENUM_ELEMENT` is represented as a private static field of
`EnumClass`.
Then we have first party code that does
```
EnumClass.ENUM_ELEMENT
```
If this first party class is not `Nullsafe` and the checker is ran
with `--no-nullsafe-optimistic-third-party-in-default-mode`, the user
gets an incorrect warning about `ENUM_ELEMENT` being unvetted third
party.
Reviewed By: ngorogiannis
Differential Revision: D25560119
fbshipit-source-id: 4ad0760c5
master
Artem Pianykh4 years agocommitted byFacebook GitHub Bot
codetoanalyze/java/nullsafe/NullMethodCall.java, codetoanalyze.java.nullsafe.NullMethodCall.withConditionalAssignemnt(codetoanalyze.java.nullsafe.NullMethodCall$AnotherI,boolean,java.lang.Object,java.lang.Object):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`i` is nullable and is not locally checked for null when calling `withObjectParameter(...)`.], NullMethodCall, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullMethodCall.java, codetoanalyze.java.nullsafe.NullMethodCall.withConditionalAssignemnt(codetoanalyze.java.nullsafe.NullMethodCall$AnotherI,boolean,java.lang.Object,java.lang.Object):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`i` is nullable and is not locally checked for null when calling `withObjectParameter(...)`.], NullMethodCall, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullMethodCall.java, codetoanalyze.java.nullsafe.NullMethodCall.withConjuction(codetoanalyze.java.nullsafe.NullMethodCall$AnotherI,boolean,boolean):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`i` is nullable and is not locally checked for null when calling `withBooleanParameter(...)`.], NullMethodCall, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullMethodCall.java, codetoanalyze.java.nullsafe.NullMethodCall.withConjuction(codetoanalyze.java.nullsafe.NullMethodCall$AnotherI,boolean,boolean):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`i` is nullable and is not locally checked for null when calling `withBooleanParameter(...)`.], NullMethodCall, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$NullsafeWithStrictMode.BAD_returnFromNonStrict():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$VariousMethods.returnVal()`: `@Nullsafe(STRICT)` prohibits using values coming from non-strict classes without a check. Result of this call is used at line 174. Either add a local check for null or assertion, or make `NullsafeMode$VariousMethods` nullsafe strict.], NullsafeMode$NullsafeWithStrictMode, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$NullsafeWithStrictMode.BAD_returnFromNonStrict():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$VariousMethods.returnVal()`: `@Nullsafe(STRICT)` prohibits using values coming from non-strict classes without a check. Result of this call is used at line 178. Either add a local check for null or assertion, or make `NullsafeMode$VariousMethods` nullsafe strict.], NullsafeMode$NullsafeWithStrictMode, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$StrictNullsafe.BAD_dereferenceNotAnnotatedThirdParty():void, 1, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.returnUnspecified()`: `@Nullsafe` mode prohibits using values coming from not vetted third party methods without a check. Result of this call is used at line 218. Either add a local check for null or assertion, or add the correct signature to nullsafe/third-party-signatures/some.test.pckg.sig.], NullsafeMode$StrictNullsafe, codetoanalyze.java.nullsafe, unvetted_3rd_party:[some.test.pckg.ThirdPartyTestClass#returnUnspecified()]
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$StrictNullsafe.BAD_dereferenceNotAnnotatedThirdParty():void, 1, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.returnUnspecified()`: `@Nullsafe` mode prohibits using values coming from not vetted third party methods without a check. Result of this call is used at line 222. Either add a local check for null or assertion, or add the correct signature to nullsafe/third-party-signatures/some.test.pckg.sig.], NullsafeMode$StrictNullsafe, codetoanalyze.java.nullsafe, unvetted_3rd_party:[some.test.pckg.ThirdPartyTestClass#returnUnspecified()]
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$StrictNullsafe.BAD_passThirdPartyToUnchecked():codetoanalyze.java.nullsafe.NullsafeMode$UncheckedParams, 1, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.getUncheckedLong(...)`: `@Nullsafe` 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/third-party-signatures/some.test.pckg.sig.], NullsafeMode$StrictNullsafe, codetoanalyze.java.nullsafe, unvetted_3rd_party:[some.test.pckg.ThirdPartyTestClass#getUncheckedLong(long)]
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$StrictNullsafe.BAD_passThirdPartyToUnchecked():codetoanalyze.java.nullsafe.NullsafeMode$UncheckedParams, 1, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.getUncheckedLong(...)`: `@Nullsafe` mode prohibits using values coming from not vetted third party methods without a check. Result of this call is used at line 218. Either add a local check for null or assertion, or add the correct signature to nullsafe/third-party-signatures/some.test.pckg.sig.], NullsafeMode$StrictNullsafe, codetoanalyze.java.nullsafe, unvetted_3rd_party:[some.test.pckg.ThirdPartyTestClass#getUncheckedLong(long)]
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$StrictNullsafe.BAD_returnFromNonNullsafe():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$NonNullsafe.returnVal()`: `@Nullsafe(STRICT)` prohibits using values coming from non-strict classes without a check. Result of this call is used at line 197. Either add a local check for null or assertion, or make `NullsafeMode$NonNullsafe` nullsafe strict.], NullsafeMode$StrictNullsafe, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$StrictNullsafe.BAD_returnFromNonNullsafe():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$NonNullsafe.returnVal()`: `@Nullsafe(STRICT)` prohibits using values coming from non-strict classes without a check. Result of this call is used at line 201. Either add a local check for null or assertion, or make `NullsafeMode$NonNullsafe` nullsafe strict.], NullsafeMode$StrictNullsafe, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$TrustAllNullsafe.BAD_passThirdPartyToUnchecked():codetoanalyze.java.nullsafe.NullsafeMode$UncheckedParams, 1, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.getUncheckedLong(...)`: `@Nullsafe` 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/third-party-signatures/some.test.pckg.sig.], NullsafeMode$TrustAllNullsafe, codetoanalyze.java.nullsafe, unvetted_3rd_party:[some.test.pckg.ThirdPartyTestClass#getUncheckedLong(long)]
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$TrustAllNullsafe.BAD_passThirdPartyToUnchecked():codetoanalyze.java.nullsafe.NullsafeMode$UncheckedParams, 1, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.getUncheckedLong(...)`: `@Nullsafe` 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/third-party-signatures/some.test.pckg.sig.], NullsafeMode$TrustAllNullsafe, codetoanalyze.java.nullsafe, unvetted_3rd_party:[some.test.pckg.ThirdPartyTestClass#getUncheckedLong(long)]
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$TrustAllNullsafe.BAD_returnFromUnvettedThirdParty():java.lang.String, 1, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.returnUnspecified()`: `@Nullsafe` mode prohibits using values coming from not vetted third party methods without a check. Result of this call is used at line 92. Either add a local check for null or assertion, or add the correct signature to nullsafe/third-party-signatures/some.test.pckg.sig.], NullsafeMode$TrustAllNullsafe, codetoanalyze.java.nullsafe, unvetted_3rd_party:[some.test.pckg.ThirdPartyTestClass#returnUnspecified()]
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$TrustAllNullsafe.BAD_returnFromUnvettedThirdParty():java.lang.String, 1, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.returnUnspecified()`: `@Nullsafe` mode prohibits using values coming from not vetted third party methods without a check. Result of this call is used at line 92. Either add a local check for null or assertion, or add the correct signature to nullsafe/third-party-signatures/some.test.pckg.sig.], NullsafeMode$TrustAllNullsafe, codetoanalyze.java.nullsafe, unvetted_3rd_party:[some.test.pckg.ThirdPartyTestClass#returnUnspecified()]
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$TrustAllNullsafe.BAD_returnNonNullableFieldFromThirdParty():java.lang.String, 1, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.nonNullableField`: `@Nullsafe` mode prohibits using values coming from not vetted third party fields without a check. This field is used at line 100. Either add a local check for null or assertion, or access `nonNullableField` via a nullsafe getter.], NullsafeMode$TrustAllNullsafe, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$TrustAllNullsafe.BAD_returnNonNullableFieldFromThirdParty():java.lang.String, 1, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.nonNullableField`: `@Nullsafe` mode prohibits using values coming from not vetted third party fields without a check. This field is used at line 100. Either add a local check for null or assertion, or access `nonNullableField` via a nullsafe getter.], NullsafeMode$TrustAllNullsafe, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.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.], NullsafeMode$TrustAllNullsafe, codetoanalyze.java.nullsafe, nullable_methods:codetoanalyze.java.nullsafe.NullsafeMode$VariousMethods.returnNull at 89
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.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.], NullsafeMode$TrustAllNullsafe, codetoanalyze.java.nullsafe, nullable_methods:codetoanalyze.java.nullsafe.NullsafeMode$VariousMethods.returnNull at 89
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.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.], NullsafeMode$TrustAllNullsafe, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.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.], NullsafeMode$TrustAllNullsafe, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$TrustNoneNullsafe.BAD_returnFromNonNullsafe():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$NonNullsafe.returnVal()`: `@Nullsafe(trust={...})` prohibits using values coming from non-`@Nullsafe` classes without a check, unless the class is in the trust list. Result of this call is used at line 154. Either add a local check for null or assertion, or make `NullsafeMode$NonNullsafe` @Nullsafe (or add it to trust list).], NullsafeMode$TrustNoneNullsafe, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$TrustNoneNullsafe.BAD_returnFromNonNullsafe():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$NonNullsafe.returnVal()`: `@Nullsafe(trust={...})` prohibits using values coming from non-`@Nullsafe` classes without a check, unless the class is in the trust list. Result of this call is used at line 158. Either add a local check for null or assertion, or make `NullsafeMode$NonNullsafe` @Nullsafe (or add it to trust list).], NullsafeMode$TrustNoneNullsafe, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$TrustSomeNullsafe.BAD_returnFromUntrustedNonNullsafe():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$VariousMethods.returnVal()`: `@Nullsafe(trust={...})` prohibits using values coming from non-`@Nullsafe` classes without a check, unless the class is in the trust list. Result of this call is used at line 134. Either add a local check for null or assertion, or make `NullsafeMode$VariousMethods` @Nullsafe (or add it to trust list).], NullsafeMode$TrustSomeNullsafe, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$TrustSomeNullsafe.BAD_returnFromUntrustedNonNullsafe():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$VariousMethods.returnVal()`: `@Nullsafe(trust={...})` prohibits using values coming from non-`@Nullsafe` classes without a check, unless the class is in the trust list. Result of this call is used at line 138. Either add a local check for null or assertion, or make `NullsafeMode$VariousMethods` @Nullsafe (or add it to trust list).], NullsafeMode$TrustSomeNullsafe, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.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.], NullsafeMode$TrustSomeNullsafe, codetoanalyze.java.nullsafe, nullable_methods:codetoanalyze.java.nullsafe.NullsafeMode$VariousMethods.returnNull at 144
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.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 148.], NullsafeMode$TrustSomeNullsafe, codetoanalyze.java.nullsafe, nullable_methods:codetoanalyze.java.nullsafe.NullsafeMode$VariousMethods.returnNull at 148
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$TrustSomeNullsafe.FP_OK_accessFieldFromNonNullsafe():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$NonNullsafe.valField`: `@Nullsafe(trust={...})` prohibits using values coming from non-`@Nullsafe` classes without a check, unless the class is in the trust list. This field is used at line 147. Either add a local check for null or assertion, or make `NullsafeMode$NonNullsafe` @Nullsafe (or add it to trust list).], NullsafeMode$TrustSomeNullsafe, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$TrustSomeNullsafe.FP_OK_accessFieldFromNonNullsafe():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$NonNullsafe.valField`: `@Nullsafe(trust={...})` prohibits using values coming from non-`@Nullsafe` classes without a check, unless the class is in the trust list. This field is used at line 151. Either add a local check for null or assertion, or make `NullsafeMode$NonNullsafe` @Nullsafe (or add it to trust list).], NullsafeMode$TrustSomeNullsafe, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$TrustSomeNullsafe.OK_returnFromUntrustedNonNullsafeAsNullable():java.lang.String, 0, ERADICATE_RETURN_OVER_ANNOTATED, no_bucket, ADVICE, [Method `OK_returnFromUntrustedNonNullsafeAsNullable()` is annotated with `@Nullable` but never returns null.], NullsafeMode$TrustSomeNullsafe, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe.NullsafeMode$TrustSomeNullsafe.OK_returnFromUntrustedNonNullsafeAsNullable():java.lang.String, 0, ERADICATE_RETURN_OVER_ANNOTATED, no_bucket, ADVICE, [Method `OK_returnFromUntrustedNonNullsafeAsNullable()` is annotated with `@Nullable` but never returns null.], NullsafeMode$TrustSomeNullsafe, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 49, ERADICATE_REDUNDANT_NESTED_CLASS_ANNOTATION, no_bucket, ADVICE, [`NullsafeLocal$NestedExplicitLocal`: the same @Nullsafe mode is already specified in the outer class, so this annotation can be removed.], NullsafeLocal$NestedExplicitLocal, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 49, ERADICATE_REDUNDANT_NESTED_CLASS_ANNOTATION, no_bucket, ADVICE, [`NullsafeLocal$NestedExplicitLocal`: the same @Nullsafe mode is already specified in the outer class, so this annotation can be removed.], NullsafeLocal$NestedExplicitLocal, codetoanalyze.java.nullsafe