What changed, and why it matters
This change fixes a bug in how Monero wallet software reads payment web links (URIs). Before the fix, if a payment link did not specify an amount, description, or other optional fields, the wallet could accidentally keep leftover values from a previous parse. That could mislead the user into sending the wrong amount or seeing wrong payment details. The patch now clears those fields right after confirming the address is valid, and adds a test to prove it.
Treat as a low-to-moderate reliability/security fix. Merge the patch and backport to maintained branches. Wallet integrators should ensure they do not rely on parse_uri output parameters retaining values across calls, and should update to a release containing this fix.
Security signals we found
Use of uninitialized or stale output values after a successful parse
Potential UI/display of wrong payment amount or metadata
Information disclosure of prior parse state to subsequent callers
Fix includes regression test
Evidence from the diff
wallet2::parse_uri() takes several output parameters passed by reference (address, payment_id, amount, tx_description, recipient_name, unknown_parameters, error). Previously, on a successful parse, optional outputs were only overwritten if the URI explicitly contained them; omitted fields retained whatever value the caller’s variables already held. The patch clears payment_id, amount, tx_description, recipient_name, unknown_parameters, and error immediately after address validation succeeds, so each parse result reflects only the current URI. The amount reset was also removed from the tx_amount branch because it is now done unconditionally. A unit test verifies that stale values are reset when parsing a minimal URI.
Changed components
src/wallet/wallet2.cpp::wallet2::parse_uriMonero wallet URI parsingtests/unit_tests/uri.cppInspect captured patch +29 / −1
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index c128eda..37c6297 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -14869,6 +14869,14 @@ bool wallet2::parse_uri(const std::string &uri, std::string &address, std::strin
error = std::string("URI has wrong address: ") + address;
return false;
}
+
+ payment_id.clear();
+ amount = 0;
+ tx_description.clear();
+ recipient_name.clear();
+ unknown_parameters.clear();
+ error.clear();
+
if (!strchr(remainder.c_str(), '?'))
return true;
@@ -14896,7 +14904,6 @@ bool wallet2::parse_uri(const std::string &uri, std::string &address, std::strin
if (kv[0] == "tx_amount")
{
- amount = 0;
if (!cryptonote::parse_amount(amount, kv[1]))
{
error = std::string("URI has invalid amount: ") + kv[1];
diff --git a/tests/unit_tests/uri.cpp b/tests/unit_tests/uri.cpp
index f1c2b69..ca241bb 100644
--- a/tests/unit_tests/uri.cpp
+++ b/tests/unit_tests/uri.cpp
@@ -82,6 +82,27 @@ TEST(uri, good_address)
ASSERT_EQ(address, TEST_ADDRESS);
}
+TEST(uri, resets_outputs)
+{
+ std::string address = "old address";
+ std::string payment_id = "old payment id";
+ std::string recipient_name = "old recipient name";
+ std::string description = "old description";
+ std::string error = "old error";
+ uint64_t amount = 1;
+ std::vector<std::string> unknown_parameters{"old=parameter"};
+ tools::wallet2 w(cryptonote::TESTNET);
+
+ ASSERT_TRUE(w.parse_uri("monero:" TEST_ADDRESS, address, payment_id, amount, description, recipient_name, unknown_parameters, error));
+ EXPECT_EQ(address, TEST_ADDRESS);
+ EXPECT_EQ(amount, 0);
+ EXPECT_TRUE(payment_id.empty());
+ EXPECT_TRUE(description.empty());
+ EXPECT_TRUE(recipient_name.empty());
+ EXPECT_TRUE(unknown_parameters.empty());
+ EXPECT_TRUE(error.empty());
+}
+
TEST(uri, good_integrated_address)
{
PARSE_URI("monero:" TEST_INTEGRATED_ADDRESS, true);
Why this scored 48/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.