Update doc revision and pdf cover.
[apps/low-level-can-service.git] / CAN-binder / libs / nanopb / tests / fuzztest / fuzzstub.c
1 /* Fuzz testing for the nanopb core.
2  * This can be used with external fuzzers, e.g. radamsa.
3  * It performs most of the same checks as fuzztest, but does not feature data generation.
4  */
5
6 #include <pb_decode.h>
7 #include <pb_encode.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <assert.h>
12 #include <time.h>
13 #include <malloc_wrappers.h>
14 #include "alltypes_static.pb.h"
15 #include "alltypes_pointer.pb.h"
16
17 #define BUFSIZE 4096
18
19 static bool do_static_decode(uint8_t *buffer, size_t msglen, bool assert_success)
20 {
21     pb_istream_t stream;
22     bool status;
23     
24     alltypes_static_AllTypes *msg = malloc_with_check(sizeof(alltypes_static_AllTypes));
25     stream = pb_istream_from_buffer(buffer, msglen);
26     status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg);
27     
28     if (!status && assert_success)
29     {
30         /* Anything that was successfully encoded, should be decodeable.
31          * One exception: strings without null terminator are encoded up
32          * to end of buffer, but refused on decode because the terminator
33          * would not fit. */
34         if (strcmp(stream.errmsg, "string overflow") != 0)
35             assert(status);
36     }
37     
38     free_with_check(msg);
39     return status;
40 }
41
42 static bool do_pointer_decode(uint8_t *buffer, size_t msglen, bool assert_success)
43 {
44     pb_istream_t stream;
45     bool status;
46     alltypes_pointer_AllTypes *msg;
47     
48     msg = malloc_with_check(sizeof(alltypes_pointer_AllTypes));
49     memset(msg, 0, sizeof(alltypes_pointer_AllTypes));
50     stream = pb_istream_from_buffer(buffer, msglen);
51
52     assert(get_alloc_count() == 0);
53     status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg);
54     
55     if (assert_success)
56         assert(status);
57     
58     pb_release(alltypes_pointer_AllTypes_fields, msg);    
59     assert(get_alloc_count() == 0);
60     
61     free_with_check(msg);
62
63     return status;
64 }
65
66 /* Do a decode -> encode -> decode -> encode roundtrip */
67 static void do_static_roundtrip(uint8_t *buffer, size_t msglen)
68 {
69     bool status;
70     uint8_t *buf2 = malloc_with_check(BUFSIZE);
71     uint8_t *buf3 = malloc_with_check(BUFSIZE);
72     size_t msglen2, msglen3;
73     alltypes_static_AllTypes *msg1 = malloc_with_check(sizeof(alltypes_static_AllTypes));
74     alltypes_static_AllTypes *msg2 = malloc_with_check(sizeof(alltypes_static_AllTypes));
75     memset(msg1, 0, sizeof(alltypes_static_AllTypes));
76     memset(msg2, 0, sizeof(alltypes_static_AllTypes));
77     
78     {
79         pb_istream_t stream = pb_istream_from_buffer(buffer, msglen);
80         status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg1);
81         assert(status);
82     }
83     
84     {
85         pb_ostream_t stream = pb_ostream_from_buffer(buf2, BUFSIZE);
86         status = pb_encode(&stream, alltypes_static_AllTypes_fields, msg1);
87         assert(status);
88         msglen2 = stream.bytes_written;
89     }
90     
91     {
92         pb_istream_t stream = pb_istream_from_buffer(buf2, msglen2);
93         status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg2);
94         assert(status);
95     }
96     
97     {
98         pb_ostream_t stream = pb_ostream_from_buffer(buf3, BUFSIZE);
99         status = pb_encode(&stream, alltypes_static_AllTypes_fields, msg2);
100         assert(status);
101         msglen3 = stream.bytes_written;
102     }
103     
104     assert(msglen2 == msglen3);
105     assert(memcmp(buf2, buf3, msglen2) == 0);
106     
107     free_with_check(msg1);
108     free_with_check(msg2);
109     free_with_check(buf2);
110     free_with_check(buf3);
111 }
112
113 /* Do decode -> encode -> decode -> encode roundtrip */
114 static void do_pointer_roundtrip(uint8_t *buffer, size_t msglen)
115 {
116     bool status;
117     uint8_t *buf2 = malloc_with_check(BUFSIZE);
118     uint8_t *buf3 = malloc_with_check(BUFSIZE);
119     size_t msglen2, msglen3;
120     alltypes_pointer_AllTypes *msg1 = malloc_with_check(sizeof(alltypes_pointer_AllTypes));
121     alltypes_pointer_AllTypes *msg2 = malloc_with_check(sizeof(alltypes_pointer_AllTypes));
122     memset(msg1, 0, sizeof(alltypes_pointer_AllTypes));
123     memset(msg2, 0, sizeof(alltypes_pointer_AllTypes));
124     
125     {
126         pb_istream_t stream = pb_istream_from_buffer(buffer, msglen);
127         status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg1);
128         assert(status);
129     }
130     
131     {
132         pb_ostream_t stream = pb_ostream_from_buffer(buf2, BUFSIZE);
133         status = pb_encode(&stream, alltypes_pointer_AllTypes_fields, msg1);
134         assert(status);
135         msglen2 = stream.bytes_written;
136     }
137     
138     {
139         pb_istream_t stream = pb_istream_from_buffer(buf2, msglen2);
140         status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg2);
141         assert(status);
142     }
143     
144     {
145         pb_ostream_t stream = pb_ostream_from_buffer(buf3, BUFSIZE);
146         status = pb_encode(&stream, alltypes_pointer_AllTypes_fields, msg2);
147         assert(status);
148         msglen3 = stream.bytes_written;
149     }
150     
151     assert(msglen2 == msglen3);
152     assert(memcmp(buf2, buf3, msglen2) == 0);
153     
154     pb_release(alltypes_pointer_AllTypes_fields, msg1);
155     pb_release(alltypes_pointer_AllTypes_fields, msg2);
156     free_with_check(msg1);
157     free_with_check(msg2);
158     free_with_check(buf2);
159     free_with_check(buf3);
160 }
161
162 static void run_iteration()
163 {
164     uint8_t *buffer = malloc_with_check(BUFSIZE);
165     size_t msglen;
166     bool status;
167     
168     msglen = fread(buffer, 1, BUFSIZE, stdin);
169
170     status = do_static_decode(buffer, msglen, false);
171     
172     if (status)
173         do_static_roundtrip(buffer, msglen);
174     
175     status = do_pointer_decode(buffer, msglen, false);
176     
177     if (status)
178         do_pointer_roundtrip(buffer, msglen);
179     
180     free_with_check(buffer);
181 }
182
183 int main(int argc, char **argv)
184 {
185     run_iteration();
186     
187     return 0;
188 }
189