Skip to content

Commit

Permalink
[corlib] version tolerant serialization fails with missing primitive …
Browse files Browse the repository at this point in the history
…members

Modifies ObjectReader so that when it encounters a primitive typed member in
an object stream which has no corresponding member in the app domain, it will
read the value anyway and throw it away. That way it can read the next block
from the stream.

Added a unit test which passes with the changes to ObjectReader.

Fixes bug #641821.
  • Loading branch information
ambroff committed Sep 24, 2010
1 parent f485bd7 commit 168f1ac
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 4 deletions.
2 changes: 2 additions & 0 deletions mcs/class/corlib/Makefile
Expand Up @@ -90,6 +90,8 @@ test-vts:
$(vtsdir)/$(vts)TestLib/4.0/Address.cs
$(MCS) -target:library \
$(vtsdir)/$(vts)TestLib/5.0/Address.cs
$(MCS) -target:library \
$(vtsdir)/$(vts)TestLib/6.0/Address.cs
run-test-vts: test-vts
$(TEST_RUNTIME) $(RUNTIME_FLAGS) $(TEST_HARNESS) -noshadow \
$(vtsdir)/BinarySerializationOverVersions.exe
Expand Down
Expand Up @@ -294,13 +294,22 @@ private void ReadObjectContent (BinaryReader reader, TypeMetadata metadata, long

info = metadata.NeedsSerializationInfo ? new SerializationInfo(metadata.Type, new FormatterConverter()) : null;

if (metadata.MemberNames != null)
if (metadata.MemberNames != null) {
for (int n=0; n<metadata.FieldCount; n++)
ReadValue (reader, objectInstance, objectId, info, metadata.MemberTypes[n], metadata.MemberNames[n], null, null);
else
for (int n=0; n<metadata.FieldCount; n++)
} else
for (int n=0; n<metadata.FieldCount; n++) {
if (metadata.MemberInfos [n] != null)
ReadValue (reader, objectInstance, objectId, info, metadata.MemberTypes[n], metadata.MemberInfos[n].Name, metadata.MemberInfos[n], null);
ReadValue (reader, objectInstance, objectId, info, metadata.MemberTypes[n], metadata.MemberInfos[n].Name, metadata.MemberInfos[n], null);
else if (BinaryCommon.IsPrimitive(metadata.MemberTypes[n])) {
// Since the member info is null, the type in this
// domain does not have this type. Even though we
// are not going to store the value, we will read
// it from the stream so that we can advance to the
// next block.
ReadPrimitiveTypeValue (reader, metadata.MemberTypes[n]);
}
}
}

private void RegisterObject (long objectId, object objectInstance, SerializationInfo info, long parentObjectId, MemberInfo parentObjectMemeber, int[] indices)
Expand Down
Expand Up @@ -124,6 +124,18 @@ static void Main (string [] args)
Deserialize ("4.0", Serialize ("5.0"));
}

[Test]
public void TestDroppedPrimitiveTypeField() //eliminate Id (int)
{
Deserialize ("5.0", Serialize ("6.0"));
}

[Test]
public void TestAddedPrimitiveTypeField () //add Id (int)
{
Deserialize ("6.0", Serialize ("5.0"));
}

private static string Serialize (string assemblyVersion)
{
return SerializeOOP (SetEnvironment (assemblyVersion)); ;
Expand Down
@@ -0,0 +1,22 @@
using System;
using System.Runtime.Serialization;

namespace VersionTolerantSerializationTestLib
{
[Serializable]
public class Address
{
private string Street;
private string City;
private string CountryCode;

[OptionalField (VersionAdded = 4)]
private string PostCode;

[OptionalField (VersionAdded = 5)]
private string AreaCode = "0";

[OptionalField (VersionAdded = 6)]
private int Id = 0;
}
}

0 comments on commit 168f1ac

Please sign in to comment.