Skip to content

Commit 7069650

Browse files
committed
add a failing test that was super hard to extract from the repro
1 parent 2b52fb2 commit 7069650

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

src/libraries/System.Formats.Nrbf/tests/EdgeCaseTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,48 @@ public void CanReadAllKindsOfDateTimes_DateTimeIsMemberOfTheRootRecord(DateTime
144144
Assert.Equal(input.Ticks, classRecord.GetDateTime(nameof(ClassWithDateTime.Value)).Ticks);
145145
Assert.Equal(input.Kind, classRecord.GetDateTime(nameof(ClassWithDateTime.Value)).Kind);
146146
}
147+
148+
[Fact]
149+
public void CanReadUserClassStoredAsSystemClass()
150+
{
151+
// For the following data, BinaryFormatter serializes the ClassWithNullableStructField class
152+
// as a record with a single field called "NullableField" with BinaryType.SystemClass (!!!)
153+
// and TypeName being System.Nullable`1[[SampleStruct, $AssemblyName]].
154+
// It most likely does so, because it's System.Nullable<$NonSystemStruct>.
155+
// But later it serializes the SampleStruct as a ClassWithMembersAndTypes record,
156+
// not SystemClassWithMembersAndTypes.
157+
// It does so, only when the payload contains at least one class with the nullable field being null.
158+
159+
using MemoryStream stream = Serialize(
160+
new ClassWithNullableStructField[]
161+
{
162+
new ClassWithNullableStructField() { NullableField = null }, // having a null here is crucial for the test
163+
new ClassWithNullableStructField() { NullableField = new ClassWithNullableStructField.SampleStruct() { Value = 42 } }
164+
}
165+
);
166+
167+
SZArrayRecord<SerializationRecord> arrayRecord = (SZArrayRecord<SerializationRecord>)NrbfDecoder.Decode(stream);
168+
SerializationRecord[] records = arrayRecord.GetArray();
169+
Assert.Equal(2, arrayRecord.Length);
170+
Assert.All(records, record => Assert.True(record.TypeNameMatches(typeof(ClassWithNullableStructField))));
171+
Assert.Null(((ClassRecord)records[0]).GetClassRecord(nameof(ClassWithNullableStructField.NullableField)));
172+
173+
ClassRecord? notNullRecord = ((ClassRecord)records[1]).GetClassRecord(nameof(ClassWithNullableStructField.NullableField));
174+
Assert.NotNull(notNullRecord);
175+
Assert.Equal(42, notNullRecord.GetInt32(nameof(ClassWithNullableStructField.SampleStruct.Value)));
176+
}
177+
178+
[Serializable]
179+
public class ClassWithNullableStructField
180+
{
181+
#pragma warning disable IDE0001 // Simplify names
182+
public System.Nullable<SampleStruct> NullableField;
183+
#pragma warning restore IDE0001
184+
185+
[Serializable]
186+
public struct SampleStruct
187+
{
188+
public int Value;
189+
}
190+
}
147191
}

0 commit comments

Comments
 (0)