1 #include <sys/types.h>
2
3 #include <algorithm>
4 #include <cstddef>
5 #include <cstdint>
6 #include <cstdlib>
7
8 #include "ringbuffer.h"
9
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)10 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
11 if (Size < 2) {
12 return 0;
13 }
14
15 // Only allocate up to 1 << 16 bytes of memory. We shouldn't ever be
16 // exercising more than this.
17 uint16_t buffer_size = *((const uint16_t*)Data);
18 ringbuffer_t* buffer = ringbuffer_init(buffer_size);
19
20 if (buffer == nullptr) {
21 return 0;
22 }
23
24 for (size_t i = 2; i < Size;) {
25 size_t bytes_left = Size - i - 1;
26 switch (Data[i++] % 6) {
27 case 0: {
28 ringbuffer_available(buffer);
29 break;
30 }
31 case 1: {
32 ringbuffer_size(buffer);
33 break;
34 }
35 case 2: {
36 if (bytes_left < 2) {
37 break;
38 }
39
40 size_t bytes_to_insert = std::min(bytes_left - 1, (size_t)Data[i++]);
41 ringbuffer_insert(buffer, &Data[i], bytes_to_insert);
42 i += bytes_to_insert;
43 break;
44 }
45 case 3: {
46 if (bytes_left < 2) {
47 break;
48 }
49
50 size_t bytes_to_grab = Data[i++];
51 uint8_t* copy_buffer = (uint8_t*)malloc(bytes_to_grab);
52 off_t offset = 0;
53 if (ringbuffer_size(buffer) != 0) {
54 offset = Data[i++] % ringbuffer_size(buffer);
55 }
56
57 ringbuffer_peek(buffer, offset, copy_buffer, (size_t)bytes_to_grab);
58 free(copy_buffer);
59 break;
60 }
61 case 4: {
62 if (bytes_left < 1) {
63 break;
64 }
65
66 size_t bytes_to_grab = Data[i++];
67 uint8_t* copy_buffer = (uint8_t*)malloc(bytes_to_grab);
68 ringbuffer_pop(buffer, copy_buffer, bytes_to_grab);
69 free(copy_buffer);
70 break;
71 }
72 case 5: {
73 if (bytes_left < 1) {
74 break;
75 }
76 ringbuffer_delete(buffer, (size_t)Data[i++]);
77 }
78 }
79 }
80
81 ringbuffer_free(buffer);
82 return 0;
83 }
84