/src/r-oss-fuzz/harnesses/sprintf.c
Line | Count | Source |
1 | | /* Exercise R's C-style format-string parser and argument dispatch. */ |
2 | | |
3 | | #include <stdint.h> |
4 | | #include <string.h> |
5 | | |
6 | | #include "common.h" |
7 | | |
8 | 4.00k | #define FUZZ_MAX_INPUT (1024 * 16) |
9 | 1.98k | #define N_CALLS 4 |
10 | | |
11 | | static SEXP format; |
12 | | static SEXP calls[N_CALLS]; |
13 | | |
14 | | int LLVMFuzzerInitialize(int *argc, char ***argv) |
15 | 2 | { |
16 | 2 | (void)argc; |
17 | 2 | (void)argv; |
18 | 2 | fuzz_init_r(); |
19 | | |
20 | 2 | SEXP string, integer, real; |
21 | 2 | Rf_protect(format = Rf_allocVector(STRSXP, 1)); |
22 | 2 | Rf_protect(string = Rf_mkString("fuzz")); |
23 | 2 | Rf_protect(integer = Rf_ScalarInteger(-12345)); |
24 | 2 | Rf_protect(real = Rf_ScalarReal(3.141592653589793)); |
25 | | |
26 | 2 | SEXP sprintf = Rf_install("sprintf"); |
27 | 2 | Rf_protect(calls[0] = Rf_lang3(sprintf, format, string)); |
28 | 2 | Rf_protect(calls[1] = Rf_lang3(sprintf, format, integer)); |
29 | 2 | Rf_protect(calls[2] = Rf_lang3(sprintf, format, real)); |
30 | 2 | Rf_protect(calls[3] = Rf_lang5(sprintf, format, integer, real, string)); |
31 | 2 | SET_STRING_ELT(format, 0, Rf_mkChar("%s")); |
32 | 2 | return 0; |
33 | 2 | } |
34 | | |
35 | | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) |
36 | 2.00k | { |
37 | 2.00k | if (size < 2 || size > FUZZ_MAX_INPUT || memchr(data + 1, '\0', size - 1)) |
38 | 20 | return 0; |
39 | | |
40 | 1.98k | char buffer[FUZZ_MAX_INPUT]; |
41 | 1.98k | memcpy(buffer, data + 1, size - 1); |
42 | 1.98k | buffer[size - 1] = '\0'; |
43 | 1.98k | if (!fuzz_set_string(format, buffer)) |
44 | 0 | return 0; |
45 | | |
46 | 1.98k | fuzz_eval_silent(calls[data[0] % N_CALLS], R_GlobalEnv); |
47 | 1.98k | return 0; |
48 | 1.98k | } |