Skip to content

Null fields should be serialized as 0 instead of 1 #141

Description

@lcacheux

In the generated writeToParcel method, null values are serialized as 1, non null as 0 :

if (getValue() == null) {
  dest.writeInt(1);
} else {
  dest.writeInt(0);
  dest.writeString(getValue());
}

This cause issues when this parcelable is exchanged between applications with different versions of the object. For example :

v1 lib have :

@AutoValue
public abstract class MyObject implements Parcelable {
  @Nullable public abstract String getName();
  @Nullable public abstract Integer getValue();
}

At some point we added some new fields to this object to create a v2 version of our lib :

@AutoValue
public abstract class MyObject implements Parcelable {
  @Nullable public abstract String getName();
  @Nullable public abstract Integer getValue();
  @Nullable public abstract String getSurname();
  @Nullable public abstract Integer getNewValue();
}

An application using v1 should still be able to send the object to an application using v2, with null value for the new fields. But with the existing implementation, the generated createFromParcel method will be :

return new AutoValue_MyObject(
  in.readInt() == 0 ? in.readString() : null,
  in.readInt() == 0 ? in.readInt() : null,
  in.readInt() == 0 ? in.readString() : null,
  in.readInt() == 0 ? in.readInt() : null
)

The first two fields are deserialized properly, but since the buffer is empty after this, readInt will always return 0, meaning that the object is not null. The second readString() will return null so the value for the second string is null as expected, but the second Integer value is 0 instead of null (same issue should happen with classes that wrap primitive types).

This behavior would not happen by inverting 0 and 1 for null/non null. Is there a reason why 0 is used for non null instead of null ?

Also changing this behavior now could result in many more backward compatibility breaks for application that used a previous version of auto-value-parcel.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions