/src/r-oss-fuzz/harnesses/dcf.c
Line | Count | Source |
1 | | /* Exercise the parser used for DESCRIPTION and PACKAGES metadata. */ |
2 | | |
3 | | #include <stdint.h> |
4 | | #include <string.h> |
5 | | |
6 | | #include "common.h" |
7 | | |
8 | 53.8k | #define FUZZ_MAX_INPUT (1024 * 64) |
9 | | |
10 | | static SEXP input_string; |
11 | | static SEXP calls[2]; |
12 | | |
13 | | static SEXP make_wrapper(const char *source) |
14 | 2 | { |
15 | 2 | ParseStatus status; |
16 | 2 | SEXP text, parsed, wrapper; |
17 | 2 | Rf_protect(text = Rf_mkString(source)); |
18 | 2 | Rf_protect(parsed = R_ParseVector(text, -1, &status, R_NilValue)); |
19 | 2 | if (status != PARSE_OK || XLENGTH(parsed) != 1) |
20 | 0 | abort(); |
21 | 2 | wrapper = Rf_eval(VECTOR_ELT(parsed, 0), R_BaseEnv); |
22 | 2 | Rf_unprotect(2); |
23 | 2 | return wrapper; |
24 | 2 | } |
25 | | |
26 | | int LLVMFuzzerInitialize(int *argc, char ***argv) |
27 | 4 | { |
28 | 4 | (void)argc; |
29 | 4 | (void)argv; |
30 | 4 | fuzz_init_r(); |
31 | | |
32 | 4 | static const char source[] = |
33 | 4 | "function(x, all) { con <- textConnection(x); " |
34 | 4 | "on.exit(close(con)); read.dcf(con, all = all) }"; |
35 | 4 | SEXP wrapper, false_value, true_value; |
36 | 4 | Rf_protect(wrapper = make_wrapper(source)); |
37 | 4 | Rf_protect(input_string = Rf_allocVector(STRSXP, 1)); |
38 | 4 | Rf_protect(false_value = Rf_ScalarLogical(FALSE)); |
39 | 4 | Rf_protect(true_value = Rf_ScalarLogical(TRUE)); |
40 | 4 | Rf_protect(calls[0] = Rf_lang3(wrapper, input_string, false_value)); |
41 | 4 | Rf_protect(calls[1] = Rf_lang3(wrapper, input_string, true_value)); |
42 | 4 | return 0; |
43 | 4 | } |
44 | | |
45 | | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) |
46 | 26.9k | { |
47 | 26.9k | if (size < 2 || size > FUZZ_MAX_INPUT || memchr(data + 1, '\0', size - 1)) |
48 | 97 | return 0; |
49 | | |
50 | 26.8k | char buffer[FUZZ_MAX_INPUT]; |
51 | 26.8k | memcpy(buffer, data + 1, size - 1); |
52 | 26.8k | buffer[size - 1] = '\0'; |
53 | 26.8k | if (!fuzz_set_string(input_string, buffer)) |
54 | 0 | return 0; |
55 | | |
56 | 26.8k | fuzz_eval_silent(calls[data[0] & 1], R_GlobalEnv); |
57 | 26.8k | return 0; |
58 | 26.8k | } |