File: ssh-parse-t.c

package info (click to toggle)
remctl 3.18-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,612 kB
  • sloc: ansic: 19,504; sh: 5,386; perl: 1,778; java: 740; makefile: 715; xml: 502; python: 430
file content (135 lines) | stat: -rw-r--r-- 4,317 bytes parent folder | download | duplicates (5)
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;
}