Skip to content

Commit

Permalink
wallet: Support %w in -walletnotify script, on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
promag authored and luke-jr committed Oct 6, 2021
1 parent c715663 commit 4c48151
Show file tree
Hide file tree
Showing 5 changed files with 6 additions and 14 deletions.
4 changes: 1 addition & 3 deletions src/util/system.cpp
Expand Up @@ -1225,14 +1225,12 @@ fs::path GetSpecialFolderPath(int nFolder, bool fCreate)
}
#endif

#ifndef WIN32
std::string ShellEscape(const std::string& arg)
{
std::string escaped = arg;
boost::replace_all(escaped, "'", "'\"'\"'");
boost::replace_all(escaped, "'", "'\\''");
return "'" + escaped + "'";
}
#endif

#if HAVE_SYSTEM
void runCommand(const std::string& strCommand)
Expand Down
2 changes: 0 additions & 2 deletions src/util/system.h
Expand Up @@ -96,9 +96,7 @@ fs::path GetConfigFile(const std::string& confPath);
#ifdef WIN32
fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
#endif
#ifndef WIN32
std::string ShellEscape(const std::string& arg);
#endif
#if HAVE_SYSTEM
void runCommand(const std::string& strCommand);
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/init.cpp
Expand Up @@ -70,7 +70,7 @@ void WalletInit::AddWalletOptions(ArgsManager& argsman) const
argsman.AddArg("-walletbroadcast", strprintf("Make the wallet broadcast transactions (default: %u)", DEFAULT_WALLETBROADCAST), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
argsman.AddArg("-walletdir=<dir>", "Specify directory to hold wallets (default: <datadir>/wallets if it exists, otherwise <datadir>)", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::WALLET);
#if HAVE_SYSTEM
argsman.AddArg("-walletnotify=<cmd>", "Execute command when a wallet transaction changes. %s in cmd is replaced by TxID, %w is replaced by wallet name, %b is replaced by the hash of the block including the transaction (set to 'unconfirmed' if the transaction is not included) and %h is replaced by the block height (-1 if not included). %w is not currently implemented on windows. On systems where %w is supported, it should NOT be quoted because this would break shell escaping used to invoke the command.", ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
argsman.AddArg("-walletnotify=<cmd>", "Execute command when a wallet transaction changes. %s in cmd is replaced by TxID, %w is replaced by wallet name, %b is replaced by the hash of the block including the transaction (set to 'unconfirmed' if the transaction is not included) and %h is replaced by the block height (-1 if not included). %w should NOT be quoted because this would break shell escaping used to invoke the command.", ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
#endif
argsman.AddArg("-walletrbf", strprintf("Send transactions with full-RBF opt-in enabled (RPC only, default: %u)", DEFAULT_WALLET_RBF), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);

Expand Down
4 changes: 0 additions & 4 deletions src/wallet/wallet.cpp
Expand Up @@ -950,11 +950,7 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const CWalletTx::Confirmatio
#if HAVE_SYSTEM
// notify an external script when a wallet transaction comes in or is updated
if (gArgs.IsArgSet("-walletnotify")) {
#ifdef WIN32
const std::string walletname_escaped = "wallet_name_substitution_is_not_available_on_Windows";
#else
const std::string walletname_escaped = ShellEscape(GetName());
#endif
const std::string txid_hex = hash.GetHex();
std::string blockhash_hex, blockheight_str;
if (confirm.status == CWalletTx::Status::CONFIRMED) {
Expand Down
8 changes: 4 additions & 4 deletions test/functional/feature_notifications.py
Expand Up @@ -14,13 +14,13 @@

# Linux allow all characters other than \x00
# Windows disallow control characters (0-31) and /\?%:|"<>
FILE_CHAR_START = 32 if os.name == 'nt' else 1
FILE_CHAR_START = 43 if os.name == 'nt' else 1
FILE_CHAR_END = 128
FILE_CHARS_DISALLOWED = '/\\?%*:|"<>' if os.name == 'nt' else '/'
FILE_CHARS_DISALLOWED = '/:;<>?@[\\]^`{|}' if os.name == 'nt' else '/'
UNCONFIRMED_HASH_STRING = 'unconfirmed'

def notify_outputname(walletname, txid):
return txid if os.name == 'nt' else '{}_{}'.format(walletname, txid)
return '{}_{}'.format(walletname, txid)


class NotificationsTest(BitcoinTestFramework):
Expand All @@ -29,7 +29,7 @@ def set_test_params(self):
self.setup_clean_chain = True

def setup_network(self):
self.wallet = ''.join(chr(i) for i in range(FILE_CHAR_START, FILE_CHAR_END) if chr(i) not in FILE_CHARS_DISALLOWED)
self.wallet = 'wallet' + ''.join(chr(i) for i in range(FILE_CHAR_START, FILE_CHAR_END) if chr(i) not in FILE_CHARS_DISALLOWED)
self.alertnotify_dir = os.path.join(self.options.tmpdir, "alertnotify")
self.blocknotify_dir = os.path.join(self.options.tmpdir, "blocknotify")
self.walletnotify_dir = os.path.join(self.options.tmpdir, "walletnotify")
Expand Down

0 comments on commit 4c48151

Please sign in to comment.