LCOV - code coverage report
Current view: top level - waltz/grpc - fuzz_grpc_h2_gen_req_hdr.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 7 17 41.2 %
Date: 2025-08-05 05:04:49 Functions: 1 2 50.0 %

          Line data    Source code
       1             : #if !FD_HAS_HOSTED
       2             : #error "This target requires FD_HAS_HOSTED"
       3             : #endif
       4             : 
       5             : #include <stdlib.h>
       6             : #include <stddef.h>
       7             : #include <string.h>
       8             : #include <stdio.h>
       9             : 
      10             : #include "fd_grpc_codec.h"
      11             : #include "../h2/fd_h2_rbuf.h"
      12             : 
      13             : int
      14             : LLVMFuzzerInitialize( int *argc,
      15          12 :                       char ***argv ) {
      16             :   /* Set up shell without signal handlers */
      17          12 :   putenv( "FD_LOG_BACKTRACE=0" );
      18          12 :   fd_boot( argc, argv );
      19          12 :   (void) atexit( fd_halt );
      20          12 :   fd_log_level_core_set( 1 ); /* crash on info log */
      21          12 :   return 0;
      22          12 : }
      23             : 
      24             : static void
      25             : expect_hdr( fd_hpack_rd_t *hpack_rd, fd_h2_hdr_t *hdr, uchar **scratch,
      26           0 :             const char *expected_name, const char *expected_value ) {
      27           0 :   FD_TEST( !fd_hpack_rd_done( hpack_rd ));
      28           0 :   FD_TEST( !fd_hpack_rd_next( hpack_rd, hdr, scratch, 0UL ));
      29           0 :   ulong name_len  = strlen( expected_name );
      30           0 :   ulong value_len = strlen( expected_value );
      31           0 :   FD_TEST( hdr->name_len==name_len );
      32           0 :   FD_TEST( fd_memeq( hdr->name, expected_name, name_len ));
      33           0 :   FD_TEST( hdr->value_len==value_len );
      34           0 :   FD_TEST( fd_memeq( hdr->value, expected_value, value_len ));
      35           0 : }
      36             : 
      37             : int
      38             : LLVMFuzzerTestOneInput( uchar const *data,
      39             :                         ulong size ) {
      40             :   char host[256], path[256], bearer_auth[256], version[256];
      41             :   char host_port[512], user_agent[512];
      42             :   ulong minimum_len = sizeof( ushort )+ // port
      43             :                       sizeof( char )+ // https
      44             :                       4UL; // lengths of strings
      45             :   if( FD_UNLIKELY( size < minimum_len )) {
      46             :     return 1;
      47             :   }
      48             :   ulong remaining = size-minimum_len;
      49             : 
      50             :   uchar host_len        = data[ 0 ];
      51             :   uchar path_len        = data[ 1 ];
      52             :   uchar bearer_auth_len = data[ 2 ];
      53             :   uchar version_len     = data[ 3 ];
      54             :   uchar https           = data[ 4 ];
      55             :   ushort port           = (ushort)(data[ 5 ] << 8 | data[ 6 ]);
      56             :   if( FD_UNLIKELY( (ulong)host_len+(ulong)path_len+(ulong)bearer_auth_len+(ulong)version_len>remaining )) {
      57             :     return 1;
      58             :   }
      59             :   const char *content = (const char *) (data+minimum_len);
      60             :   const char *p = content;
      61             : 
      62             :   strncpy( host, p, host_len );
      63             :   host[ host_len ] = '\0';
      64             :   p += host_len;
      65             : 
      66             :   strncpy( path, p, path_len );
      67             :   path[ path_len ] = '\0';
      68             :   p += path_len;
      69             : 
      70             :   strncpy( bearer_auth, p, bearer_auth_len );
      71             :   bearer_auth[ bearer_auth_len ] = '\0';
      72             :   p += bearer_auth_len;
      73             : 
      74             :   strncpy( version, p, version_len );
      75             :   version[ version_len ] = '\0';
      76             : 
      77             :   /* update length if there is a null byte in the middle */
      78             :   host_len = (uchar)strlen( host );
      79             :   path_len = (uchar)strlen( path );
      80             :   bearer_auth_len = (uchar)strlen( bearer_auth );
      81             :   version_len = (uchar)strlen( version );
      82             :   if( FD_UNLIKELY((host_len==0) | (path_len==0) | (bearer_auth_len==0) | (version_len==0))) {
      83             :     return 1;
      84             :   }
      85             : 
      86             :   snprintf( host_port, sizeof(host_port), "%s:%d", host, port );
      87             : 
      88             :   snprintf( user_agent, sizeof(user_agent), "grpc-firedancer/%s", version );
      89             : 
      90             :   fd_grpc_req_hdrs_t req = {
      91             :       .host            = host,
      92             :       .host_len        = host_len,
      93             :       .port            = port,
      94             :       .path            = path,
      95             :       .path_len        = path_len,
      96             :       .https           = (uint)https%2,
      97             :       .bearer_auth     = bearer_auth,
      98             :       .bearer_auth_len = bearer_auth_len,
      99             :   };
     100             :   uchar buf[2048];
     101             :   fd_h2_rbuf_t rbuf_tx[1];
     102             :   fd_h2_rbuf_init( rbuf_tx, buf, sizeof(buf));
     103             :   FD_TEST( fd_grpc_h2_gen_request_hdrs( &req, rbuf_tx, version, version_len ) == 1 );
     104             :   FD_TEST((rbuf_tx->lo_off == 0) & (rbuf_tx->lo == buf));
     105             : 
     106             :   fd_hpack_rd_t hpack_rd[1];
     107             :   fd_hpack_rd_init( hpack_rd, buf, rbuf_tx->hi_off );
     108             :   fd_h2_hdr_t hdr[1];
     109             :   uchar *scratch = NULL;
     110             :   expect_hdr( hpack_rd, hdr, &scratch, ":method", "POST" );
     111             :   expect_hdr( hpack_rd, hdr, &scratch, ":scheme", "https" );
     112             :   expect_hdr( hpack_rd, hdr, &scratch, ":path", path );
     113             :   expect_hdr( hpack_rd, hdr, &scratch, ":authority", host_port );
     114             :   expect_hdr( hpack_rd, hdr, &scratch, "te", "trailers" );
     115             :   expect_hdr( hpack_rd, hdr, &scratch, "content-type", "application/grpc+proto" );
     116             :   expect_hdr( hpack_rd, hdr, &scratch, "user-agent", user_agent );
     117             :   FD_TEST( !fd_hpack_rd_done( hpack_rd ));
     118             :   FD_TEST( !fd_hpack_rd_next( hpack_rd, hdr, &scratch, 0UL ));
     119             :   FD_TEST( hdr->name_len == 13 );
     120             :   FD_TEST( fd_memeq( hdr->name, "authorization", 13UL ));
     121             :   FD_TEST( hdr->value_len == 7+req.bearer_auth_len );
     122             :   FD_TEST( fd_memeq( hdr->value, "Bearer ", 7UL ));
     123             :   FD_TEST( fd_memeq( hdr->value+7, req.bearer_auth, req.bearer_auth_len ));
     124             :   FD_TEST( fd_hpack_rd_done( hpack_rd ));
     125             : 
     126             :   return 0;
     127             : }

Generated by: LCOV version 1.14