From 2eee93e8f9ea2daa81769bc69843d63ced1a7112 Mon Sep 17 00:00:00 2001 From: Chris Lumens Date: Tue, 20 Jul 2021 16:39:07 -0400 Subject: [PATCH 1/2] Low: tools: Audit command line options. This just goes through and makes sure the command line options that take arguments are in the special parameter to pcmk__cmdline_preproc, and that options that do not take arguments are not. --- tools/crm_attribute.c | 2 +- tools/crm_error.c | 2 +- tools/crm_resource.c | 2 +- tools/crm_rule.c | 2 +- tools/crm_simulate.c | 2 +- tools/crmadmin.c | 2 +- tools/stonith_admin.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/crm_attribute.c b/tools/crm_attribute.c index 8a5b4e4..6bd4e2a 100644 --- a/tools/crm_attribute.c +++ b/tools/crm_attribute.c @@ -312,7 +312,7 @@ main(int argc, char **argv) GOptionGroup *output_group = NULL; pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY); - gchar **processed_args = pcmk__cmdline_preproc(argv, "DGNPdilnpstv"); + gchar **processed_args = pcmk__cmdline_preproc(argv, "NPUdilnpstv"); GOptionContext *context = build_arg_context(args, &output_group); if (!g_option_context_parse_strv(context, &processed_args, &error)) { diff --git a/tools/crm_error.c b/tools/crm_error.c index b4328ce..923f393 100644 --- a/tools/crm_error.c +++ b/tools/crm_error.c @@ -79,7 +79,7 @@ main(int argc, char **argv) GOptionGroup *output_group = NULL; pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY); - gchar **processed_args = pcmk__cmdline_preproc(argv, "lrnX"); + gchar **processed_args = pcmk__cmdline_preproc(argv, NULL); GOptionContext *context = build_arg_context(args, &output_group); if (!g_option_context_parse_strv(context, &processed_args, &error)) { diff --git a/tools/crm_resource.c b/tools/crm_resource.c index fa7902c..d8e140f 100644 --- a/tools/crm_resource.c +++ b/tools/crm_resource.c @@ -1530,7 +1530,7 @@ main(int argc, char **argv) */ args = pcmk__new_common_args(SUMMARY); - processed_args = pcmk__cmdline_preproc(argv, "GINSTdginpstuv"); + processed_args = pcmk__cmdline_preproc(argv, "GHINSTdginpstuvx"); context = build_arg_context(args, &output_group); pcmk__register_formats(output_group, formats); diff --git a/tools/crm_rule.c b/tools/crm_rule.c index 8b19bcd..30c5155 100644 --- a/tools/crm_rule.c +++ b/tools/crm_rule.c @@ -239,7 +239,7 @@ main(int argc, char **argv) pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY); GOptionContext *context = build_arg_context(args); - gchar **processed_args = pcmk__cmdline_preproc(argv, "nopNO"); + gchar **processed_args = pcmk__cmdline_preproc(argv, "drX"); if (!g_option_context_parse_strv(context, &processed_args, &error)) { exit_code = CRM_EX_USAGE; diff --git a/tools/crm_simulate.c b/tools/crm_simulate.c index 0406bff..c83b1b1 100644 --- a/tools/crm_simulate.c +++ b/tools/crm_simulate.c @@ -865,7 +865,7 @@ main(int argc, char **argv) GOptionGroup *output_group = NULL; pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY); - gchar **processed_args = pcmk__cmdline_preproc(argv, "bdefgiqrtuwxDFGINO"); + gchar **processed_args = pcmk__cmdline_preproc(argv, "bdefgiqrtuwxDFGINOP"); GOptionContext *context = build_arg_context(args, &output_group); /* This must come before g_option_context_parse_strv. */ diff --git a/tools/crmadmin.c b/tools/crmadmin.c index 5cbde1b..b98f282 100644 --- a/tools/crmadmin.c +++ b/tools/crmadmin.c @@ -188,7 +188,7 @@ main(int argc, char **argv) GOptionGroup *output_group = NULL; pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY); - gchar **processed_args = pcmk__cmdline_preproc(argv, "itBDEHKNPS"); + gchar **processed_args = pcmk__cmdline_preproc(argv, "itKNS"); GOptionContext *context = build_arg_context(args, &output_group); pcmk__register_formats(output_group, formats); diff --git a/tools/stonith_admin.c b/tools/stonith_admin.c index 6773cea..2d48326 100644 --- a/tools/stonith_admin.c +++ b/tools/stonith_admin.c @@ -349,7 +349,7 @@ main(int argc, char **argv) GOptionGroup *output_group = NULL; pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY); - gchar **processed_args = pcmk__cmdline_preproc(argv, "adehilorstvBCDFHQRTU"); + gchar **processed_args = pcmk__cmdline_preproc(argv, "adehilorstvyBCDFHQRTU"); GOptionContext *context = build_arg_context(args, &output_group); pcmk__register_formats(output_group, formats); -- 1.8.3.1 From 8301678ad1162450814d2fea5288aefe47a67a74 Mon Sep 17 00:00:00 2001 From: Chris Lumens Date: Tue, 20 Jul 2021 16:40:58 -0400 Subject: [PATCH 2/2] Low: libcrmcommon: Also allow string arguments that start with a dash. There's various places where an option to a command line argument could itself be a valid command line argument. For instance: crm_attribute -n crm_mon_options -v "-1i3" The previous patching to pcmk__cmdline_preproc did not take this into account. With this patch, options that are last in a string (or by themselves) and take an argument will have the next command line option grabbed and copied straight through without processing. Regression in 2.1.0 caused by a long-standing bug in pcmk__cmdline_preproc. --- lib/common/cmdline.c | 8 ++++++ .../tests/cmdline/pcmk__cmdline_preproc_test.c | 33 ++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/lib/common/cmdline.c b/lib/common/cmdline.c index 9c1b810..1ca6147 100644 --- a/lib/common/cmdline.c +++ b/lib/common/cmdline.c @@ -146,6 +146,7 @@ gchar ** pcmk__cmdline_preproc(char **argv, const char *special) { GPtrArray *arr = NULL; bool saw_dash_dash = false; + bool copy_option = false; if (argv == NULL) { return NULL; @@ -175,6 +176,12 @@ pcmk__cmdline_preproc(char **argv, const char *special) { continue; } + if (copy_option == true) { + g_ptr_array_add(arr, g_strdup(argv[i])); + copy_option = false; + continue; + } + /* This is just a dash by itself. That could indicate stdin/stdout, or * it could be user error. Copy it over and let glib figure it out. */ @@ -239,6 +246,7 @@ pcmk__cmdline_preproc(char **argv, const char *special) { */ } else { g_ptr_array_add(arr, g_strdup_printf("-%c", *ch)); + copy_option = true; ch++; } diff --git a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c index 9a752ef..edc5640 100644 --- a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c +++ b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c @@ -106,6 +106,36 @@ negative_score_2(void) { g_strfreev(processed); } +static void +string_arg_with_dash(void) { + const char *argv[] = { "-n", "crm_mon_options", "-v", "--opt1 --opt2", NULL }; + const gchar *expected[] = { "-n", "crm_mon_options", "-v", "--opt1 --opt2", NULL }; + + gchar **processed = pcmk__cmdline_preproc((char **) argv, "v"); + LISTS_EQ(processed, expected); + g_strfreev(processed); +} + +static void +string_arg_with_dash_2(void) { + const char *argv[] = { "-n", "crm_mon_options", "-v", "-1i3", NULL }; + const gchar *expected[] = { "-n", "crm_mon_options", "-v", "-1i3", NULL }; + + gchar **processed = pcmk__cmdline_preproc((char **) argv, "v"); + LISTS_EQ(processed, expected); + g_strfreev(processed); +} + +static void +string_arg_with_dash_3(void) { + const char *argv[] = { "-abc", "-1i3", NULL }; + const gchar *expected[] = { "-a", "-b", "-c", "-1i3", NULL }; + + gchar **processed = pcmk__cmdline_preproc((char **) argv, "c"); + LISTS_EQ(processed, expected); + g_strfreev(processed); +} + int main(int argc, char **argv) { @@ -120,5 +150,8 @@ main(int argc, char **argv) g_test_add_func("/common/cmdline/preproc/long_arg", long_arg); g_test_add_func("/common/cmdline/preproc/negative_score", negative_score); g_test_add_func("/common/cmdline/preproc/negative_score_2", negative_score_2); + g_test_add_func("/common/cmdline/preproc/string_arg_with_dash", string_arg_with_dash); + g_test_add_func("/common/cmdline/preproc/string_arg_with_dash_2", string_arg_with_dash_2); + g_test_add_func("/common/cmdline/preproc/string_arg_with_dash_3", string_arg_with_dash_3); return g_test_run(); } -- 1.8.3.1