Skip to content

Commit

Permalink
[NRBF] throw SerializationException when a surrogate character is read (
Browse files Browse the repository at this point in the history
dotnet#107532)

 (so far an ArgumentException was thrown)
  • Loading branch information
adamsitnik committed Sep 13, 2024
1 parent 90035a0 commit 02e8bb0
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ internal static IReadOnlyList<T> DecodePrimitiveTypes(BinaryReader reader, int c
}
else if (typeof(T) == typeof(char))
{
return (T[])(object)reader.ReadChars(count);
return (T[])(object)reader.ParseChars(count);
}

// It's safe to pre-allocate, as we have ensured there is enough bytes in the stream.
Expand Down Expand Up @@ -206,7 +206,7 @@ private static List<T> DecodeFromNonSeekableStream(BinaryReader reader, int coun
}
else if (typeof(T) == typeof(char))
{
values.Add((T)(object)reader.ReadChar());
values.Add((T)(object)reader.ParseChar());
}
else if (typeof(T) == typeof(short))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ internal static char ParseChar(this BinaryReader reader)
}
}

internal static char[] ParseChars(this BinaryReader reader, int count)
{
try
{
return reader.ReadChars(count);
}
catch (ArgumentException) // A surrogate character was read.
{
throw new SerializationException(SR.Serialization_SurrogateCharacter);
}
}

/// <summary>
/// Creates a <see cref="DateTime"/> object from raw data with validation.
/// </summary>
Expand Down
24 changes: 20 additions & 4 deletions src/libraries/System.Formats.Nrbf/tests/InvalidInputTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -564,8 +564,10 @@ public void InvalidDecimal(string textRepresentation)
Assert.Throws<SerializationException>(() => NrbfDecoder.Decode(stream));
}

[Fact]
public void SurrogateCharacter()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void SurrogateCharacters(bool array)
{
using MemoryStream stream = new();
BinaryWriter writer = new(stream, Encoding.UTF8);
Expand All @@ -576,8 +578,22 @@ public void SurrogateCharacter()
writer.Write("ClassWithCharField"); // type name
writer.Write(1); // member count
writer.Write("memberName");
writer.Write((byte)BinaryType.Primitive);
writer.Write((byte)PrimitiveType.Char);

if (array)
{
writer.Write((byte)BinaryType.PrimitiveArray);
writer.Write((byte)PrimitiveType.Char);
writer.Write((byte)SerializationRecordType.ArraySinglePrimitive);
writer.Write(2); // array record Id
writer.Write(1); // array length
writer.Write((byte)PrimitiveType.Char);
}
else
{
writer.Write((byte)BinaryType.Primitive);
writer.Write((byte)PrimitiveType.Char);
}

writer.Write((byte)0xC0); // a surrogate character
writer.Write((byte)SerializationRecordType.MessageEnd);

Expand Down

0 comments on commit 02e8bb0

Please sign in to comment.