Skip to content

Commit 1f4b894

Browse files
authored
fix: Fixes unaligned BitReader reads when reading >= 8 bits. (#1240)
* fix: Fixes unaligned BitReader reads when reading >= 8 bits. Also adds tests to exercise that case. * Why didn't standards.py --fix fix this the first time I ran it?
1 parent 1347808 commit 1f4b894

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

com.unity.netcode.gameobjects/Runtime/Serialization/BitReader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ private unsafe void ReadMisaligned(out byte value)
212212
int pos = m_BitPosition >> 3;
213213
int shift1 = 8 - off;
214214

215-
value = (byte)((m_BufferPointer[pos] >> shift1) | (m_BufferPointer[(m_BitPosition += 8) >> 3] << shift1));
215+
value = (byte)((m_BufferPointer[pos] >> off) | (m_BufferPointer[(m_BitPosition += 8) >> 3] << shift1));
216216
}
217217
}
218218
}

com.unity.netcode.gameobjects/Tests/Editor/Serialization/BitReaderTests.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,34 @@ public unsafe void TestReadingMultipleBytesToLongs([Range(1U, 64U)] uint numBits
288288
}
289289
}
290290

291+
[Test]
292+
public unsafe void TestReadingMultipleBytesToLongsMisaligned([Range(1U, 63U)] uint numBits)
293+
{
294+
ulong value = 0b01010101_10101010_01010101_10101010_01010101_10101010_01010101_10101010;
295+
var reader = new FastBufferReader((byte*)&value, Allocator.Temp, sizeof(ulong));
296+
using (reader)
297+
{
298+
ulong* asUlong = (ulong*)reader.GetUnsafePtr();
299+
300+
Assert.AreEqual(value, *asUlong);
301+
var mask = 0UL;
302+
for (var i = 0; i < numBits; ++i)
303+
{
304+
mask |= (1UL << i);
305+
}
306+
307+
ulong readValue;
308+
309+
Assert.IsTrue(reader.TryBeginRead(sizeof(ulong)));
310+
using (var bitReader = reader.EnterBitwiseContext())
311+
{
312+
bitReader.ReadBit(out bool unused);
313+
bitReader.ReadBits(out readValue, numBits);
314+
}
315+
Assert.AreEqual((value >> 1) & mask, readValue);
316+
}
317+
}
318+
291319
[Test]
292320
public unsafe void TestReadingBitsThrowsIfTryBeginReadNotCalled()
293321
{

com.unity.netcode.gameobjects/Tests/Editor/Serialization/BitWriterTests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,33 @@ public unsafe void TestWritingMultipleBytesFromLongs([Range(1U, 64U)] uint numBi
243243
}
244244
}
245245

246+
[Test]
247+
public unsafe void TestWritingMultipleBytesFromLongsMisaligned([Range(1U, 63U)] uint numBits)
248+
{
249+
var writer = new FastBufferWriter(sizeof(ulong), Allocator.Temp);
250+
using (writer)
251+
{
252+
ulong* asUlong = (ulong*)writer.GetUnsafePtr();
253+
254+
Assert.AreEqual(0, *asUlong);
255+
var mask = 0UL;
256+
for (var i = 0; i < numBits; ++i)
257+
{
258+
mask |= (1UL << i);
259+
}
260+
261+
ulong value = 0xFFFFFFFFFFFFFFFF;
262+
263+
Assert.IsTrue(writer.TryBeginWrite(sizeof(ulong)));
264+
using (var bitWriter = writer.EnterBitwiseContext())
265+
{
266+
bitWriter.WriteBit(false);
267+
bitWriter.WriteBits(value, numBits);
268+
}
269+
Assert.AreEqual(value & mask, *asUlong >> 1);
270+
}
271+
}
272+
246273
[Test]
247274
public unsafe void TestWritingBitsThrowsIfTryBeginWriteNotCalled()
248275
{

0 commit comments

Comments
 (0)