Blob Blame History Raw
From ea5510dd979bb6d375324cda26925d9e7c4362f5 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 19 Jul 2021 10:04:16 -0400
Subject: [PATCH 1/2] Low: tools: The --get-value option does not require an
 arg.

Regression in 2.1.0 introduced by 15f5c2901.
---
 tools/crm_attribute.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/crm_attribute.c b/tools/crm_attribute.c
index 2cc8d26..8a5b4e4 100644
--- a/tools/crm_attribute.c
+++ b/tools/crm_attribute.c
@@ -242,7 +242,7 @@ static GOptionEntry deprecated_entries[] = {
       NULL, NULL
     },
 
-    { "get-value", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, value_cb,
+    { "get-value", 0, G_OPTION_FLAG_HIDDEN|G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, value_cb,
       NULL, NULL
     },
 
-- 
1.8.3.1


From ef054d943afe8e60017f6adc4e25f88a59ac91a4 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 19 Jul 2021 11:37:04 -0400
Subject: [PATCH 2/2] Low: libcrmcommon: Allow negative numbers as cmdline
 options.

The bug here is that negative numbers (for instance, negative scores)
are not supported as command line arguments.  Because we break up a
string that starts with a single dash into multiple arguments, "-1000"
becomes "-1", "-0", "-0", and "-0".

Because we don't have enough information about what is happening on the
command line, the best we can do here is recognize something as a
negative number and pass it on.  Any errors will have to be detected at
a later step.

Also note that we only recognize negative numbers if they start with
1-9.  Starting with 0 will be recognized as some sort of string.

Regression in 2.1.0 caused by a long-standing bug in
pcmk__cmdline_preproc_test.
---
 lib/common/cmdline.c                               | 29 ++++++++++++++++++++++
 .../tests/cmdline/pcmk__cmdline_preproc_test.c     | 24 +++++++++++++++++-
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/lib/common/cmdline.c b/lib/common/cmdline.c
index 7c95d02..9c1b810 100644
--- a/lib/common/cmdline.c
+++ b/lib/common/cmdline.c
@@ -9,6 +9,7 @@
 
 #include <crm_internal.h>
 
+#include <ctype.h>
 #include <glib.h>
 
 #include <crm/crm.h>
@@ -189,6 +190,34 @@ pcmk__cmdline_preproc(char **argv, const char *special) {
             /* Skip over leading dash */
             char *ch = argv[i]+1;
 
+            /* This looks like the start of a number, which means it is a negative
+             * number.  It's probably the argument to the preceeding option, but
+             * we can't know that here.  Copy it over and let whatever handles
+             * arguments next figure it out.
+             */
+            if (*ch != '\0' && *ch >= '1' && *ch <= '9') {
+                bool is_numeric = true;
+
+                while (*ch != '\0') {
+                    if (!isdigit(*ch)) {
+                        is_numeric = false;
+                        break;
+                    }
+
+                    ch++;
+                }
+
+                if (is_numeric) {
+                    g_ptr_array_add(arr, g_strdup_printf("%s", argv[i]));
+                    continue;
+                } else {
+                    /* This argument wasn't entirely numeric.  Reset ch to the
+                     * beginning so we can process it one character at a time.
+                     */
+                    ch = argv[i]+1;
+                }
+            }
+
             while (*ch != '\0') {
                 /* This is a special short argument that takes an option.  getopt
                  * allows values to be interspersed with a list of arguments, but
diff --git a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c
index b8506c6..9a752ef 100644
--- a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c
+++ b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 the Pacemaker project contributors
+ * Copyright 2020-2021 the Pacemaker project contributors
  *
  * The version control history for this file may have further details.
  *
@@ -86,6 +86,26 @@ long_arg(void) {
     g_strfreev(processed);
 }
 
+static void
+negative_score(void) {
+    const char *argv[] = { "-v", "-1000", NULL };
+    const gchar *expected[] = { "-v", "-1000", NULL };
+
+    gchar **processed = pcmk__cmdline_preproc((char **) argv, "v");
+    LISTS_EQ(processed, expected);
+    g_strfreev(processed);
+}
+
+static void
+negative_score_2(void) {
+    const char *argv[] = { "-1i3", NULL };
+    const gchar *expected[] = { "-1", "-i", "-3", NULL };
+
+    gchar **processed = pcmk__cmdline_preproc((char **) argv, NULL);
+    LISTS_EQ(processed, expected);
+    g_strfreev(processed);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -98,5 +118,7 @@ main(int argc, char **argv)
     g_test_add_func("/common/cmdline/preproc/special_args", special_args);
     g_test_add_func("/common/cmdline/preproc/special_arg_at_end", special_arg_at_end);
     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);
     return g_test_run();
 }
-- 
1.8.3.1