1 #include <cstdint>
2 #include <cstdio>
3 #include <cstdlib>
4 #include <unordered_map>
5
6 #include "cbor.h"
7
8 static size_t allocated_mem = 0;
9 static std::unordered_map<void*, size_t> allocated_len_map;
10 static constexpr size_t kMemoryLimit = 1 << 30;
11
limited_malloc(size_t size)12 void *limited_malloc(size_t size) {
13 if (size + allocated_mem > kMemoryLimit) {
14 return nullptr;
15 }
16 if (size == 0) {
17 return nullptr;
18 }
19 void* m = malloc(size);
20 if (m != nullptr) {
21 allocated_mem += size;
22 allocated_len_map[m] = size;
23 }
24 return m;
25 }
26
limited_free(void * ptr)27 void limited_free(void *ptr) {
28 if (ptr != NULL && allocated_len_map.find(ptr) == allocated_len_map.end()) {
29 abort();
30 }
31 free(ptr);
32 if (ptr != NULL) {
33 allocated_mem -= allocated_len_map[ptr];
34 allocated_len_map.erase(ptr);
35 }
36 }
37
limited_realloc(void * ptr,size_t size)38 void *limited_realloc(void *ptr, size_t size) {
39 if (ptr != NULL && allocated_len_map.find(ptr) == allocated_len_map.end()) {
40 abort();
41 }
42 if (ptr == NULL) {
43 return limited_malloc(size);
44 }
45 long delta = (long) size - allocated_len_map[ptr];
46 if (delta + allocated_mem > kMemoryLimit) {
47 return nullptr;
48 }
49 void* new_ptr = realloc(ptr, size);
50 if (size > 0 && new_ptr == nullptr) {
51 return nullptr;
52 }
53 allocated_mem += delta;
54 allocated_len_map.erase(ptr);
55 if (size > 0) {
56 allocated_len_map[new_ptr] = size;
57 }
58 return new_ptr;
59 }
60
61 struct State {
62 FILE* fout;
63
StateState64 State() : fout(fopen("/dev/null", "r")) {
65 cbor_set_allocs(limited_malloc, limited_realloc, limited_free);
66 }
67 };
68
69 static State kState;
70
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)71 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
72 cbor_load_result result;
73 cbor_item_t *item = cbor_load(Data, Size, &result);
74 if (result.error.code == CBOR_ERR_NONE) {
75 cbor_describe(item, kState.fout);
76 unsigned char *buffer;
77 size_t buffer_size;
78 cbor_serialize_alloc(item, &buffer, &buffer_size);
79 free(buffer);
80 cbor_item_t *copied = cbor_copy(item);
81 cbor_decref(&copied);
82 cbor_decref(&item);
83 }
84 return 0;
85 }
86