aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortobtoht <tob@featherwallet.org>2026-06-09 17:49:35 +0000
committertobtoht <tob@featherwallet.org>2026-06-09 17:49:35 +0000
commit1ed6b8183c798fe65df724d6ea7fdc3ba3ad20f7 (patch)
treea7d0176fb663a0c1211ea55eed52b42e0c5d9a6c
parentf6939487fe5f8efe865cbfa9204956c85411241b (diff)
parent93d792e63c85baec6f8a3b8f9bbad3f803dd3a7e (diff)
downloadmonzero-core-1ed6b8183c798fe65df724d6ea7fdc3ba3ad20f7.tar.gz
monzero-core-1ed6b8183c798fe65df724d6ea7fdc3ba3ad20f7.tar.xz
monzero-core-1ed6b8183c798fe65df724d6ea7fdc3ba3ad20f7.zip
Merge pull request #10704
93d792e net: canonicalize Tor/I2P hosts during deserialization (selsta)
-rw-r--r--src/net/i2p_address.cpp12
-rw-r--r--src/net/tor_address.cpp14
-rw-r--r--tests/unit_tests/net.cpp28
3 files changed, 45 insertions, 9 deletions
diff --git a/src/net/i2p_address.cpp b/src/net/i2p_address.cpp
index e793048c0..e24e7da01 100644
--- a/src/net/i2p_address.cpp
+++ b/src/net/i2p_address.cpp
@@ -117,11 +117,15 @@ namespace net
bool i2p_address::_load(epee::serialization::portable_storage& src, epee::serialization::section* hparent)
{
i2p_serialized in{};
- if (in._load(src, hparent) && in.host.size() < sizeof(host_) && (in.host == unknown_host || !host_check(in.host).has_error()))
+ if (in._load(src, hparent) && in.host.size() < sizeof(host_))
{
- std::memcpy(host_, in.host.data(), in.host.size());
- std::memset(host_ + in.host.size(), 0, sizeof(host_) - in.host.size());
- return true;
+ net::canonicalize_host(in.host);
+ if (in.host == unknown_host || !host_check(in.host).has_error())
+ {
+ std::memcpy(host_, in.host.data(), in.host.size());
+ std::memset(host_ + in.host.size(), 0, sizeof(host_) - in.host.size());
+ return true;
+ }
}
static_assert(sizeof(unknown_host) <= sizeof(host_), "bad buffer size");
std::memcpy(host_, unknown_host, sizeof(unknown_host)); // include null terminator
diff --git a/src/net/tor_address.cpp b/src/net/tor_address.cpp
index 35bd8e9a2..25f9fde66 100644
--- a/src/net/tor_address.cpp
+++ b/src/net/tor_address.cpp
@@ -129,12 +129,16 @@ namespace net
bool tor_address::_load(epee::serialization::portable_storage& src, epee::serialization::section* hparent)
{
tor_serialized in{};
- if (in._load(src, hparent) && in.host.size() < sizeof(host_) && (in.host == unknown_host || !host_check(in.host).has_error()))
+ if (in._load(src, hparent) && in.host.size() < sizeof(host_))
{
- std::memcpy(host_, in.host.data(), in.host.size());
- std::memset(host_ + in.host.size(), 0, sizeof(host_) - in.host.size());
- port_ = in.port;
- return true;
+ net::canonicalize_host(in.host);
+ if (in.host == unknown_host || !host_check(in.host).has_error())
+ {
+ std::memcpy(host_, in.host.data(), in.host.size());
+ std::memset(host_ + in.host.size(), 0, sizeof(host_) - in.host.size());
+ port_ = in.port;
+ return true;
+ }
}
static_assert(sizeof(unknown_host) <= sizeof(host_), "bad buffer size");
std::memcpy(host_, unknown_host, sizeof(unknown_host)); // include null terminator
diff --git a/tests/unit_tests/net.cpp b/tests/unit_tests/net.cpp
index 9633f50e5..291f1e6ab 100644
--- a/tests/unit_tests/net.cpp
+++ b/tests/unit_tests/net.cpp
@@ -343,6 +343,20 @@ TEST(tor_address, epee_serializev_v3)
EXPECT_STREQ(v3_onion, command.tor.host_str());
EXPECT_EQ(10u, command.tor.port());
+ // make sure tor_address::_load canonicalizes incoming hosts
+ {
+ epee::serialization::portable_storage stg{};
+ stg.load_from_binary(epee::to_span(buffer));
+
+ EXPECT_TRUE(stg.set_value("host", std::string{v3_onion_upper}, stg.open_section("tor", nullptr, false)));
+ EXPECT_TRUE(command.load(stg));
+ }
+
+ EXPECT_FALSE(command.tor.is_unknown());
+ EXPECT_NE(net::tor_address{}, command.tor);
+ EXPECT_STREQ(v3_onion, command.tor.host_str());
+ EXPECT_EQ(10u, command.tor.port());
+
// make sure that exceeding max buffer doesn't destroy tor_address::_load
{
epee::serialization::portable_storage stg{};
@@ -751,6 +765,20 @@ TEST(i2p_address, epee_serializev_b32)
EXPECT_STREQ(b32_i2p, command.i2p.host_str());
EXPECT_EQ(1u, command.i2p.port());
+ // make sure i2p_address::_load canonicalizes incoming hosts
+ {
+ epee::serialization::portable_storage stg{};
+ stg.load_from_binary(epee::to_span(buffer));
+
+ EXPECT_TRUE(stg.set_value("host", std::string{b32_i2p_upper}, stg.open_section("i2p", nullptr, false)));
+ EXPECT_TRUE(command.load(stg));
+ }
+
+ EXPECT_FALSE(command.i2p.is_unknown());
+ EXPECT_NE(net::i2p_address{}, command.i2p);
+ EXPECT_STREQ(b32_i2p, command.i2p.host_str());
+ EXPECT_EQ(1u, command.i2p.port());
+
// make sure that exceeding max buffer doesn't destroy i2p_address::_load
{
epee::serialization::portable_storage stg{};