Skip to content

Commit 9180338

Browse files
committed
CSHARP-5614: Fix deserialization of primitive arrays on Big Endian systems
Signed-off-by: Medha Tiwari <[email protected]>
1 parent 89a8e71 commit 9180338

File tree

1 file changed

+22
-22
lines changed

1 file changed

+22
-22
lines changed

src/MongoDB.Bson/Serialization/Serializers/PrimitivesArrayReader.cs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,20 @@ private static T[] ReadBsonArray<T>(
7474
using var buffer = ThreadStaticBuffer.RentBuffer(array.Length);
7575

7676
var bytes = buffer.Bytes;
77-
array.GetBytes(0, bytes, 0, array.Length);
77+
array.GetBytes(0, bytes, 0, array.Length);
78+
var span = bytes.AsSpan();
7879

7980
var result = new List<T>();
80-
81-
81+
8282
var index = 4; // 4 first bytes are array object size in bytes
8383
var maxIndex = array.Length - 1;
8484

8585
while (index < maxIndex)
8686
{
87-
ValidateBsonType(bsonDataType);
87+
ValidateBsonType(bsonDataType, span);
8888

8989
// Skip name
90-
while (bytes[index] != 0) { index++; }
90+
while (span[index] != 0) { index++; }
9191
index++; // Skip string terminating 0
9292

9393
T value = default;
@@ -97,81 +97,81 @@ private static T[] ReadBsonArray<T>(
9797
{
9898
case ConversionType.DoubleToSingle:
9999
{
100-
var v = (float)BitConverter.Int64BitsToDouble(BinaryPrimitives.ReadInt64LittleEndian(bytes.AsSpan(index)));
100+
var v = (float)BinaryPrimitivesCompat.ReadDoubleLittleEndian(span.Slice(index));
101101
value = Unsafe.As<float, T>(ref v);
102102
break;
103103
}
104104
case ConversionType.DoubleToDouble:
105105
{
106-
var v = BitConverter.Int64BitsToDouble(BinaryPrimitives.ReadInt64LittleEndian(bytes.AsSpan(index)));
106+
var v = BitConverter.Int64BitsToDouble(BinaryPrimitives.ReadInt64LittleEndian(span.Slice(index)));
107107
value = Unsafe.As<double, T>(ref v);
108108
break;
109109
}
110110
case ConversionType.Decimal128ToDecimal128:
111111
{
112-
var lowBits = BinaryPrimitives.ReadUInt64LittleEndian(bytes.AsSpan(index));
113-
var highBits = BinaryPrimitives.ReadUInt64LittleEndian(bytes.AsSpan(index + 8));
112+
var lowBits = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(index));
113+
var highBits = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(index + 8));
114114
var v = Decimal128.ToDecimal(Decimal128.FromIEEEBits(highBits, lowBits));
115115
value = Unsafe.As<decimal, T>(ref v);
116116
break;
117117
}
118118
case ConversionType.BoolToBool:
119119
{
120-
var v = bytes[index] != 0;
120+
var v = span[index] != 0;
121121
value = Unsafe.As<bool, T>(ref v);
122122
break;
123123
}
124124
case ConversionType.Int32ToInt8:
125125
{
126-
var v = (sbyte)BinaryPrimitives.ReadInt32LittleEndian(bytes.AsSpan(index));
126+
var v = (sbyte)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index));
127127
value = Unsafe.As<sbyte, T>(ref v);
128128
break;
129129
}
130130
case ConversionType.Int32ToUInt8:
131131
{
132-
var v = (byte)BinaryPrimitives.ReadInt32LittleEndian(bytes.AsSpan(index));
132+
var v = (byte)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index));
133133
value = Unsafe.As<byte, T>(ref v);
134134
break;
135135
}
136136
case ConversionType.Int32ToInt16:
137137
{
138-
var v = (short)BinaryPrimitives.ReadInt32LittleEndian(bytes.AsSpan(index));
138+
var v = (short)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index));
139139
value = Unsafe.As<short, T>(ref v);
140140
break;
141141
}
142142
case ConversionType.Int32ToUInt16:
143143
{
144-
var v = (ushort)BinaryPrimitives.ReadInt32LittleEndian(bytes.AsSpan(index));
144+
var v = (ushort)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index));
145145
value = Unsafe.As<ushort, T>(ref v);
146146
break;
147147
}
148148
case ConversionType.Int32ToChar:
149149
{
150-
var v = (char)(ushort)BinaryPrimitives.ReadInt32LittleEndian(bytes.AsSpan(index));
150+
var v = (char)(ushort)BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index));
151151
value = Unsafe.As<char, T>(ref v);
152152
break;
153153
}
154154
case ConversionType.Int32ToInt32:
155155
{
156-
var v = BinaryPrimitives.ReadInt32LittleEndian(bytes.AsSpan(index));
156+
var v = BinaryPrimitives.ReadInt32LittleEndian(span.Slice(index));
157157
value = Unsafe.As<int, T>(ref v);
158158
break;
159159
}
160160
case ConversionType.Int32ToUInt32:
161161
{
162-
var v = BinaryPrimitives.ReadUInt32LittleEndian(bytes.AsSpan(index));
162+
var v = BinaryPrimitives.ReadUInt32LittleEndian(span.Slice(index));
163163
value = Unsafe.As<uint, T>(ref v);
164164
break;
165165
}
166166
case ConversionType.Int64ToInt64:
167167
{
168-
var v = BinaryPrimitives.ReadInt64LittleEndian(bytes.AsSpan(index));
168+
var v = BinaryPrimitives.ReadInt64LittleEndian(span.Slice(index));
169169
value = Unsafe.As<long, T>(ref v);
170170
break;
171171
}
172172
case ConversionType.Int64ToUInt64:
173173
{
174-
var v = BinaryPrimitives.ReadUInt64LittleEndian(bytes.AsSpan(index));
174+
var v = BinaryPrimitives.ReadUInt64LittleEndian(span.Slice(index));
175175
value = Unsafe.As<ulong, T>(ref v);
176176
break;
177177
}
@@ -183,12 +183,12 @@ private static T[] ReadBsonArray<T>(
183183
index += bsonDataSize;
184184
}
185185

186-
ValidateBsonType(BsonType.EndOfDocument);
186+
ValidateBsonType(BsonType.EndOfDocument, span);
187187
return result.ToArray();
188188

189-
void ValidateBsonType(BsonType bsonType)
189+
void ValidateBsonType(BsonType bsonType, Span<byte> span)
190190
{
191-
if ((BsonType)bytes[index] != bsonType)
191+
if ((BsonType)span[index] != bsonType)
192192
{
193193
throw new InvalidOperationException();
194194
}

0 commit comments

Comments
 (0)