LCOV - code coverage report
Current view: top level - fuzztest - generate_message.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 31 33 93.9 %
Date: 2023-02-14 20:10:26 Functions: 3 3 100.0 %

          Line data    Source code
       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             :  */
      22          25 : static void limit_sizes(alltypes_static_AllTypes *msg)
      23             : {
      24             :     pb_field_iter_t iter;
      25          25 :     pb_field_iter_begin(&iter, alltypes_static_AllTypes_fields, msg);
      26        1700 :     while (pb_field_iter_next(&iter))
      27             :     {
      28        1675 :         if (PB_LTYPE(iter.type) == PB_LTYPE_BYTES)
      29             :         {
      30          75 :             ((pb_bytes_array_t*)iter.pData)->size %= iter.data_size - PB_BYTES_ARRAY_T_ALLOCSIZE(0);
      31             :         }
      32             :         
      33        1675 :         if (PB_HTYPE(iter.type) == PB_HTYPE_REPEATED)
      34             :         {
      35         525 :             *((pb_size_t*)iter.pSize) %= iter.array_size;
      36             :         }
      37             :         
      38        1675 :         if (PB_HTYPE(iter.type) == PB_HTYPE_ONEOF)
      39             :         {
      40             :             /* Set the oneof to this message type with 50% chance. */
      41          75 :             if (rand_word() & 1)
      42             :             {
      43          34 :                 *((pb_size_t*)iter.pSize) = iter.tag;
      44             :             }
      45             :         }
      46             :     }
      47          25 : }
      48             : 
      49           1 : static void generate_message()
      50             : {
      51             :     alltypes_static_AllTypes msg;
      52           1 :     alltypes_static_TestExtension extmsg = alltypes_static_TestExtension_init_zero;
      53           1 :     pb_extension_t ext = pb_extension_init_zero;
      54             : 
      55             :     static uint8_t buf[FUZZTEST_BUFSIZE];
      56           1 :     pb_ostream_t stream = {0};
      57             :     
      58             :     do {
      59          25 :         rand_fill((void*)&msg, sizeof(msg));
      60          25 :         limit_sizes(&msg);
      61             : 
      62          25 :         rand_fill((void*)&extmsg, sizeof(extmsg));
      63          25 :         ext.type = &alltypes_static_TestExtension_testextension;
      64          25 :         ext.dest = &extmsg;
      65          25 :         ext.next = NULL;
      66          25 :         msg.extensions = &ext;
      67             : 
      68          25 :         stream = pb_ostream_from_buffer(buf, sizeof(buf));
      69          25 :     } while (!pb_encode(&stream, alltypes_static_AllTypes_fields, &msg));
      70             :     
      71           1 :     fwrite(buf, 1, stream.bytes_written, stdout);
      72           1 : }
      73             : 
      74           1 : int main(int argc, char **argv)
      75             : {
      76           1 :     if (argc < 2)
      77             :     {
      78           0 :         fprintf(stderr, "Usage: generate_message <seed>\n");
      79           0 :         return 1;
      80             :     }
      81             : 
      82           1 :     random_set_seed(atol(argv[1]));
      83             : 
      84           1 :     generate_message();
      85             :     
      86           1 :     return 0;
      87             : }
      88             : 

Generated by: LCOV version 1.14