84 lines
1.9 KiB
C++
84 lines
1.9 KiB
C++
#include <sys/types.h>
|
|
|
|
#include <algorithm>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <cstdlib>
|
|
|
|
#include "ringbuffer.h"
|
|
|
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
|
|
if (Size < 2) {
|
|
return 0;
|
|
}
|
|
|
|
// Only allocate up to 1 << 16 bytes of memory. We shouldn't ever be
|
|
// exercising more than this.
|
|
uint16_t buffer_size = *((const uint16_t*)Data);
|
|
ringbuffer_t* buffer = ringbuffer_init(buffer_size);
|
|
|
|
if (buffer == nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
for (size_t i = 2; i < Size;) {
|
|
size_t bytes_left = Size - i - 1;
|
|
switch (Data[i++] % 6) {
|
|
case 0: {
|
|
ringbuffer_available(buffer);
|
|
break;
|
|
}
|
|
case 1: {
|
|
ringbuffer_size(buffer);
|
|
break;
|
|
}
|
|
case 2: {
|
|
if (bytes_left < 2) {
|
|
break;
|
|
}
|
|
|
|
size_t bytes_to_insert = std::min(bytes_left - 1, (size_t)Data[i++]);
|
|
ringbuffer_insert(buffer, &Data[i], bytes_to_insert);
|
|
i += bytes_to_insert;
|
|
break;
|
|
}
|
|
case 3: {
|
|
if (bytes_left < 2) {
|
|
break;
|
|
}
|
|
|
|
size_t bytes_to_grab = Data[i++];
|
|
uint8_t* copy_buffer = (uint8_t*)malloc(bytes_to_grab);
|
|
off_t offset = 0;
|
|
if (ringbuffer_size(buffer) != 0) {
|
|
offset = Data[i++] % ringbuffer_size(buffer);
|
|
}
|
|
|
|
ringbuffer_peek(buffer, offset, copy_buffer, (size_t)bytes_to_grab);
|
|
free(copy_buffer);
|
|
break;
|
|
}
|
|
case 4: {
|
|
if (bytes_left < 1) {
|
|
break;
|
|
}
|
|
|
|
size_t bytes_to_grab = Data[i++];
|
|
uint8_t* copy_buffer = (uint8_t*)malloc(bytes_to_grab);
|
|
ringbuffer_pop(buffer, copy_buffer, bytes_to_grab);
|
|
free(copy_buffer);
|
|
break;
|
|
}
|
|
case 5: {
|
|
if (bytes_left < 1) {
|
|
break;
|
|
}
|
|
ringbuffer_delete(buffer, (size_t)Data[i++]);
|
|
}
|
|
}
|
|
}
|
|
|
|
ringbuffer_free(buffer);
|
|
return 0;
|
|
}
|