Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/core/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
if (BUILD_TESTING AND (GTest_FOUND OR GTEST_FOUND))
add_executable(core_test pack_test.cpp events_test.cpp chain_test.cpp)
target_link_libraries(core_test PRIVATE GTest::gtest_main core GTest::gtest)
add_executable(core_test pack_test.cpp events_test.cpp chain_test.cpp packet_test.cpp)
target_link_libraries(core_test PRIVATE GTest::gtest_main core c2pool_merged_mining GTest::gtest)

include(GoogleTest)
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
Expand Down
64 changes: 64 additions & 0 deletions src/core/test/packet_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include <gtest/gtest.h>

#include <cstddef>
#include <limits>
#include <ios>
#include <vector>

#include <core/pack.hpp>
#include <core/pack_types.hpp>
#include <core/message.hpp>
#include <core/hash.hpp>
#include <core/packet.hpp>

// A4 (Bug-9 hardening) cap-boundary tests for the Packet read-constructor.
// The read ctor caps prefix_length at MAX_PREFIX_LENGTH (16) and throws
// std::ios_base::failure on over-cap values, which is how UAF garbage from a
// destroyed m_node (Bug-3-family rapid disconnect/reconnect) is rejected
// without crashing the process. See src/core/packet.hpp.
namespace {

constexpr size_t kCap = 16; // must track MAX_PREFIX_LENGTH in packet.hpp

// --- at/under the cap: must succeed and size the prefix exactly ---

TEST(PacketPrefixCap, ZeroLengthSucceeds)
{
core::Packet p(0);
EXPECT_EQ(p.prefix.size(), 0u);
}

TEST(PacketPrefixCap, JustUnderCapSucceeds)
{
core::Packet p(kCap - 1);
EXPECT_EQ(p.prefix.size(), kCap - 1);
}

TEST(PacketPrefixCap, AtCapSucceeds)
{
// Boundary: exactly at the cap is the largest accepted value.
core::Packet p(kCap);
EXPECT_EQ(p.prefix.size(), kCap);
}

// --- over the cap: must throw cleanly, never resize ---

TEST(PacketPrefixCap, JustOverCapThrows)
{
EXPECT_THROW({ core::Packet p(kCap + 1); }, std::ios_base::failure);
}

TEST(PacketPrefixCap, WayOverCapThrows)
{
EXPECT_THROW({ core::Packet p(1024); }, std::ios_base::failure);
}

TEST(PacketPrefixCap, UafGarbageMaxSizeThrows)
{
// Simulates the garbage size_t read from a freed m_node vector; pre-cap
// this reached resize() and aborted via std::length_error.
EXPECT_THROW({ core::Packet p(std::numeric_limits<size_t>::max()); },
std::ios_base::failure);
}

} // namespace
Loading