Blob Blame History Raw
From 2eee93e8f9ea2daa81769bc69843d63ced1a7112 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
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 <clumens@redhat.com>
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