Skip to content

Commit

Permalink
Fix handling of readonly private fields
Browse files Browse the repository at this point in the history
Disallow writing to readonly private fields even when using a resolver
that allows using private fields.

Fixes: #1218
  • Loading branch information
Alxandr committed Jun 14, 2021
1 parent dd880a6 commit db29bea
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1492,7 +1492,7 @@ public static ObjectSerializationInfo CreateOrNull(Type type, bool forceStringKe
{
FieldInfo = field,
IsReadable = allowPrivate || field.IsPublic,
IsWritable = allowPrivate || (field.IsPublic && !field.IsInitOnly),
IsWritable = (allowPrivate || field.IsPublic) && !field.IsInitOnly,
StringKey = firstMemberByName ? item.Name : $"{item.DeclaringType.FullName}.{item.Name}",
};
}
Expand Down Expand Up @@ -1675,7 +1675,7 @@ public static ObjectSerializationInfo CreateOrNull(Type type, bool forceStringKe
{
FieldInfo = item,
IsReadable = allowPrivate || item.IsPublic,
IsWritable = allowPrivate || (item.IsPublic && !item.IsInitOnly),
IsWritable = (allowPrivate || item.IsPublic) && !item.IsInitOnly,
};
if (!member.IsReadable && !member.IsWritable)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,28 @@ internal class InternalClass
internal InternalEnum EnumProperty { get; set; }
}

[MessagePackObject]
public class PrivateReadonlyField
{
public static PrivateReadonlyField WithNullValue { get; } = new PrivateReadonlyField();

[Key(0)]
private readonly string field;

[SerializationConstructor]
public PrivateReadonlyField(string field)
{
this.field = field ?? "not null";
}

private PrivateReadonlyField()
{
}

[IgnoreMember]
public string Field => field;
}

#if !ENABLE_IL2CPP

[MessagePackObject]
Expand Down Expand Up @@ -310,6 +332,15 @@ public void InternalClassWithInternalEnum()
Assert.Equal(expected.EnumProperty, actual.EnumProperty);
}

[Fact]
public void PrivateReadonlyFieldSetInConstructor()
{
PrivateReadonlyField initial = PrivateReadonlyField.WithNullValue;
var bin = MessagePackSerializer.Serialize(initial, StandardResolverAllowPrivate.Options);
var deserialized = MessagePackSerializer.Deserialize<PrivateReadonlyField>(bin, StandardResolverAllowPrivate.Options);
Assert.Equal("not null", deserialized.Field);
}

#if !ENABLE_IL2CPP

[Fact]
Expand Down

0 comments on commit db29bea

Please sign in to comment.