aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/fuzz/config.c
blob: 4877ba765f77601089b0dbe087be4102f9a6e3a3 (plain) (blame)
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
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2018-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 */

#include <stdio.h>
#undef stderr
#define stderr stdin
#include "../config.c"
#include "../encoding.c"
#undef stderr

#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "../config.h"

const char *__asan_default_options()
{
        return "verbosity=1";
}

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t len)
{
	bool file;
	char *input;

	if (len < 2)
		return 0;
	file = !!(data[0] >> 7);
	input = malloc(len);
	if (!input)
		return 0;
	memcpy(input, data + 1, len - 1);
	input[len - 1] = '\0';

	if (file) {
		struct config_ctx ctx;
		char *saveptr;

		config_read_init(&ctx, false);
		for (char *line = strtok_r(input, "\n", &saveptr); line; line = strtok_r(NULL, "\n", &saveptr)) {
			if (!config_read_line(&ctx, line))
				config_read_init(&ctx, false);
		}
		free_wgdevice(config_read_finish(&ctx));
	} else {
		size_t spaces = 0;
		char **argv, *saveptr;

		for (char *c = input; *c; ++c) {
			if (*c == ' ')
				++spaces;
		}
		argv = calloc(spaces + 1, sizeof(char *));
		if (!argv)
			goto out;
		spaces = 0;
		for (char *token = strtok_r(input, " ", &saveptr); token; token = strtok_r(NULL, " ", &saveptr))
			argv[spaces++] = token;
		free_wgdevice(config_read_cmd(argv, spaces));
		free(argv);
	}

out:
	free(input);
	return 0;
}