summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/enet/protocol.h4
-rw-r--r--packet.c6
-rw-r--r--peer.c13
-rw-r--r--protocol.c36
4 files changed, 42 insertions, 17 deletions
diff --git a/include/enet/protocol.h b/include/enet/protocol.h
index faef917..f8a27d8 100644
--- a/include/enet/protocol.h
+++ b/include/enet/protocol.h
@@ -16,7 +16,9 @@ enum
ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768,
ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1,
ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255,
- ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF
+ ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF,
+ ENET_PROTOCOL_MAXIMUM_PACKET_SIZE = 1024 * 1024 * 1024,
+ ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT = 1024 * 1024
};
typedef enum _ENetProtocolCommand
diff --git a/packet.c b/packet.c
index 2fc9a10..fd59b14 100644
--- a/packet.c
+++ b/packet.c
@@ -26,6 +26,9 @@ enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
if (flags & ENET_PACKET_FLAG_NO_ALLOCATE)
packet -> data = (enet_uint8 *) data;
else
+ if (dataLength <= 0)
+ packet -> data = NULL;
+ else
{
packet -> data = (enet_uint8 *) enet_malloc (dataLength);
if (packet -> data == NULL)
@@ -54,7 +57,8 @@ enet_packet_destroy (ENetPacket * packet)
{
if (packet -> freeCallback != NULL)
(* packet -> freeCallback) (packet);
- if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
+ if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE) &&
+ packet -> data != NULL)
enet_free (packet -> data);
enet_free (packet);
}
diff --git a/peer.c b/peer.c
index 44b0bc5..38839b1 100644
--- a/peer.c
+++ b/peer.c
@@ -104,7 +104,8 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
size_t fragmentLength;
if (peer -> state != ENET_PEER_STATE_CONNECTED ||
- channelID >= peer -> channelCount)
+ channelID >= peer -> channelCount ||
+ packet -> dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE)
return -1;
fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
@@ -113,7 +114,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
if (packet -> dataLength > fragmentLength)
{
- enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
+ enet_uint32 fragmentCount = (packet -> dataLength + fragmentLength - 1) / fragmentLength,
fragmentNumber,
fragmentOffset;
enet_uint8 commandNumber;
@@ -121,6 +122,9 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
ENetList fragments;
ENetOutgoingCommand * fragment;
+ if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT)
+ return -1;
+
if ((packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT)) == ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT &&
channel -> outgoingUnreliableSequenceNumber < 0xFFFF)
{
@@ -164,7 +168,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
fragment -> command.header.channelID = channelID;
fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber;
fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength);
- fragment -> command.sendFragment.fragmentCount = fragmentCount;
+ fragment -> command.sendFragment.fragmentCount = ENET_HOST_TO_NET_32 (fragmentCount);
fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset);
@@ -832,7 +836,8 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
if (fragmentCount > 0)
{
- incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32));
+ if (fragmentCount <= ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT)
+ incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32));
if (incomingCommand -> fragments == NULL)
{
enet_free (incomingCommand);
diff --git a/protocol.c b/protocol.c
index 2e111a8..6d4618c 100644
--- a/protocol.c
+++ b/protocol.c
@@ -406,7 +406,9 @@ enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENet
dataLength = ENET_NET_TO_HOST_16 (command -> sendReliable.dataLength);
* currentData += dataLength;
- if (* currentData > & host -> receivedData [host -> receivedDataLength])
+ if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
+ * currentData < host -> receivedData ||
+ * currentData > & host -> receivedData [host -> receivedDataLength])
return -1;
packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendReliable),
@@ -432,7 +434,9 @@ enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const E
dataLength = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.dataLength);
* currentData += dataLength;
- if (* currentData > & host -> receivedData [host -> receivedDataLength])
+ if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
+ * currentData < host -> receivedData ||
+ * currentData > & host -> receivedData [host -> receivedDataLength])
return -1;
unsequencedGroup = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.unsequencedGroup);
@@ -480,7 +484,9 @@ enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const EN
dataLength = ENET_NET_TO_HOST_16 (command -> sendUnreliable.dataLength);
* currentData += dataLength;
- if (* currentData > & host -> receivedData [host -> receivedDataLength])
+ if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
+ * currentData < host -> receivedData ||
+ * currentData > & host -> receivedData [host -> receivedDataLength])
return -1;
packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable),
@@ -513,7 +519,9 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
* currentData += fragmentLength;
- if (* currentData > & host -> receivedData [host -> receivedDataLength])
+ if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
+ * currentData < host -> receivedData ||
+ * currentData > & host -> receivedData [host -> receivedDataLength])
return -1;
channel = & peer -> channels [command -> header.channelID];
@@ -532,9 +540,11 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset);
totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength);
- if (fragmentOffset >= totalLength ||
- fragmentOffset + fragmentLength > totalLength ||
- fragmentNumber >= fragmentCount)
+ if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT ||
+ fragmentNumber >= fragmentCount ||
+ totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
+ fragmentOffset >= totalLength ||
+ fragmentLength > totalLength - fragmentOffset)
return -1;
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
@@ -622,7 +632,9 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer,
fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
* currentData += fragmentLength;
- if (* currentData > & host -> receivedData [host -> receivedDataLength])
+ if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
+ * currentData < host -> receivedData ||
+ * currentData > & host -> receivedData [host -> receivedDataLength])
return -1;
channel = & peer -> channels [command -> header.channelID];
@@ -647,9 +659,11 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer,
fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset);
totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength);
- if (fragmentOffset >= totalLength ||
- fragmentOffset + fragmentLength > totalLength ||
- fragmentNumber >= fragmentCount)
+ if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT ||
+ fragmentNumber >= fragmentCount ||
+ totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
+ fragmentOffset >= totalLength ||
+ fragmentLength > totalLength - fragmentOffset)
return -1;
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));