argsman: allow duplicate registration between HIDDEN and other categories
What changed, and why it matters
This commit fixes a bug where Bitcoin Core's graphical wallet (bitcoin-qt) would crash immediately on startup. The crash was caused by an overly strict internal safety check that treated a normal, intentional code pattern as a duplicate-setting error. The fix narrows the check so it ignores entries marked as 'hidden' (used for settings that don't apply to a particular program version), restoring normal startup. There is no indication this bug could be exploited by an attacker.
Treat as a routine bug/regression fix rather than a security patch. Users on affected builds should upgrade or apply the patch to restore bitcoin-qt startup. No additional security hardening is indicated.
Security signals we found
Fixes a regression causing a denial-of-service-like startup crash in bitcoin-qt
Change is a relaxation of an internal assertion, not a memory-safety or cryptographic fix
No input-dependent behavior change; crash was deterministic on affected builds
Evidence from the diff
Commit f963f2b relaxes an assertion introduced in PR #35470 that prevented the same argument from being registered under two different OptionsCategory values. The intended pattern from PR #13441 pre-registers GUI-only arguments as OptionsCategory::HIDDEN inside SetupServerArgs so a shared bitcoin.conf containing GUI options does not fail when parsed by bitcoind; SetupUIArgs then re-registers them under OptionsCategory::GUI in bitcoin-qt. The new assertion fired on this HIDDEN/GUI pair and caused a startup assertion failure. The patch skips the duplicate check when either the existing or new category is HIDDEN, while still asserting against duplicates between non-HIDDEN categories.
Changed components
src/common/args.cppArgsManager::AddArgbitcoin-qt startup pathInspect captured patch +3 / −0
diff --git a/src/common/args.cpp b/src/common/args.cpp
index 4721a90b..cfd36e1f 100644
--- a/src/common/args.cpp
+++ b/src/common/args.cpp
@@ -669,7 +669,10 @@ void ArgsManager::AddArg(const std::string& name, const std::string& help, unsig
LOCK(cs_args);
+ // Allow duplicates involving HIDDEN — it is used as a placeholder for args
+ // unavailable in this binary but tolerated for shared config files (see #13441).
for (const auto& arg_map : m_available_args) {
+ if (arg_map.first == OptionsCategory::HIDDEN || cat == OptionsCategory::HIDDEN) continue;
Assert(!arg_map.second.contains(arg_name));
}
Why this scored 26/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.