mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
init: fix fatal error on '-wallet' negated option value
Because we don't have type checking for command-line/settings/config args, strings are interpreted as 'false' for non-boolean args. By convention, this "forces" us to interpret negated strings as 'true', which conflicts with the negated option definition in all the settings classes (they expect negated options to always be false and ignore any other value preceding them). Consequently, when retrieving all "wallet" values from the command-line/settings/config, we also fetch the negated string boolean value, which is not of the expected 'string' type. This mismatch leads to an internal fatal error, resulting in an unclean shutdown during initialization. Furthermore, this error displays a poorly descriptive error message: "JSON value of type bool is not of expected type string" This commit fixes the fatal error by ensuring that only string values are returned in the "wallet" settings list, failing otherwise. It also improves the clarity of the returned error message. Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
This commit is contained in:
parent
d79ea809d2
commit
ee47ca29d6
3 changed files with 40 additions and 0 deletions
|
@ -77,6 +77,11 @@ bool VerifyWallets(WalletContext& context)
|
|||
std::set<fs::path> wallet_paths;
|
||||
|
||||
for (const auto& wallet : chain.getSettingsList("wallet")) {
|
||||
if (!wallet.isStr()) {
|
||||
chain.initError(_("Invalid value detected for '-wallet' or '-nowallet'. "
|
||||
"'-wallet' requires a string value, while '-nowallet' accepts only '1' to disable all wallets"));
|
||||
return false;
|
||||
}
|
||||
const auto& wallet_file = wallet.get_str();
|
||||
const fs::path path = fsbridge::AbsPathJoin(GetWalletDir(), fs::PathFromString(wallet_file));
|
||||
|
||||
|
@ -110,6 +115,11 @@ bool LoadWallets(WalletContext& context)
|
|||
try {
|
||||
std::set<fs::path> wallet_paths;
|
||||
for (const auto& wallet : chain.getSettingsList("wallet")) {
|
||||
if (!wallet.isStr()) {
|
||||
chain.initError(_("Invalid value detected for '-wallet' or '-nowallet'. "
|
||||
"'-wallet' requires a string value, while '-nowallet' accepts only '1' to disable all wallets"));
|
||||
return false;
|
||||
}
|
||||
const auto& name = wallet.get_str();
|
||||
if (!wallet_paths.insert(fs::PathFromString(name)).second) {
|
||||
continue;
|
||||
|
|
|
@ -153,6 +153,13 @@ class ConfArgsTest(BitcoinTestFramework):
|
|||
expected_msg='Error: Error parsing command line arguments: Can not set -proxy with no value. Please specify value with -proxy=value.',
|
||||
extra_args=['-proxy'],
|
||||
)
|
||||
# Provide a value different from 1 to the -wallet negated option
|
||||
if self.is_wallet_compiled():
|
||||
for value in [0, 'not_a_boolean']:
|
||||
self.nodes[0].assert_start_raises_init_error(
|
||||
expected_msg="Error: Invalid value detected for '-wallet' or '-nowallet'. '-wallet' requires a string value, while '-nowallet' accepts only '1' to disable all wallets",
|
||||
extra_args=[f'-nowallet={value}'],
|
||||
)
|
||||
|
||||
def test_log_buffer(self):
|
||||
self.stop_node(0)
|
||||
|
|
|
@ -13,11 +13,32 @@ from test_framework.util import assert_equal
|
|||
|
||||
|
||||
class SettingsTest(BitcoinTestFramework):
|
||||
def add_options(self, parser):
|
||||
self.add_wallet_options(parser)
|
||||
|
||||
def set_test_params(self):
|
||||
self.setup_clean_chain = True
|
||||
self.num_nodes = 1
|
||||
self.wallet_names = []
|
||||
|
||||
def test_wallet_settings(self, settings_path):
|
||||
if not self.is_wallet_compiled():
|
||||
return
|
||||
|
||||
self.log.info("Testing wallet settings..")
|
||||
node = self.nodes[0]
|
||||
# Create wallet to use it during tests
|
||||
self.start_node(0)
|
||||
node.createwallet(wallet_name='w1')
|
||||
self.stop_node(0)
|
||||
|
||||
# Verify wallet settings can only be strings. Either names or paths. Not booleans, nums nor anything else.
|
||||
for wallets_data in [[10], [True], [[]], [{}], ["w1", 10], ["w1", False]]:
|
||||
with settings_path.open("w") as fp:
|
||||
json.dump({"wallet": wallets_data}, fp)
|
||||
node.assert_start_raises_init_error(expected_msg="Error: Invalid value detected for '-wallet' or '-nowallet'. '-wallet' requires a string value, while '-nowallet' accepts only '1' to disable all wallets",
|
||||
extra_args=[f'-settings={settings_path}'])
|
||||
|
||||
def run_test(self):
|
||||
node, = self.nodes
|
||||
settings = node.chain_path / "settings.json"
|
||||
|
@ -86,6 +107,8 @@ class SettingsTest(BitcoinTestFramework):
|
|||
self.start_node(0, extra_args=[f"-settings={altsettings}"])
|
||||
self.stop_node(0)
|
||||
|
||||
self.test_wallet_settings(settings)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
SettingsTest(__file__).main()
|
||||
|
|
Loading…
Add table
Reference in a new issue