1 #include <stddef.h>
2 #include <stdint.h>
3
4 #include <errno.h>
5 #include <vector>
6
7 #include "system/camera_metadata.h"
8
9 #define OK 0
10
AlignUp(uint32_t num,uint32_t alignment)11 static inline uint32_t AlignUp(uint32_t num, uint32_t alignment) {
12 return (num + (alignment - 1)) & (~(alignment - 1));
13 }
14
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)15 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
16 const size_t sizeof_int = sizeof(uint32_t);
17 if (data == nullptr || size < 2 * sizeof_int) {
18 return 0;
19 }
20 camera_metadata_t *m = NULL;
21
22 // Use first int as capacity, and the following one as data capacity.
23 uint32_t entry_capacity = *reinterpret_cast<const uint32_t*>(data) % 0xFF;
24 uint32_t data_capacity = *reinterpret_cast<const uint32_t*>(data + sizeof_int) % 0xFFF;
25
26 m = allocate_camera_metadata(entry_capacity, data_capacity);
27
28 size_t i = 2 * sizeof_int;
29 std::vector<uint32_t> tags;
30 // Do we have at least 2 ints left?
31 while(i + (2 * sizeof_int) < size) {
32 // Use one int as tag Id, and the following one as data size.
33 // Note that i is already aligned at this point.
34 uint32_t tag = *reinterpret_cast<const uint32_t*>(data + i);
35 uint32_t data_count = *reinterpret_cast<const uint32_t*>(
36 data + i + sizeof_int) % 0xFF;
37
38 i += 2 * sizeof_int;
39
40 int32_t tag_type = get_camera_metadata_tag_type(tag);
41
42 // If the tag doesn't exists, just try to add it anyway to try that path,
43 // but skip the rest of the loop.
44 if (tag_type == -1) {
45 add_camera_metadata_entry(m, tag, data, data_count);
46 validate_camera_metadata_structure(m, NULL);
47 continue;
48 }
49
50 size_t tag_data_size = camera_metadata_type_size[tag_type] * data_count;
51
52 // Is there enough data left to consider this tag/size pair?
53 if (i + tag_data_size >= size) {
54 continue;
55 }
56
57 const void* tag_data = data + i;
58 // add then remove
59 add_camera_metadata_entry(m, tag, tag_data, data_count);
60 validate_camera_metadata_structure(m, NULL);
61 camera_metadata_ro_entry_t entry;
62 if (OK == find_camera_metadata_ro_entry(m, tag, &entry)) {
63 delete_camera_metadata_entry(m, entry.index);
64 validate_camera_metadata_structure(m, NULL);
65 }
66
67 // add back
68 add_camera_metadata_entry(m, tag, tag_data, data_count);
69 tags.push_back(tag);
70
71 get_camera_metadata_section_name(tag);
72 get_camera_metadata_tag_name(tag);
73 get_camera_metadata_tag_type(tag);
74
75 i += AlignUp(tag_data_size, sizeof_int);
76 }
77
78 for (auto tag: tags){
79 camera_metadata_ro_entry_t entry;
80 if (OK == find_camera_metadata_ro_entry(m, tag, &entry)) {
81 delete_camera_metadata_entry(m, entry.index);
82 validate_camera_metadata_structure(m, NULL);
83 }
84 }
85
86 free_camera_metadata(m);
87 return 0;
88 }