lightningd: trim whitespaces from end of config parameters

Signed-off-by: Max Rantil <rantil@pm.me>
This commit is contained in:
Max Rantil 2024-08-08 00:26:24 +02:00 committed by Rusty Russell
parent d0c0c4480a
commit 3e65ef4b12
6 changed files with 67 additions and 6 deletions

View file

@ -51,6 +51,20 @@ const struct opt_table *configvar_unparsed(struct configvar *cv)
return ot;
}
static void trim_whitespace(const char *s)
{
size_t len = strlen(s);
/* Cast away const to allow modifications */
char *mutable_s = (char *)s;
while (len > 0 && isspace((unsigned char)mutable_s[len - 1]))
len--;
/* Move null terminator to the end of the trimmed string */
memmove(mutable_s + len, mutable_s + strlen(s), 1);
}
const char *configvar_parse(struct configvar *cv,
bool early,
bool full_knowledge,
@ -82,6 +96,8 @@ const char *configvar_parse(struct configvar *cv,
} else {
if (!cv->optarg)
return "requires an argument";
if (!(ot->type & OPT_KEEP_WHITESPACE))
trim_whitespace(cv->optarg);
return ot->cb_arg(cv->optarg, ot->u.arg);
}
}

View file

@ -60,6 +60,8 @@ struct configvar {
#define OPT_SHOWBOOL (1 << (OPT_USER_START+5))
/* Can be changed at runtime: cb will get called with NULL for `check`! */
#define OPT_DYNAMIC (1 << (OPT_USER_START+6))
/* Keep whitespace at the end of the option argument */
#define OPT_KEEP_WHITESPACE (1 << (OPT_USER_START+7))
/* Use this instead of opt_register_*_arg if you want OPT_* from above */
#define clnopt_witharg(names, type, cb, show, arg, desc) \

View file

@ -83,6 +83,14 @@ re-enable it. Unless we've made a horrible mistake it's probably time
to complain or fix to whatever is using the old API. It can be
specified multiple times for different features.
### Whitespace Handling
Because it's a common error, we automatically trim whitespace from the
end of most configuration options. Exceptions are noted below:
- `log-prefix`: Preserves whitespace at the end.
- `alias`: Preserves whitespace at the end.
### Bitcoin control options:
Bitcoin control options:

View file

@ -915,9 +915,8 @@ void opt_register_logging(struct lightningd *ld)
opt_set_bool_arg, opt_show_bool,
&ld->log_book->print_timestamps,
"prefix log messages with timestamp");
opt_register_early_arg("--log-prefix", arg_log_prefix, show_log_prefix,
ld->log_book,
"log prefix");
clnopt_witharg("--log-prefix", OPT_EARLY|OPT_KEEP_WHITESPACE,
arg_log_prefix, show_log_prefix, ld->log_book, "log prefix");
clnopt_witharg("--log-file=<file>",
OPT_EARLY|OPT_MULTI,
arg_log_to_file, NULL, ld,

View file

@ -1525,9 +1525,8 @@ static void register_opts(struct lightningd *ld)
opt_lightningd_usage, ld, "Print this message.");
opt_register_arg("--rgb", opt_set_rgb, opt_show_rgb, ld,
"RRGGBB hex color for node");
opt_register_arg("--alias", opt_set_alias, opt_show_alias, ld,
"Up to 32-byte alias for node");
clnopt_witharg("--alias", OPT_KEEP_WHITESPACE, opt_set_alias,
opt_show_alias, ld, "Up to 32-byte alias for node");
opt_register_arg("--pid-file=<file>", opt_set_talstr, opt_show_charp,
&ld->pidfile,
"Specify pid file");

View file

@ -3867,6 +3867,43 @@ def test_fast_shutdown(node_factory):
break
def test_config_whitespace(node_factory):
""" Test the configuration parsing with extra
whitespace in the configuration file. """
l1 = node_factory.get_node()
configfile = os.path.join(l1.daemon.opts.get("lightning-dir"), TEST_NETWORK, 'config')
# Stop the node to modify the configuration file safely
l1.stop()
# Ensure the log-prefix option is not set in the command line arguments
if 'log-prefix' in l1.daemon.opts:
del l1.daemon.opts['log-prefix']
# Write configuration parameters with extra whitespace
with open(configfile, "a") as f:
f.write("\n\n# Test whitespace\n")
f.write("funder-policy-mod=100 \n")
f.write("funder-min-their-funding=10000\n")
f.write("allow-deprecated-apis=false \n")
f.write("alias=MyLightningNode \n")
f.write("log-prefix=MyNode \n")
l1.start()
configs = l1.rpc.listconfigs()
# Verify that the trimmed configuration values are correctly set
assert configs['configs']['funder-policy-mod']['value_str'] == '100', "funder-policy-mod should be '100'"
assert configs['configs']['funder-min-their-funding']['value_str'] == '10000', "funder-min-their-funding should be '10000'"
assert configs['configs']['allow-deprecated-apis']['value_bool'] is False, "allow-deprecated-apis should be False"
# We want to keep the whitespaces at the parameter 'alias' & 'log-prefix'
assert configs['configs']['alias']['value_str'] == 'MyLightningNode ', "alias should be 'MyLightningNode '"
assert configs['configs']['log-prefix']['value_str'] == 'MyNode ', "log-prefix should be 'MyNode '"
def test_setconfig(node_factory, bitcoind):
l1, l2 = node_factory.line_graph(2, fundchannel=False)
configfile = os.path.join(l2.daemon.opts.get("lightning-dir"), TEST_NETWORK, 'config')