MOS Source Code
Loading...
Searching...
No Matches
generate_message.c
Go to the documentation of this file.
1/* Generates a random, valid protobuf message. Useful to seed
2 * external fuzzers such as afl-fuzz.
3 */
4
5#include <pb_encode.h>
6#include <pb_common.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <assert.h>
11#include "alltypes_static.pb.h"
12#include "random_data.h"
13
14#ifndef FUZZTEST_BUFSIZE
15#define FUZZTEST_BUFSIZE 4096
16#endif
17
18/* Check that size/count fields do not exceed their max size.
19 * Otherwise we would have to loop pretty long in generate_message().
20 * Note that there may still be a few encoding errors from submessages.
21 */
22static void limit_sizes(alltypes_static_AllTypes *msg)
23{
24 pb_field_iter_t iter;
25 pb_field_iter_begin(&iter, alltypes_static_AllTypes_fields, msg);
26 while (pb_field_iter_next(&iter))
27 {
28 if (PB_LTYPE(iter.type) == PB_LTYPE_BYTES)
29 {
30 ((pb_bytes_array_t*)iter.pData)->size %= iter.data_size - PB_BYTES_ARRAY_T_ALLOCSIZE(0);
31 }
32
33 if (PB_HTYPE(iter.type) == PB_HTYPE_REPEATED)
34 {
35 *((pb_size_t*)iter.pSize) %= iter.array_size;
36 }
37
38 if (PB_HTYPE(iter.type) == PB_HTYPE_ONEOF)
39 {
40 /* Set the oneof to this message type with 50% chance. */
41 if (rand_word() & 1)
42 {
43 *((pb_size_t*)iter.pSize) = iter.tag;
44 }
45 }
46 }
47}
48
49static void generate_message()
50{
51 alltypes_static_AllTypes msg;
52 alltypes_static_TestExtension extmsg = alltypes_static_TestExtension_init_zero;
53 pb_extension_t ext = pb_extension_init_zero;
54
55 static uint8_t buf[FUZZTEST_BUFSIZE];
56 pb_ostream_t stream = {0};
57
58 do {
59 rand_fill((void*)&msg, sizeof(msg));
60 limit_sizes(&msg);
61
62 rand_fill((void*)&extmsg, sizeof(extmsg));
63 ext.type = &alltypes_static_TestExtension_testextension;
64 ext.dest = &extmsg;
65 ext.next = NULL;
66 msg.extensions = &ext;
67
68 stream = pb_ostream_from_buffer(buf, sizeof(buf));
69 } while (!pb_encode(&stream, alltypes_static_AllTypes_fields, &msg));
70
71 fwrite(buf, 1, stream.bytes_written, stdout);
72}
73
74int main(int argc, char **argv)
75{
76 if (argc < 2)
77 {
78 fprintf(stderr, "Usage: generate_message <seed>\n");
79 return 1;
80 }
81
82 random_set_seed(atol(argv[1]));
83
85
86 return 0;
87}
88
static void limit_sizes(alltypes_static_AllTypes *msg)
static void generate_message()
#define FUZZTEST_BUFSIZE
#define stdout
Definition mos_stdio.h:31
#define stderr
Definition mos_stdio.h:32
size_t fwrite(const void *__restrict ptr, size_t size, size_t nmemb, FILE *__restrict stream)
const char ** argv
Definition kmain.c:44
size_t argc
Definition kmain.c:43
#define PB_HTYPE(x)
Definition pb.h:298
uint_least16_t pb_size_t
Definition pb.h:310
#define PB_BYTES_ARRAY_T_ALLOCSIZE(n)
Definition pb.h:377
#define PB_HTYPE_ONEOF
Definition pb.h:287
#define PB_LTYPE(x)
Definition pb.h:299
#define PB_HTYPE_REPEATED
Definition pb.h:285
#define PB_LTYPE_BYTES
Definition pb.h:251
#define pb_extension_init_zero
Definition pb.h:477
bool pb_field_iter_next(pb_field_iter_t *iter)
Definition pb_common.c:188
bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, void *message)
Definition pb_common.c:156
pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize)
Definition pb_encode.c:63
bool pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct)
Definition pb_encode.c:512
#define NULL
Definition pb_syshdr.h:46
unsigned char uint8_t
Definition pb_syshdr.h:20
void random_set_seed(uint32_t seed)
Definition random_data.c:10
void rand_fill(uint8_t *buf, size_t count)
Definition random_data.c:78
uint32_t rand_word()
Definition random_data.c:22
int main()
Definition simple.cpp:6