You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.9 KiB
88 lines
2.9 KiB
#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;
|
|
} |