1 #include <libexif/exif-data.h>
2 #include <libexif/exif-loader.h>
3 #include <stddef.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 constexpr size_t kMaxDataSize = 32;
8
9 /* Extract all MakerNote tags */
mnote_dump(ExifData * data)10 static void mnote_dump(ExifData *data) {
11 ExifMnoteData *mn = exif_data_get_mnote_data(data);
12 if (mn) {
13 int num = exif_mnote_data_count(mn);
14
15 /* Loop through all MakerNote tags */
16 for (int i = 0; i < num; ++i) {
17 char buf[1024];
18 exif_mnote_data_get_value(mn, i, buf, sizeof(buf));
19 }
20 }
21 }
22
dump_value(ExifEntry * entry,void *)23 static void dump_value(ExifEntry *entry, void *) {
24 char buf[1024];
25 exif_entry_get_value(entry, buf, sizeof(buf));
26 }
27
data_func(ExifContent * content,void *)28 static void data_func(ExifContent *content, void *) {
29 exif_content_foreach_entry(content, dump_value, NULL);
30 }
31
32 /* This is like exif_data_dump but without writing to stdout */
data_dump(ExifData * data)33 static void data_dump(ExifData *data) {
34 exif_data_foreach_content(data, data_func, NULL);
35 }
36
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)37 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
38 if (!data) {
39 return 0;
40 }
41
42 size = (size % kMaxDataSize);
43 uint8_t *buffer = (uint8_t *)malloc(size * sizeof(uint8_t));
44 memcpy(buffer, data, size);
45 // Parse tags using (ultimately) exif_data_load_data()
46 auto image = exif_data_new_from_data(buffer, size);
47 if (image) {
48 // Exercise the EXIF tag manipulation code
49 exif_data_get_mnote_data(image);
50 data_dump(image);
51 mnote_dump(image);
52 unsigned char *buf;
53 unsigned int sz;
54 exif_data_save_data(image, &buf, &sz);
55 free(buf);
56 exif_data_fix(image);
57 exif_data_unref(image);
58 }
59
60 // Parse tags again, but using exif_loader_write(), which is a separate
61 // parser. There is no need to fuzz the parsed ExifData again, since it will
62 // be identical to what has been loaded (and fuzzed) above.
63 ExifLoader *loader = exif_loader_new();
64 if (!loader) {
65 free(buffer);
66 return 0;
67 }
68 exif_loader_write(loader, const_cast<unsigned char *>(buffer), size);
69 image = exif_loader_get_data(loader);
70 if (image) {
71 exif_data_unref(image);
72 }
73 exif_loader_unref(loader);
74 free(buffer);
75 return 0;
76 }
77