Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nullness annotations to gson [review 1] #1

Open
wants to merge 18 commits into
base: master
Choose a base branch
from

Conversation

PRITI1999
Copy link

@Maxi17, annotations are added for nullness checker according to week 1 of plan.

@Maxi17 Maxi17 self-requested a review June 8, 2020 12:42
Copy link
Collaborator

@Maxi17 Maxi17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PRITI1999 This is an initial review. Please go through my comments and address them. When you are ready, request my review again. Good job so far!

@@ -146,7 +147,7 @@ public boolean hasModifier(int modifier) {
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
Object get(Object instance) throws IllegalAccessException {
@Nullable Object get(Object instance) throws IllegalAccessException {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the documentation it is not specified that the return result can be null. This annotation is forced here because the method get(Object) in java.lang.reflect has its return type annotated with @Nullable. I am not sure if this annotation is correct, since get from jdk.internal.reflect.FieldAccessor.java is not annotated as @Nullable.

@@ -39,7 +41,6 @@
public JsonArray() {
elements = new ArrayList<JsonElement>();
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid this type of changes.

gson/src/main/java/com/google/gson/TypeAdapter.java Outdated Show resolved Hide resolved
gson/src/main/java/com/google/gson/Gson.java Show resolved Hide resolved
gson/src/main/java/com/google/gson/Gson.java Outdated Show resolved Hide resolved
@@ -389,8 +392,10 @@ static void checkValidFloatingPoint(double value) {
@Override public void write(JsonWriter out, AtomicLong value) throws IOException {
longAdapter.write(out, value.get());
}
/*Possible defect in Gson code as read(in) #3 may return null*/
@SuppressWarnings("dereference.of.nullable")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method is private. Still, can you verify that it is not possible to throw a NullPointerException internally?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No NullPointerException is thrown internally but as the method is private developers ensure the concerned read function does not return null so the code is safe

@@ -192,11 +193,13 @@ public Gson() {
Collections.<TypeAdapterFactory>emptyList());
}

/*dangerous to call an instance method inside a constructor, framework could identify #1 and #2 out of 4 such errors*/
@SuppressWarnings("method.invocation.invalid")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The errors you suppressed are InitializationChecker errors. You can use this when doing nullness case studies. Can you make sure adding such annotations still produce method.invocation.invalid errors?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Maxi17 I could not completely understand this comment. Adding which annotations still produce this error?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am saying that the errors you are suppressing are because of InitializationChecker. What I'm asking is if you add InitializationChecker annotations (link @Initialized) works here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Annotation needs to be added to the current object or this which is not possible, therefore the suppression

gson/src/main/java/com/google/gson/Gson.java Outdated Show resolved Hide resolved
gson/src/main/java/com/google/gson/stream/JsonReader.java Outdated Show resolved Hide resolved
@@ -192,11 +193,13 @@ public Gson() {
Collections.<TypeAdapterFactory>emptyList());
}

/*dangerous to call an instance method inside a constructor, framework could identify #1 and #2 out of 4 such errors*/
@SuppressWarnings("method.invocation.invalid")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am saying that the errors you are suppressing are because of InitializationChecker. What I'm asking is if you add InitializationChecker annotations (link @Initialized) works here.

@PRITI1999
Copy link
Author

@Maxi17 nullness annotations are added according to week 2 of plan.

Copy link
Collaborator

@Maxi17 Maxi17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job so far. I added some comments. Please address them.

try {
final Constructor<? super T> constructor = rawType.getDeclaredConstructor();
if (!constructor.isAccessible()) {
accessor.makeAccessible(constructor);
}
return new ObjectConstructor<T>() {
@SuppressWarnings("unchecked") // T is the same raw type as is requested
/*Probable missing annotation in java.lang.reflect.Constructor.java
#1 sends null to a variable length argument*/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After you add the annotation in the jdk, make sure you re-run the case study and fix all @SuppressWarnings caused by missing jdk annotations.

@@ -31,6 +32,9 @@
public abstract class UnsafeAllocator {
public abstract <T> T newInstance(Class<T> c) throws Exception;

@CFComment({"possible missing annotation in jdk for class Field, method get as the doc says it can take null argument #1",
"class Method, function invoke is annotated to receive non-null args but CFComment says it might permit null #2"})
@SuppressWarnings({"nullness:argument.type.incompatible","unboxing.of.nullable"})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like more annotations need to be added in the jdk. Remove the comment after you do so.



Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert changes like this.

@@ -157,7 +158,9 @@ public Adapter(Gson context, Type keyType, TypeAdapter<K> keyTypeAdapter,
this.constructor = constructor;
}

@Override public Map<K, V> read(JsonReader in) throws IOException {
//INSTANCE in #3 may be null as JsonReaderInternalAccess do not initialize it
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a bug in Gson. Can you produce a test case in which INSTANCE is null and the program crashes?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method is defined inside a private class and is never called so can this method be ruled out as safe?

@@ -65,18 +69,20 @@ boolean makeAccessibleWithUnsafe(AccessibleObject ao) {
return false;
}

private static Object getUnsafeInstance() {
//null should not be sent to get method #1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If null should not be sent to this smethod, then why is the code safe?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants