mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 19:10:32 +00:00
Fixed NetworkReader tests, everything passes now. Also sneaked in two more tests for 0-length byte arrays because the conventional test didnt apply to them, since they didnt throw when there wasnt any data for them. Also made NetworkReader throw when it can't satisfy a request to read bytes past EOS. (#739)
This commit is contained in:
parent
f64e127378
commit
b995a98743
@ -43,19 +43,24 @@ public string ReadString()
|
|||||||
// note: this will throw an ArgumentException if an invalid utf8
|
// note: this will throw an ArgumentException if an invalid utf8
|
||||||
// string was sent (e.g. in a DOS attack). TransportReceive will
|
// string was sent (e.g. in a DOS attack). TransportReceive will
|
||||||
// handle it.
|
// handle it.
|
||||||
return reader.ReadBoolean() ? reader.ReadString() : null; // null support, see NetworkWriter
|
return ReadBoolean() ? reader.ReadString() : null; // null support, see NetworkWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] ReadBytes(int count) => reader.ReadBytes(count);
|
public byte[] ReadBytes(int count)
|
||||||
|
{
|
||||||
|
byte[] data = reader.ReadBytes(count);
|
||||||
|
if (data.Length != count) throw new EndOfStreamException("Could not fulfill request to read a byte[] of length " + count);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] ReadBytesAndSize()
|
public byte[] ReadBytesAndSize()
|
||||||
{
|
{
|
||||||
// notNull? (see NetworkWriter)
|
// notNull? (see NetworkWriter)
|
||||||
bool notNull = reader.ReadBoolean();
|
bool notNull = ReadBoolean();
|
||||||
if (notNull)
|
if (notNull)
|
||||||
{
|
{
|
||||||
uint size = ReadPackedUInt32();
|
uint size = ReadPackedUInt32();
|
||||||
return reader.ReadBytes((int)size);
|
return ReadBytes((int)size);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -229,7 +234,7 @@ public Matrix4x4 ReadMatrix4x4()
|
|||||||
|
|
||||||
public Guid ReadGuid()
|
public Guid ReadGuid()
|
||||||
{
|
{
|
||||||
byte[] bytes = reader.ReadBytes(16);
|
byte[] bytes = ReadBytes(16);
|
||||||
return new Guid(bytes);
|
return new Guid(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,95 +39,88 @@ public void TestWritingHugeArray()
|
|||||||
Assert.That(deserialized.Length, Is.EqualTo(100000));
|
Assert.That(deserialized.Length, Is.EqualTo(100000));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestReadingLengthWrapAround()
|
||||||
|
{
|
||||||
|
NetworkWriter writer = new NetworkWriter();
|
||||||
|
writer.Write(true);
|
||||||
|
// This is 1.5x int.MaxValue, in the negative range of int.
|
||||||
|
writer.WritePackedUInt32(3221225472);
|
||||||
|
NetworkReader reader = new NetworkReader(writer.ToArray());
|
||||||
|
Assert.Throws<System.ArgumentOutOfRangeException>(() => reader.ReadBytesAndSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestReading0LengthBytesAnsSize()
|
||||||
|
{
|
||||||
|
NetworkWriter writer = new NetworkWriter();
|
||||||
|
writer.WriteBytesAndSize(new byte[]{});
|
||||||
|
NetworkReader reader = new NetworkReader(writer.ToArray());
|
||||||
|
Assert.That(reader.ReadBytesAndSize().Length, Is.EqualTo(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestReading0LengthBytes()
|
||||||
|
{
|
||||||
|
NetworkWriter writer = new NetworkWriter();
|
||||||
|
writer.Write(new byte[]{}, 0, 0);
|
||||||
|
NetworkReader reader = new NetworkReader(writer.ToArray());
|
||||||
|
Assert.That(reader.ReadBytes(0).Length, Is.EqualTo(0));
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestReadingTooMuch()
|
public void TestReadingTooMuch()
|
||||||
{
|
{
|
||||||
|
void EnsureThrows(Action<NetworkReader> read, byte[] data = null)
|
||||||
|
{
|
||||||
|
Assert.Throws<System.IO.EndOfStreamException>(() => read(new NetworkReader(data ?? new byte[]{})));
|
||||||
|
}
|
||||||
// Try reading more than there is data to be read from
|
// Try reading more than there is data to be read from
|
||||||
// The reasoning this should not throw is that when you are running an MMO server
|
// This should throw EndOfStreamException always
|
||||||
// you can't expect all your clients to play nice. They can craft any sort of
|
EnsureThrows(r => r.ReadByte());
|
||||||
// malicious packet, and NetworkReader has to put up with it and take the beating.
|
EnsureThrows(r => r.ReadSByte());
|
||||||
// Currently this test fails with System.IO.EndOfStreamException
|
EnsureThrows(r => r.ReadChar());
|
||||||
// Ideally NetworkReader should Debug.LogWarning and complain about malformed packets
|
EnsureThrows(r => r.ReadBoolean());
|
||||||
// but still continue humming along just fine.
|
EnsureThrows(r => r.ReadInt16());
|
||||||
// MMO Servers cannot afford to be DOS'd and brought to their knees by
|
EnsureThrows(r => r.ReadUInt16());
|
||||||
// one salty player with too much computer knowledge.
|
EnsureThrows(r => r.ReadInt32());
|
||||||
Assert.DoesNotThrow(() => {
|
EnsureThrows(r => r.ReadUInt32());
|
||||||
Action<NetworkReader>[] readFunctions = new Action<NetworkReader>[]{
|
EnsureThrows(r => r.ReadInt64());
|
||||||
r => r.ReadByte(),
|
EnsureThrows(r => r.ReadUInt64());
|
||||||
r => r.ReadSByte(),
|
EnsureThrows(r => r.ReadDecimal());
|
||||||
r => r.ReadChar(),
|
EnsureThrows(r => r.ReadSingle());
|
||||||
r => r.ReadBoolean(),
|
EnsureThrows(r => r.ReadDouble());
|
||||||
r => r.ReadInt16(),
|
EnsureThrows(r => r.ReadString());
|
||||||
r => r.ReadUInt16(),
|
EnsureThrows(r => r.ReadBytes(1));
|
||||||
r => r.ReadInt32(),
|
EnsureThrows(r => r.ReadBytes(2));
|
||||||
r => r.ReadUInt32(),
|
EnsureThrows(r => r.ReadBytes(3));
|
||||||
r => r.ReadInt64(),
|
EnsureThrows(r => r.ReadBytes(4));
|
||||||
r => r.ReadUInt64(),
|
EnsureThrows(r => r.ReadBytes(8));
|
||||||
r => r.ReadDecimal(),
|
EnsureThrows(r => r.ReadBytes(16));
|
||||||
r => r.ReadSingle(),
|
EnsureThrows(r => r.ReadBytes(32));
|
||||||
r => r.ReadDouble(),
|
EnsureThrows(r => r.ReadBytes(100));
|
||||||
r => r.ReadString(),
|
EnsureThrows(r => r.ReadBytes(1000));
|
||||||
r => r.ReadBytes(0),
|
EnsureThrows(r => r.ReadBytes(10000));
|
||||||
r => r.ReadBytes(1),
|
EnsureThrows(r => r.ReadBytes(1000000));
|
||||||
r => r.ReadBytes(2),
|
EnsureThrows(r => r.ReadBytes(10000000));
|
||||||
r => r.ReadBytes(3),
|
EnsureThrows(r => r.ReadBytesAndSize());
|
||||||
r => r.ReadBytes(4),
|
EnsureThrows(r => r.ReadPackedInt32());
|
||||||
r => r.ReadBytes(8),
|
EnsureThrows(r => r.ReadPackedUInt32());
|
||||||
r => r.ReadBytes(16),
|
EnsureThrows(r => r.ReadPackedInt64());
|
||||||
r => r.ReadBytes(32),
|
EnsureThrows(r => r.ReadPackedUInt64());
|
||||||
r => r.ReadBytes(100),
|
EnsureThrows(r => r.ReadVector2());
|
||||||
r => r.ReadBytes(1000),
|
EnsureThrows(r => r.ReadVector3());
|
||||||
r => r.ReadBytes(10000),
|
EnsureThrows(r => r.ReadVector4());
|
||||||
r => r.ReadBytes(1000000),
|
EnsureThrows(r => r.ReadVector2Int());
|
||||||
r => r.ReadBytes(10000000),
|
EnsureThrows(r => r.ReadVector3Int());
|
||||||
r => r.ReadBytesAndSize(),
|
EnsureThrows(r => r.ReadColor());
|
||||||
r => r.ReadPackedInt32(),
|
EnsureThrows(r => r.ReadColor32());
|
||||||
r => r.ReadPackedUInt32(),
|
EnsureThrows(r => r.ReadQuaternion());
|
||||||
r => r.ReadPackedInt64(),
|
EnsureThrows(r => r.ReadRect());
|
||||||
r => r.ReadPackedUInt64(),
|
EnsureThrows(r => r.ReadPlane());
|
||||||
r => r.ReadVector2(),
|
EnsureThrows(r => r.ReadRay());
|
||||||
r => r.ReadVector3(),
|
EnsureThrows(r => r.ReadMatrix4x4());
|
||||||
r => r.ReadVector4(),
|
EnsureThrows(r => r.ReadGuid());
|
||||||
r => r.ReadVector2Int(),
|
|
||||||
r => r.ReadVector3Int(),
|
|
||||||
r => r.ReadColor(),
|
|
||||||
r => r.ReadColor32(),
|
|
||||||
r => r.ReadQuaternion(),
|
|
||||||
r => r.ReadRect(),
|
|
||||||
r => r.ReadPlane(),
|
|
||||||
r => r.ReadRay(),
|
|
||||||
r => r.ReadMatrix4x4(),
|
|
||||||
r => r.ReadGuid(),
|
|
||||||
};
|
|
||||||
byte[][] readerData = new byte[][]{
|
|
||||||
new byte[] {},
|
|
||||||
new byte[] {0},
|
|
||||||
new byte[] {255,0},
|
|
||||||
new byte[] {255,0,2,3,4,5},
|
|
||||||
new byte[] {255,0,2,3,4,5},
|
|
||||||
new byte[] {255,255,255,255,255,255},
|
|
||||||
new byte[] {250,0},
|
|
||||||
new byte[] {250,0,4,5,6,2},
|
|
||||||
new byte[] {248,2},
|
|
||||||
new byte[] {249,2,2,3,4},
|
|
||||||
new byte[] {1,2,3},
|
|
||||||
new byte[] {1,2,3,4},
|
|
||||||
new byte[] {1,2,3,4,5,6,7},
|
|
||||||
new byte[] {1,2,3,4,5,6,7,8},
|
|
||||||
new byte[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
|
|
||||||
new byte[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},
|
|
||||||
new byte[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31},
|
|
||||||
new byte[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32},
|
|
||||||
};
|
|
||||||
foreach (byte[] data in readerData)
|
|
||||||
{
|
|
||||||
foreach (Action<NetworkReader> readFunction in readFunctions)
|
|
||||||
{
|
|
||||||
NetworkReader reader = new NetworkReader(data);
|
|
||||||
readFunction(reader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -142,7 +135,6 @@ public void TestReadingInvalidString()
|
|||||||
0xFB, 0xFC, 0xFD, 0xFE,
|
0xFB, 0xFC, 0xFD, 0xFE,
|
||||||
0xFF,
|
0xFF,
|
||||||
};
|
};
|
||||||
Assert.DoesNotThrow(() => {
|
|
||||||
foreach (byte invalid in invalidUTF8bytes)
|
foreach (byte invalid in invalidUTF8bytes)
|
||||||
{
|
{
|
||||||
NetworkWriter writer = new NetworkWriter();
|
NetworkWriter writer = new NetworkWriter();
|
||||||
@ -150,10 +142,8 @@ public void TestReadingInvalidString()
|
|||||||
byte[] data = writer.ToArray();
|
byte[] data = writer.ToArray();
|
||||||
data[10] = invalid;
|
data[10] = invalid;
|
||||||
NetworkReader reader = new NetworkReader(data);
|
NetworkReader reader = new NetworkReader(data);
|
||||||
string result = reader.ReadString();
|
Assert.Throws<System.Text.DecoderFallbackException>(() => reader.ReadString());
|
||||||
Assert.That(result, Is.EqualTo(null));
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
Loading…
Reference in New Issue
Block a user