Skip to content

Commit

Permalink
fix(net): prevent component size calculation integer overflow
Browse files Browse the repository at this point in the history
  • Loading branch information
FabianTerhorst committed Sep 25, 2024
1 parent 8a1586d commit eab9fc7
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 4 deletions.
46 changes: 42 additions & 4 deletions code/components/net-base/include/ByteCounter.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,14 @@ namespace net
template <typename T>
bool Field(T& value)
{
m_counter += sizeof(value);
const uint64_t size = sizeof(value);
if (m_counter > m_counter + size)
{
m_counter = std::numeric_limits<uint64_t>::max();
return true;
}

m_counter += size;
return true;
}

Expand All @@ -51,6 +58,12 @@ namespace net
template <typename T>
bool Field(T& value, const size_t size)
{
if (m_counter > m_counter + size)
{
m_counter = std::numeric_limits<uint64_t>::max();
return true;
}

m_counter += size;
return true;
}
Expand All @@ -64,29 +77,54 @@ namespace net
template <typename T>
bool Field(Span<T>& value, const size_t size)
{
m_counter += size * sizeof(T);

const uint64_t valueSize = size * sizeof(T);
if (m_counter > m_counter + valueSize)
{
m_counter = std::numeric_limits<uint64_t>::max();
return true;
}

m_counter += valueSize;
return true;
}
};

template <>
inline bool ByteCounter::Field<bool>(bool& value)
{
m_counter += 1;
const uint64_t valueSize = 1;
if (m_counter > m_counter + valueSize)
{
m_counter = std::numeric_limits<uint64_t>::max();
return true;
}

m_counter += valueSize;
return true;
}

template <>
inline bool ByteCounter::Field<std::string_view>(std::string_view& value, const size_t size)
{
if (m_counter > m_counter + size)
{
m_counter = std::numeric_limits<uint64_t>::max();
return true;
}

m_counter += size;
return true;
}

template <>
inline bool ByteCounter::Field<std::string>(std::string& value, const size_t size)
{
if (m_counter > m_counter + size)
{
m_counter = std::numeric_limits<uint64_t>::max();
return true;
}

m_counter += size;
return true;
}
Expand Down
25 changes: 25 additions & 0 deletions code/tests/shared/TestComponents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,28 @@ TEST_CASE("Serializable component property")

REQUIRE(instanceRead.component.GetValue().value.GetValue() == random);
}

namespace SerializableComponentUnlimitedSizeTest
{
class Component: public net::SerializableComponent
{
public:
net::SerializableProperty<uint8_t> value1 {};
net::SerializableProperty<net::Span<uint8_t>, net::storage_type::StreamTail> value2 {};

template <typename T>
bool Process(T& stream)
{
return ProcessPropertiesInOrder<T>(
stream,
value1,
value2
);
}
};
}

TEST_CASE("Serializable component size of unlimited size")
{
REQUIRE(net::SerializableComponent::GetSize<SerializableComponentUnlimitedSizeTest::Component>() == UINT64_MAX);
}

0 comments on commit eab9fc7

Please sign in to comment.