From 9a1db7459e6952677ef0382ca277250de82243e1 Mon Sep 17 00:00:00 2001 From: Kuang-che Wu Date: Thu, 28 Oct 2021 16:57:54 +0800 Subject: [PATCH] Improve fuzz-conv fuzzer Input format - Less restriction on input length - Input text and charset no longer overlapped Performance - Less memory allocation - Less disk IO - Do not force GC. This make the fuzzer roughly 10x faster --- fuzz/fuzz-conv.c | 67 +++++++++++++----------------------------------- 1 file changed, 18 insertions(+), 49 deletions(-) diff --git a/fuzz/fuzz-conv.c b/fuzz/fuzz-conv.c index 9b5c261..fd76073 100644 --- a/fuzz/fuzz-conv.c +++ b/fuzz/fuzz-conv.c @@ -1,21 +1,9 @@ #include -#include #include -#include #include #include "wc.h" #include "wtf.h" -char *get_null_terminated(const uint8_t *data, size_t size) { - char *new_str = (char *)malloc(size+1); - if (new_str == NULL){ - exit(1); - } - memcpy(new_str, data, size); - new_str[size] = '\0'; - return new_str; -} - static void *die_oom(size_t bytes) { fprintf(stderr, "Out of memory: %lu bytes unavailable!\n", (unsigned long)bytes); exit(1); @@ -42,46 +30,27 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size){ init_done = 1; } - if (size < 30) { - return 0; - } - - GC_disable(); - - char *new_str1 = get_null_terminated(data, 20); - data += 20; size -= 20; - char *new_str2 = get_null_terminated(data, size); + /* Assume the data format is: + * \0 \0 + */ + const uint8_t *str1, *str2, *str3; + const uint8_t *p; + str1 = data; + p = memchr(str1, '\0', size); + if (p == NULL) return 0; + str2 = p + 1; + if (str2 >= data + size) return 0; + p = memchr(str2, '\0', data + size - str2); + if (p == NULL) return 0; + str3 = p + 1; wc_ces old, from, to; - from = wc_guess_charset_short(new_str1,0); - to = wc_guess_charset_short(new_str2, 0); + from = wc_guess_charset_short((char*)str1, 0); + to = wc_guess_charset_short((char*)str2, 0); - char filename[256]; - sprintf(filename, "/tmp/libfuzzer.%d", getpid()); - - FILE *fp = fopen(filename, "wb"); - if (fp) { - fwrite(data, size, 1, fp); - fclose(fp); - } - - FILE *f = fopen(filename, "r"); - if (f) { - Str s = Strfgetall(f); - wc_Str_conv_with_detect(s, &from, from, to); - if (s != NULL) { - Strfree(s); - } - fclose(f); - } - - unlink(filename); - - free(new_str1); - free(new_str2); - - GC_enable(); - GC_gcollect(); + Str s = Strnew_charp_n((char*)str3, data + size - str3); + wc_Str_conv_with_detect(s, &from, from, to); + Strfree(s); return 0; }