1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
/*
* Test suite for ssh command parsing.
*
* Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2016 Dropbox, Inc.
*
* SPDX-License-Identifier: MIT
*/
#include <config.h>
#include <portable/system.h>
#include <server/internal.h>
#include <tests/tap/basic.h>
#include <tests/tap/messages.h>
#include <util/messages.h>
/*
* Check a struct iovec against a string.
*/
static bool __attribute__((__format__(printf, 3, 4)))
is_iovec_string(const char *wanted, const struct iovec *seen,
const char *format, ...)
{
size_t length;
bool success;
va_list args;
length = strlen(wanted);
if (length != seen->iov_len)
success = false;
else
success = (memcmp(wanted, seen->iov_base, length) == 0);
if (!success) {
diag("wanted: %s", wanted);
diag(" seen: %.*s", (int) seen->iov_len,
(const char *) seen->iov_base);
}
va_start(args, format);
okv(success, format, args);
va_end(args);
return success;
}
int
main(void)
{
struct iovec **argv;
plan(29);
/* Simple argument parse. */
argv = server_ssh_parse_command("foo bar baz");
is_iovec_string("foo", argv[0], "simple word 1");
is_iovec_string("bar", argv[1], "simple word 2");
is_iovec_string("baz", argv[2], "simple word 3");
ok(argv[3] == NULL, "simple length");
server_free_command(argv);
/* Extra whitespace. */
argv = server_ssh_parse_command(" foo\tbar \t ");
is_iovec_string("foo", argv[0], "extra whitespace word 1");
is_iovec_string("bar", argv[1], "extra whitespace word 2");
ok(argv[2] == NULL, "extra whitespace length");
server_free_command(argv);
/* Double quotes. */
argv = server_ssh_parse_command("\"one argument\"");
is_iovec_string("one argument", argv[0], "double quotes word 1");
ok(argv[1] == NULL, "double quotes length");
server_free_command(argv);
/* Single quotes. */
argv = server_ssh_parse_command(" 'one \"argument' ");
is_iovec_string("one \"argument", argv[0], "single quotes word 1");
ok(argv[1] == NULL, "single quotes length");
server_free_command(argv);
/* Mixed quotes. */
argv = server_ssh_parse_command(" one'two\" three '\"four '\" ' '");
is_iovec_string("onetwo\" three four '", argv[0], "mixed quotes word 1");
is_iovec_string(" ", argv[1], "mixed quotes word 2");
ok(argv[2] == NULL, "mixed quotes length");
server_free_command(argv);
/* Empty arguments. */
argv = server_ssh_parse_command(" '' \"\" ");
is_iovec_string("", argv[0], "empty arguments word 1");
is_iovec_string("", argv[1], "empty arguments word 2");
ok(argv[2] == NULL, "empty arguments length");
server_free_command(argv);
/* Backslashes. */
argv = server_ssh_parse_command("\"foo\\\" bar\" \\'baz");
is_iovec_string("foo\" bar", argv[0], "backslashes word 1");
is_iovec_string("'baz", argv[1], "backslashes word 2");
ok(argv[2] == NULL, "backslashes length");
server_free_command(argv);
/* More backslashes. */
argv = server_ssh_parse_command(" '\\f\\o\\o\\ \\\' bar' \\ foo\\\\");
is_iovec_string("foo ' bar", argv[0], "more backslashes word 1");
is_iovec_string(" foo\\", argv[1], "more backslashes word 2");
ok(argv[2] == NULL, "more backslashes length");
server_free_command(argv);
/* Trailing backslash. */
argv = server_ssh_parse_command("trailing\\");
is_iovec_string("trailing\\", argv[0], "trailing backslash word 1");
ok(argv[1] == NULL, "trailing backslash length");
server_free_command(argv);
/* Unterminated double quote. */
errors_capture();
argv = server_ssh_parse_command(" foo \"bar");
ok(argv == NULL, "unterminated double quote return");
is_string(errors, "unterminated \" quote in command\n",
"unterminated double quote error");
errors_uncapture();
/* Unterminated single quote. */
errors_capture();
argv = server_ssh_parse_command("' foo \" bar baz ");
ok(argv == NULL, "unterminated single quote return");
is_string(errors, "unterminated ' quote in command\n",
"unterminated single quote error");
errors_uncapture();
free(errors);
errors = NULL;
message_handlers_reset();
return 0;
}
|