• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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