diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArrayInfo.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArrayInfo.cs
index e8b28825888e4..4b24b1912e89a 100644
--- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArrayInfo.cs
+++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArrayInfo.cs
@@ -13,7 +13,7 @@ namespace System.Formats.Nrbf;
///
/// ArrayInfo structures are described in [MS-NRBF] 2.4.2.1.
///
-[DebuggerDisplay("Length={Length}, {ArrayType}, rank={Rank}")]
+[DebuggerDisplay("{ArrayType}, rank={Rank}")]
internal readonly struct ArrayInfo
{
internal const int MaxArrayLength = 2147483591; // Array.MaxLength
diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySinglePrimitiveRecord.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySinglePrimitiveRecord.cs
index 5b3b974639468..46693c344bc84 100644
--- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySinglePrimitiveRecord.cs
+++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySinglePrimitiveRecord.cs
@@ -41,17 +41,9 @@ internal ArraySinglePrimitiveRecord(ArrayInfo arrayInfo, IReadOnlyList values
public override T[] GetArray(bool allowNulls = true)
=> (T[])(_arrayNullsNotAllowed ??= (Values is T[] array ? array : Values.ToArray()));
- internal override (AllowedRecordTypes allowed, PrimitiveType primitiveType) GetAllowedRecordType()
- {
- Debug.Fail("GetAllowedRecordType should never be called on ArraySinglePrimitiveRecord");
- throw new InvalidOperationException();
- }
+ internal override (AllowedRecordTypes allowed, PrimitiveType primitiveType) GetAllowedRecordType() => throw new InvalidOperationException();
- private protected override void AddValue(object value)
- {
- Debug.Fail("AddValue should never be called on ArraySinglePrimitiveRecord");
- throw new InvalidOperationException();
- }
+ private protected override void AddValue(object value) => throw new InvalidOperationException();
internal static IReadOnlyList DecodePrimitiveTypes(BinaryReader reader, int count)
{
@@ -94,7 +86,7 @@ internal static IReadOnlyList DecodePrimitiveTypes(BinaryReader reader, int c
#if NET
reader.BaseStream.ReadExactly(resultAsBytes);
#else
- byte[] bytes = ArrayPool.Shared.Rent(Math.Min(count * Unsafe.SizeOf(), 256_000));
+ byte[] bytes = ArrayPool.Shared.Rent((int)Math.Min(requiredBytes, 256_000));
while (!resultAsBytes.IsEmpty)
{
@@ -159,31 +151,10 @@ internal static IReadOnlyList DecodePrimitiveTypes(BinaryReader reader, int c
private static List DecodeDecimals(BinaryReader reader, int count)
{
List values = new();
-#if NET
- Span buffer = stackalloc byte[256];
- for (int i = 0; i < count; i++)
- {
- int stringLength = reader.Read7BitEncodedInt();
- if (!(stringLength > 0 && stringLength <= buffer.Length))
- {
- ThrowHelper.ThrowInvalidValue(stringLength);
- }
-
- reader.BaseStream.ReadExactly(buffer.Slice(0, stringLength));
-
- if (!decimal.TryParse(buffer.Slice(0, stringLength), NumberStyles.Number, CultureInfo.InvariantCulture, out decimal value))
- {
- ThrowHelper.ThrowInvalidFormat();
- }
-
- values.Add(value);
- }
-#else
for (int i = 0; i < count; i++)
{
values.Add(reader.ParseDecimal());
}
-#endif
return values;
}
@@ -244,12 +215,14 @@ private static List DecodeFromNonSeekableStream(BinaryReader reader, int coun
{
values.Add((T)(object)Utils.BinaryReaderExtensions.CreateDateTimeFromData(reader.ReadUInt64()));
}
- else
+ else if (typeof(T) == typeof(TimeSpan))
{
- Debug.Assert(typeof(T) == typeof(TimeSpan));
-
values.Add((T)(object)new TimeSpan(reader.ReadInt64()));
}
+ else
+ {
+ throw new InvalidOperationException();
+ }
}
return values;
diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySingleStringRecord.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySingleStringRecord.cs
index de248bcef7675..7fed2a494b9b0 100644
--- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySingleStringRecord.cs
+++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySingleStringRecord.cs
@@ -21,7 +21,7 @@ internal sealed class ArraySingleStringRecord : SZArrayRecord
public override SerializationRecordType RecordType => SerializationRecordType.ArraySingleString;
///
- public override TypeName TypeName => TypeNameHelpers.GetPrimitiveSZArrayTypeName(PrimitiveType.String);
+ public override TypeName TypeName => TypeNameHelpers.GetPrimitiveSZArrayTypeName(TypeNameHelpers.StringPrimitiveType);
private List Records { get; }
diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/BinaryArrayRecord.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/BinaryArrayRecord.cs
index 0c7e04e840a48..5aa4878016d9f 100644
--- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/BinaryArrayRecord.cs
+++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/BinaryArrayRecord.cs
@@ -138,7 +138,7 @@ internal static ArrayRecord Decode(BinaryReader reader, RecordMap recordMap, Pay
lengths[i] = ArrayInfo.ParseValidArrayLength(reader);
totalElementCount *= lengths[i];
- if (totalElementCount > uint.MaxValue)
+ if (totalElementCount > ArrayInfo.MaxArrayLength)
{
ThrowHelper.ThrowInvalidValue(lengths[i]); // max array size exceeded
}
diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/BinaryLibraryRecord.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/BinaryLibraryRecord.cs
index ccd39922e23fb..7318052610e1b 100644
--- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/BinaryLibraryRecord.cs
+++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/BinaryLibraryRecord.cs
@@ -30,14 +30,7 @@ private BinaryLibraryRecord(SerializationRecordId libraryId, AssemblyNameInfo li
public override SerializationRecordType RecordType => SerializationRecordType.BinaryLibrary;
- public override TypeName TypeName
- {
- get
- {
- Debug.Fail("TypeName should never be called on BinaryLibraryRecord");
- return TypeName.Parse(nameof(BinaryLibraryRecord).AsSpan());
- }
- }
+ public override TypeName TypeName => TypeName.Parse(nameof(BinaryLibraryRecord).AsSpan());
internal string? RawLibraryName { get; }
diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/MemberTypeInfo.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/MemberTypeInfo.cs
index 9843a0b71f04c..2e4b7e1399be2 100644
--- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/MemberTypeInfo.cs
+++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/MemberTypeInfo.cs
@@ -53,10 +53,14 @@ internal static MemberTypeInfo Decode(BinaryReader reader, int count, PayloadOpt
case BinaryType.Class:
info[i] = (type, ClassTypeInfo.Decode(reader, options, recordMap));
break;
- default:
- // Other types have no additional data.
- Debug.Assert(type is BinaryType.String or BinaryType.ObjectArray or BinaryType.StringArray or BinaryType.Object);
+ case BinaryType.String:
+ case BinaryType.StringArray:
+ case BinaryType.Object:
+ case BinaryType.ObjectArray:
+ // These types have no additional data.
break;
+ default:
+ throw new InvalidOperationException();
}
}
@@ -97,7 +101,8 @@ internal static MemberTypeInfo Decode(BinaryReader reader, int count, PayloadOpt
BinaryType.PrimitiveArray => (PrimitiveArray, default),
BinaryType.Class => (NonSystemClass, default),
BinaryType.SystemClass => (SystemClass, default),
- _ => (ObjectArray, default)
+ BinaryType.ObjectArray => (ObjectArray, default),
+ _ => throw new InvalidOperationException()
};
}
@@ -144,15 +149,15 @@ internal TypeName GetArrayTypeName(ArrayInfo arrayInfo)
TypeName elementTypeName = binaryType switch
{
- BinaryType.String => TypeNameHelpers.GetPrimitiveTypeName(PrimitiveType.String),
- BinaryType.StringArray => TypeNameHelpers.GetPrimitiveSZArrayTypeName(PrimitiveType.String),
+ BinaryType.String => TypeNameHelpers.GetPrimitiveTypeName(TypeNameHelpers.StringPrimitiveType),
+ BinaryType.StringArray => TypeNameHelpers.GetPrimitiveSZArrayTypeName(TypeNameHelpers.StringPrimitiveType),
BinaryType.Primitive => TypeNameHelpers.GetPrimitiveTypeName((PrimitiveType)additionalInfo!),
BinaryType.PrimitiveArray => TypeNameHelpers.GetPrimitiveSZArrayTypeName((PrimitiveType)additionalInfo!),
BinaryType.Object => TypeNameHelpers.GetPrimitiveTypeName(TypeNameHelpers.ObjectPrimitiveType),
BinaryType.ObjectArray => TypeNameHelpers.GetPrimitiveSZArrayTypeName(TypeNameHelpers.ObjectPrimitiveType),
BinaryType.SystemClass => (TypeName)additionalInfo!,
BinaryType.Class => ((ClassTypeInfo)additionalInfo!).TypeName,
- _ => throw new ArgumentOutOfRangeException(paramName: nameof(binaryType), actualValue: binaryType, message: null)
+ _ => throw new InvalidOperationException()
};
// In general, arrayRank == 1 may have two different meanings:
diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/MessageEndRecord.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/MessageEndRecord.cs
index 7cb28224a890e..62c7d57b3fa37 100644
--- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/MessageEndRecord.cs
+++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/MessageEndRecord.cs
@@ -24,12 +24,5 @@ private MessageEndRecord()
public override SerializationRecordId Id => SerializationRecordId.NoId;
- public override TypeName TypeName
- {
- get
- {
- Debug.Fail("TypeName should never be called on MessageEndRecord");
- return TypeName.Parse(nameof(MessageEndRecord).AsSpan());
- }
- }
+ public override TypeName TypeName => TypeName.Parse(nameof(MessageEndRecord).AsSpan());
}
diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/NrbfDecoder.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/NrbfDecoder.cs
index de4b24b6e46e1..fc03409bd2eec 100644
--- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/NrbfDecoder.cs
+++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/NrbfDecoder.cs
@@ -69,28 +69,22 @@ public static bool StartsWithPayloadHeader(Stream stream)
return false;
}
- try
+ byte[] buffer = new byte[SerializedStreamHeaderRecord.Size];
+ int offset = 0;
+ while (offset < buffer.Length)
{
-#if NET
- Span buffer = stackalloc byte[SerializedStreamHeaderRecord.Size];
- stream.ReadExactly(buffer);
-#else
- byte[] buffer = new byte[SerializedStreamHeaderRecord.Size];
- int offset = 0;
- while (offset < buffer.Length)
+ int read = stream.Read(buffer, offset, buffer.Length - offset);
+ if (read == 0)
{
- int read = stream.Read(buffer, offset, buffer.Length - offset);
- if (read == 0)
- throw new EndOfStreamException();
- offset += read;
+ stream.Position = beginning;
+ return false;
}
-#endif
- return StartsWithPayloadHeader(buffer);
- }
- finally
- {
- stream.Position = beginning;
+ offset += read;
}
+
+ bool result = StartsWithPayloadHeader(buffer);
+ stream.Position = beginning;
+ return result;
}
///
@@ -241,7 +235,8 @@ private static SerializationRecord DecodeNext(BinaryReader reader, RecordMap rec
SerializationRecordType.ObjectNullMultiple => ObjectNullMultipleRecord.Decode(reader),
SerializationRecordType.ObjectNullMultiple256 => ObjectNullMultiple256Record.Decode(reader),
SerializationRecordType.SerializedStreamHeader => SerializedStreamHeaderRecord.Decode(reader),
- _ => SystemClassWithMembersAndTypesRecord.Decode(reader, recordMap, options),
+ SerializationRecordType.SystemClassWithMembersAndTypes => SystemClassWithMembersAndTypesRecord.Decode(reader, recordMap, options),
+ _ => throw new InvalidOperationException()
};
recordMap.Add(record);
@@ -269,8 +264,8 @@ private static SerializationRecord DecodeMemberPrimitiveTypedRecord(BinaryReader
PrimitiveType.Double => new MemberPrimitiveTypedRecord(reader.ReadDouble()),
PrimitiveType.Decimal => new MemberPrimitiveTypedRecord(reader.ParseDecimal()),
PrimitiveType.DateTime => new MemberPrimitiveTypedRecord(Utils.BinaryReaderExtensions.CreateDateTimeFromData(reader.ReadUInt64())),
- // String is handled with a record, never on it's own
- _ => new MemberPrimitiveTypedRecord(new TimeSpan(reader.ReadInt64())),
+ PrimitiveType.TimeSpan => new MemberPrimitiveTypedRecord(new TimeSpan(reader.ReadInt64())),
+ _ => throw new InvalidOperationException()
};
}
@@ -295,7 +290,8 @@ private static SerializationRecord DecodeArraySinglePrimitiveRecord(BinaryReader
PrimitiveType.Double => Decode(info, reader),
PrimitiveType.Decimal => Decode(info, reader),
PrimitiveType.DateTime => Decode(info, reader),
- _ => Decode(info, reader),
+ PrimitiveType.TimeSpan => Decode(info, reader),
+ _ => throw new InvalidOperationException()
};
static SerializationRecord Decode(ArrayInfo info, BinaryReader reader) where T : unmanaged
diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/NullsRecord.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/NullsRecord.cs
index d3d859c193a9c..9c11db4307ced 100644
--- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/NullsRecord.cs
+++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/NullsRecord.cs
@@ -12,12 +12,5 @@ internal abstract class NullsRecord : SerializationRecord
public override SerializationRecordId Id => SerializationRecordId.NoId;
- public override TypeName TypeName
- {
- get
- {
- Debug.Fail($"TypeName should never be called on {GetType().Name}");
- return TypeName.Parse(GetType().Name.AsSpan());
- }
- }
+ public override TypeName TypeName => TypeName.Parse(GetType().Name.AsSpan());
}
diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/PrimitiveType.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/PrimitiveType.cs
index 9ddb9179518fa..f2e696e6a90e9 100644
--- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/PrimitiveType.cs
+++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/PrimitiveType.cs
@@ -11,10 +11,6 @@ namespace System.Formats.Nrbf;
///
internal enum PrimitiveType : byte
{
- ///
- /// Used internally to express no value
- ///
- None = 0,
Boolean = 1,
Byte = 2,
Char = 3,
@@ -30,7 +26,19 @@ internal enum PrimitiveType : byte
DateTime = 13,
UInt16 = 14,
UInt32 = 15,
- UInt64 = 16,
- Null = 17,
- String = 18
+ UInt64 = 16
+ // This internal enum no longer contains Null and String as they were always illegal:
+ // - In case of BinaryArray (NRBF 2.4.3.1):
+ // "If the BinaryTypeEnum value is Primitive, the PrimitiveTypeEnumeration
+ // value in AdditionalTypeInfo MUST NOT be Null (17) or String (18)."
+ // - In case of MemberPrimitiveTyped (NRBF 2.5.1):
+ // "PrimitiveTypeEnum (1 byte): A PrimitiveTypeEnumeration
+ // value that specifies the Primitive Type of data that is being transmitted.
+ // This field MUST NOT contain a value of 17 (Null) or 18 (String)."
+ // - In case of ArraySinglePrimitive (NRBF 2.4.3.3):
+ // "A PrimitiveTypeEnumeration value that identifies the Primitive Type
+ // of the items of the Array. The value MUST NOT be 17 (Null) or 18 (String)."
+ // - In case of MemberTypeInfo (NRBF 2.3.1.2):
+ // "When the BinaryTypeEnum value is Primitive, the PrimitiveTypeEnumeration
+ // value in AdditionalInfo MUST NOT be Null (17) or String (18)."
}
diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/RecordMap.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/RecordMap.cs
index 04a4d0e085048..eafcbf93249c5 100644
--- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/RecordMap.cs
+++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/RecordMap.cs
@@ -56,7 +56,7 @@ internal void Add(SerializationRecord record)
return;
}
#endif
- throw new SerializationException(SR.Format(SR.Serialization_DuplicateSerializationRecordId, record.Id));
+ throw new SerializationException(SR.Format(SR.Serialization_DuplicateSerializationRecordId, record.Id._id));
}
}
}
diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/RectangularArrayRecord.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/RectangularArrayRecord.cs
index de3c6d671850a..bc286e56ee5c2 100644
--- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/RectangularArrayRecord.cs
+++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/RectangularArrayRecord.cs
@@ -14,7 +14,7 @@ namespace System.Formats.Nrbf;
internal sealed class RectangularArrayRecord : ArrayRecord
{
private readonly int[] _lengths;
- private readonly ICollection