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 }