From 82057795365b252ff5cd9671813246317e398bac Mon Sep 17 00:00:00 2001 From: Max Rantil Date: Thu, 8 Aug 2024 00:26:24 +0200 Subject: [PATCH] lightningd: trim whitespaces from end of config parameters Signed-off-by: Max Rantil --- common/configvar.c | 16 ++++++++++++++++ common/configvar.h | 2 ++ doc/lightningd-config.5.md | 8 ++++++++ lightningd/log.c | 5 ++--- lightningd/options.c | 5 ++--- tests/test_misc.py | 37 +++++++++++++++++++++++++++++++++++++ 6 files changed, 67 insertions(+), 6 deletions(-) diff --git a/common/configvar.c b/common/configvar.c index e7e734565c4a..d696ab2d0e7e 100644 --- a/common/configvar.c +++ b/common/configvar.c @@ -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); } } diff --git a/common/configvar.h b/common/configvar.h index 9a308ecd5b11..158704ab07fa 100644 --- a/common/configvar.h +++ b/common/configvar.h @@ -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) \ diff --git a/doc/lightningd-config.5.md b/doc/lightningd-config.5.md index b1545fd5db63..510fc37f9fff 100644 --- a/doc/lightningd-config.5.md +++ b/doc/lightningd-config.5.md @@ -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: diff --git a/lightningd/log.c b/lightningd/log.c index 91b2b4af9aae..3a9b115d6141 100644 --- a/lightningd/log.c +++ b/lightningd/log.c @@ -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=", OPT_EARLY|OPT_MULTI, arg_log_to_file, NULL, ld, diff --git a/lightningd/options.c b/lightningd/options.c index 2954ffeae016..cd6680584a1a 100644 --- a/lightningd/options.c +++ b/lightningd/options.c @@ -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=", opt_set_talstr, opt_show_charp, &ld->pidfile, "Specify pid file"); diff --git a/tests/test_misc.py b/tests/test_misc.py index 72ef4ff15c49..f59c8c814981 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -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')