#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "gr_api.h"
#define MAX_STR_LEN 128
#define MAX_FILE_NAME_LEN 64
#define MAX_BUF_LEN 1024
static gr_instance_handle g_inst = NULL;
static gr_vfs_handle g_vfs = {0};
static int g_inited = 0;
__attribute__((constructor))
static void fuzz_init() {
if (!g_inited) {
gr_create_inst("127.0.0.1:19225", &g_inst);
gr_vfs_create(g_inst, "fuzzdir", 0);
gr_vfs_mount(g_inst, "fuzzdir", &g_vfs);
g_inited = 1;
}
}
__attribute__((destructor))
static void fuzz_cleanup() {
if (g_inited) {
gr_vfs_unmount(&g_vfs);
gr_delete_inst(g_inst);
g_inst = NULL;
g_inited = 0;
}
}
static void make_safe_str(char *dst, const uint8_t *data, size_t size, size_t maxlen) {
size_t len = size > maxlen - 1 ? maxlen - 1 : size;
memcpy(dst, data, len);
dst[len] = '\0';
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 8 || g_inst == NULL) return 0;
uint8_t api_id = data[0] % 10;
size_t offset = 1;
char str1[MAX_STR_LEN] = {0};
char str2[MAX_STR_LEN] = {0};
char buf[MAX_BUF_LEN] = {0};
make_safe_str(str1, data + offset, size - offset, MAX_STR_LEN);
offset += MAX_STR_LEN / 2;
if (offset < size) {
make_safe_str(str2, data + offset, size - offset, MAX_STR_LEN);
offset += MAX_STR_LEN / 2;
}
char file_name[MAX_FILE_NAME_LEN] = {0};
if (offset < size) {
make_safe_str(file_name, data + offset, size - offset, MAX_FILE_NAME_LEN);
offset += MAX_FILE_NAME_LEN / 2;
}
switch (api_id) {
case 0:
gr_set_conf(g_inst, str1, str2);
break;
case 1:
gr_get_conf(g_inst, str1, buf);
break;
case 2:
gr_vfs_create(g_inst, str1, 0);
break;
case 3:
gr_vfs_mount(g_inst, str1, &g_vfs);
break;
case 4:
gr_file_create(g_vfs, file_name, NULL);
break;
case 5: {
gr_file_handle fh;
gr_file_open(g_vfs, file_name, 0, &fh);
gr_file_close(g_vfs, &fh, 0);
break;
}
case 6: {
gr_file_handle fh;
gr_file_open(g_vfs, file_name, 0, &fh);
gr_file_pwrite(g_vfs, &fh, buf, (offset < size ? data[offset] : 10), 0);
gr_file_close(g_vfs, &fh, 0);
break;
}
case 7: {
gr_file_handle fh;
gr_file_open(g_vfs, file_name, 0, &fh);
gr_file_pread(g_vfs, fh, buf, (offset < size ? data[offset] : 10), 0);
gr_file_close(g_vfs, &fh, 0);
break;
}
case 8:
gr_file_delete(g_vfs, file_name, 0);
break;
case 9: {
int file_num = 0;
gr_vfs_query_file_num(g_vfs, &file_num);
break;
}
default:
break;
}
return 0;
}