blob: 8550dbf044e3396296d1476bd46e09de66a349e0 [file] [log] [blame]
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
#include <vector>
#include "system/camera_metadata.h"
#define OK 0
static inline uint32_t AlignUp(uint32_t num, uint32_t alignment) {
return (num + (alignment - 1)) & (~(alignment - 1));
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
const size_t sizeof_int = sizeof(uint32_t);
if (data == nullptr || size < 2 * sizeof_int) {
return 0;
}
camera_metadata_t *m = NULL;
// Use first int as capacity, and the following one as data capacity.
uint32_t entry_capacity = *reinterpret_cast<const uint32_t*>(data) % 0xFF;
uint32_t data_capacity = *reinterpret_cast<const uint32_t*>(data + sizeof_int) % 0xFFF;
m = allocate_camera_metadata(entry_capacity, data_capacity);
size_t i = 2 * sizeof_int;
std::vector<uint32_t> tags;
// Do we have at least 2 ints left?
while(i + (2 * sizeof_int) < size) {
// Use one int as tag Id, and the following one as data size.
// Note that i is already aligned at this point.
uint32_t tag = *reinterpret_cast<const uint32_t*>(data + i);
uint32_t data_count = *reinterpret_cast<const uint32_t*>(
data + i + sizeof_int) % 0xFF;
i += 2 * sizeof_int;
int32_t tag_type = get_camera_metadata_tag_type(tag);
// If the tag doesn't exists, just try to add it anyway to try that path,
// but skip the rest of the loop.
if (tag_type == -1) {
add_camera_metadata_entry(m, tag, data, data_count);
validate_camera_metadata_structure(m, NULL);
continue;
}
size_t tag_data_size = camera_metadata_type_size[tag_type] * data_count;
// Is there enough data left to consider this tag/size pair?
if (i + tag_data_size >= size) {
continue;
}
const void* tag_data = data + i;
// add then remove
add_camera_metadata_entry(m, tag, tag_data, data_count);
validate_camera_metadata_structure(m, NULL);
camera_metadata_ro_entry_t entry;
if (OK == find_camera_metadata_ro_entry(m, tag, &entry)) {
delete_camera_metadata_entry(m, entry.index);
validate_camera_metadata_structure(m, NULL);
}
// add back
add_camera_metadata_entry(m, tag, tag_data, data_count);
tags.push_back(tag);
get_camera_metadata_section_name(tag);
get_camera_metadata_tag_name(tag);
get_camera_metadata_tag_type(tag);
i += AlignUp(tag_data_size, sizeof_int);
}
for (auto tag: tags){
camera_metadata_ro_entry_t entry;
if (OK == find_camera_metadata_ro_entry(m, tag, &entry)) {
delete_camera_metadata_entry(m, entry.index);
validate_camera_metadata_structure(m, NULL);
}
}
free_camera_metadata(m);
return 0;
}