]> granicus.if.org Git - p11-kit/commitdiff
argv: Fix misinterpretation of backslash in quotes
authorDaiki Ueno <dueno@redhat.com>
Wed, 15 Feb 2017 16:23:18 +0000 (17:23 +0100)
committerDaiki Ueno <ueno@gnu.org>
Thu, 16 Feb 2017 11:54:59 +0000 (12:54 +0100)
Don't append the backslash character twice to the output.  It is
interpolated a few lines below, if it is really required.

common/Makefile.am
common/argv.c
common/test-argv.c [new file with mode: 0644]

index b053ec0df21a87fe288f1579c5b0cf722e7c68e9..9265f5a5d2594a895b4c655e42caae769068b1af 100644 (file)
@@ -61,8 +61,12 @@ CHECK_PROGS += \
        test-path \
        test-lexer \
        test-message \
+       test-argv \
        $(NULL)
 
+test_argv_SOURCES = common/test-argv.c
+test_argv_LDADD = $(common_LIBS)
+
 test_array_SOURCES = common/test-array.c
 test_array_LDADD = $(common_LIBS)
 
index 6d91bfa4c5acd3fed91488b2e7bef4f50721fc80..541730cc3ac332b672745f4339dd1ad7db785b37 100644 (file)
@@ -66,7 +66,7 @@ p11_argv_parse (const char *string,
                /* Inside of quotes */
                } else if (quote != '\0') {
                        if (*src == '\\') {
-                               *at++ = *src++;
+                               src++;
                                if (!*src) {
                                        ret = false;
                                        goto done;
diff --git a/common/test-argv.c b/common/test-argv.c
new file mode 100644 (file)
index 0000000..7eeddde
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 Red Hat Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *     * Redistributions of source code must retain the above
+ *       copyright notice, this list of conditions and the
+ *       following disclaimer.
+ *     * Redistributions in binary form must reproduce the
+ *       above copyright notice, this list of conditions and
+ *       the following disclaimer in the documentation and/or
+ *       other materials provided with the distribution.
+ *     * The names of contributors to this software may not be
+ *       used to endorse or promote products derived from this
+ *       software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Daiki Ueno
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "argv.h"
+#include "test.h"
+
+struct {
+       char *foo;
+       char *bar;
+} test;
+
+static void
+on_argv_parsed (char *argument, void *data)
+{
+       char *value;
+
+       value = argument + strcspn (argument, ":=");
+       if (!*value)
+               value = NULL;
+       else
+               *(value++) = 0;
+
+       if (strcmp (argument, "foo") == 0) {
+               test.foo = value ? strdup (value) : NULL;
+       } else if (strcmp (argument, "bar") == 0) {
+               test.bar = value ? strdup (value) : NULL;
+       }
+}
+
+static void
+setup (void *data)
+{
+       memset (&test, 0, sizeof (test));
+}
+
+static void
+teardown (void *data)
+{
+       free (test.foo);
+       free (test.bar);
+}
+
+static void
+test_parse (void)
+{
+       p11_argv_parse ("foo=foo bar=bar", on_argv_parsed, NULL);
+       assert_str_eq ("foo", test.foo);
+       assert_str_eq ("bar", test.bar);
+}
+
+static void
+test_parse_quote (void)
+{
+       p11_argv_parse ("foo='foo bar' bar=\"bar baz\"", on_argv_parsed, NULL);
+       assert_str_eq ("foo bar", test.foo);
+       assert_str_eq ("bar baz", test.bar);
+}
+
+static void
+test_parse_backslash (void)
+{
+       p11_argv_parse ("foo='\\this\\isn\\'t\\a\\path' bar=bar",
+                       on_argv_parsed, NULL);
+       assert_str_eq ("\\this\\isn't\\a\\path", test.foo);
+       assert_str_eq ("bar", test.bar);
+}
+
+int
+main (int argc,
+      char *argv[])
+{
+       p11_fixture (setup, teardown);
+       p11_test (test_parse, "/argv/parse");
+       p11_test (test_parse_quote, "/argv/parse_quote");
+       p11_test (test_parse_backslash, "/argv/parse_backslash");
+       return p11_test_run (argc, argv);
+}