1 #include <assert.h>
2 #include <stdint.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <getopt.h>
7 #include "fuzz-emul.h"
8 
9 static uint8_t input[INPUT_SIZE];
10 
main(int argc,char ** argv)11 int main(int argc, char **argv)
12 {
13     size_t size;
14     FILE *fp = NULL;
15     int max, count;
16 
17     setbuf(stdin, NULL);
18     setbuf(stdout, NULL);
19 
20     while ( 1 )
21     {
22         enum {
23             OPT_MIN_SIZE,
24         };
25         static const struct option lopts[] = {
26             { "min-input-size", no_argument, NULL, OPT_MIN_SIZE },
27             { 0, 0, 0, 0 }
28         };
29         int c = getopt_long_only(argc, argv, "", lopts, NULL);
30 
31         if ( c == -1 )
32             break;
33 
34         switch ( c )
35         {
36         case OPT_MIN_SIZE:
37             printf("%u\n", fuzz_minimal_input_size());
38             exit(0);
39             break;
40 
41         case '?':
42             printf("Usage: %s $FILE [$FILE...] | [--min-input-size]\n", argv[0]);
43             exit(-1);
44             break;
45 
46         default:
47             printf("Bad getopt return %d (%c)\n", c, c);
48             exit(-1);
49             break;
50         }
51     }
52 
53     max = argc - optind;
54 
55     if ( !max ) /* No positional parameters.  Use stdin. */
56     {
57         max = 1;
58         fp = stdin;
59     }
60 
61     if ( LLVMFuzzerInitialize(&argc, &argv) )
62         exit(-1);
63 
64 #ifdef __AFL_HAVE_MANUAL_CONTROL
65     __AFL_INIT();
66 
67     for( count = 0; __AFL_LOOP(1000); )
68 #else
69     for( count = 0; count < max; count++ )
70 #endif
71     {
72         if ( fp != stdin ) /* If not using stdin, open the provided file. */
73         {
74             printf("Opening file %s\n", argv[optind + count]);
75             fp = fopen(argv[optind + count], "rb");
76             if ( fp == NULL )
77             {
78                 perror("fopen");
79                 exit(-1);
80             }
81         }
82 #ifdef __AFL_HAVE_MANUAL_CONTROL
83         else
84         {
85             /*
86              * This will ensure we're dealing with a clean stream
87              * state after the afl-fuzz process messes with the open
88              * file handle.
89              */
90             fseek(fp, 0, SEEK_SET);
91         }
92 #endif
93 
94         size = fread(input, 1, INPUT_SIZE, fp);
95 
96         if ( ferror(fp) )
97         {
98             perror("fread");
99             exit(-1);
100         }
101 
102         /* Only run the test if the input file was smaller than INPUT_SIZE */
103         if ( feof(fp) )
104         {
105             LLVMFuzzerTestOneInput(input, size);
106         }
107         else
108         {
109             printf("Input too large\n");
110             /* Don't exit if we're doing batch processing */
111             if ( max == 1 )
112                 exit(-1);
113         }
114 
115         if ( fp != stdin )
116         {
117             fclose(fp);
118             fp = NULL;
119         }
120     }
121 
122     return 0;
123 }
124 
125 /*
126  * Local variables:
127  * mode: C
128  * c-file-style: "BSD"
129  * c-basic-offset: 4
130  * indent-tabs-mode: nil
131  * End:
132  */
133