diff options
author | Daiki Ueno <dueno@redhat.com> | 2017-02-15 17:23:18 +0100 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2017-02-16 12:54:59 +0100 |
commit | b16500f93407aef72445b03c1ee96c6768917906 (patch) | |
tree | 54effdf021b27edd6a7df0fc3a4f99753ed21ddb /common | |
parent | 873d391fa5015e8c5c82457a0641ed5bb1e2b7e3 (diff) |
argv: Fix misinterpretation of backslash in quotes
Don't append the backslash character twice to the output. It is
interpolated a few lines below, if it is really required.
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile.am | 4 | ||||
-rw-r--r-- | common/argv.c | 2 | ||||
-rw-r--r-- | common/test-argv.c | 114 |
3 files changed, 119 insertions, 1 deletions
diff --git a/common/Makefile.am b/common/Makefile.am index b053ec0..9265f5a 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -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) diff --git a/common/argv.c b/common/argv.c index 6d91bfa..541730c 100644 --- a/common/argv.c +++ b/common/argv.c @@ -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 index 0000000..7eeddde --- /dev/null +++ b/common/test-argv.c @@ -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); +} |