Coverage Report

Created: 2026-05-16 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libcoap/tests/oss-fuzz/block_check_target.c
Line
Count
Source
1
#include "coap3/coap_internal.h"
2
#include <stdint.h>
3
#include <string.h>
4
5
static int
6
18
fuzz_event_handler(coap_session_t *session, const coap_event_t event) {
7
18
  (void)session;
8
18
  (void)event;
9
18
  return 0;
10
18
}
11
12
static uint8_t test_data[4096];
13
14
int
15
36
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
16
36
  if (size < 20) {
17
8
    return 0;
18
8
  }
19
20
114k
  for (size_t i = 0; i < sizeof(test_data); i++) {
21
114k
    test_data[i] = (uint8_t)(i & 0xFF);
22
114k
  }
23
24
28
  coap_startup();
25
28
  coap_set_log_level(COAP_LOG_EMERG);
26
28
  coap_dtls_set_log_level(COAP_LOG_EMERG);
27
28
  coap_debug_set_packet_loss("50%");
28
28
  coap_debug_set_packet_fail("100%");
29
30
28
  coap_context_t *ctx = coap_new_context(NULL);
31
28
  if (!ctx) {
32
0
    return 0;
33
0
  }
34
28
  coap_register_event_handler(ctx, fuzz_event_handler);
35
36
28
  if (data[0] & 0x01) {
37
13
    ctx->block_mode |= COAP_BLOCK_USE_LIBCOAP;
38
13
  }
39
28
  if (data[0] & 0x04) {
40
11
    ctx->block_mode |= (COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_HAS_Q_BLOCK);
41
11
  }
42
43
28
  coap_address_t addr;
44
28
  coap_address_init(&addr);
45
28
  addr.addr.sa.sa_family = AF_INET;
46
47
28
  coap_endpoint_t *ep = coap_new_endpoint(ctx, &addr, COAP_PROTO_UDP);
48
28
  if (!ep) {
49
0
    coap_free_context(ctx);
50
0
    return 0;
51
0
  }
52
53
28
  coap_session_t *session = coap_new_client_session(ctx, NULL, &addr,
54
28
                                                    COAP_PROTO_UDP);
55
28
  if (!session) {
56
0
    coap_free_context(ctx);
57
0
    return 0;
58
0
  }
59
60
28
  coap_str_const_t *uri = coap_make_str_const("test");
61
28
  coap_resource_t *resource = coap_resource_init(uri, 0);
62
28
  if (resource) {
63
28
    coap_add_resource(ctx, resource);
64
28
  }
65
66
28
  unsigned int block_szx = (size > 1) ? (data[1] % 7) : 2;
67
28
  size_t data_len = ((data[2] % 32) + 1) * 64;
68
28
  if (data_len > sizeof(test_data)) {
69
0
    data_len = sizeof(test_data);
70
0
  }
71
28
  uint32_t block_num = (size > 4) ? (data[4] % 16) : 0;
72
73
  /* Populate lg_xmit so timeout functions iterate a non-empty list */
74
28
  {
75
28
    uint32_t saved_mode = session->block_mode;
76
28
    session->block_mode |= COAP_BLOCK_USE_LIBCOAP;
77
28
    coap_pdu_t *setup_pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_PUT,
78
28
                                          coap_new_message_id(session),
79
28
                                          coap_session_max_pdu_size(session));
80
28
    if (setup_pdu) {
81
28
      coap_add_option(setup_pdu, COAP_OPTION_URI_PATH, 4, (const uint8_t *)"test");
82
28
      coap_add_data_large_request_lkd(session, setup_pdu, sizeof(test_data),
83
28
                                      test_data, NULL, NULL);
84
28
      coap_delete_pdu(setup_pdu);
85
28
    }
86
28
    session->block_mode = saved_mode;
87
28
  }
88
89
28
  coap_tick_t now, tim_rem;
90
28
  coap_ticks(&now);
91
92
  /* Timeout handlers */
93
28
  coap_block_check_lg_xmit_timeouts(session, now, &tim_rem);
94
28
  coap_block_check_lg_crcv_timeouts(session, now, &tim_rem);
95
28
  coap_block_check_lg_srcv_timeouts(session, now, &tim_rem);
96
28
  coap_block_check_q_block1_xmit(session, now, &tim_rem);
97
28
  coap_block_check_q_block2_xmit(session, now, &tim_rem);
98
99
  /* Low-level block encoding */
100
28
  coap_pdu_t *pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_PUT,
101
28
                                  coap_new_message_id(session),
102
28
                                  coap_session_max_pdu_size(session));
103
28
  if (pdu) {
104
28
    coap_add_option(pdu, COAP_OPTION_URI_PATH, 4, (const uint8_t *)"test");
105
106
28
    if (coap_add_block(pdu, data_len, test_data, block_num, block_szx)) {
107
17
      coap_block_t block;
108
17
      memset(&block, 0, sizeof(block));
109
17
      block.num = block_num;
110
17
      block.szx = block_szx;
111
17
      block.m = (size > 5) ? (data[5] & 0x01) : 0;
112
17
      coap_write_block_opt(&block, COAP_OPTION_BLOCK1, pdu, data_len);
113
17
    }
114
115
28
    coap_block_t block_read;
116
28
    if (coap_get_block(pdu, COAP_OPTION_BLOCK1, &block_read)) {
117
17
      (void)block_read.num;
118
17
    }
119
28
    coap_delete_pdu(pdu);
120
28
  }
121
122
  /* BERT block encoding */
123
28
  pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_PUT,
124
28
                      coap_new_message_id(session),
125
28
                      coap_session_max_pdu_size(session));
126
28
  if (pdu) {
127
28
    coap_block_b_t block_b;
128
28
    memset(&block_b, 0, sizeof(block_b));
129
28
    block_b.num = (size > 6) ? (data[6] % 32) : 0;
130
28
    block_b.szx = block_szx;
131
28
    block_b.m = (size > 7) ? (data[7] & 0x01) : 0;
132
28
    block_b.aszx = block_szx;
133
28
    coap_write_block_b_opt(session, &block_b, COAP_OPTION_BLOCK1, pdu,
134
28
                           data_len);
135
136
28
    coap_pdu_t *resp = coap_pdu_init(COAP_MESSAGE_ACK, COAP_RESPONSE_CODE(205),
137
28
                                     coap_new_message_id(session), 1152);
138
28
    if (resp) {
139
28
      coap_add_block_b_data(resp, data_len, test_data, &block_b);
140
28
      coap_delete_pdu(resp);
141
28
    }
142
28
    coap_delete_pdu(pdu);
143
28
  }
144
145
  /* Large data transfer APIs */
146
28
  pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_GET,
147
28
                      coap_new_message_id(session),
148
28
                      coap_session_max_pdu_size(session));
149
28
  if (pdu && resource) {
150
28
    coap_add_option(pdu, COAP_OPTION_URI_PATH, 4, (const uint8_t *)"test");
151
152
28
    coap_pdu_t *resp = coap_pdu_init(COAP_MESSAGE_ACK, COAP_RESPONSE_CODE(205),
153
28
                                     coap_new_message_id(session),
154
28
                                     coap_session_max_pdu_size(session));
155
28
    if (resp) {
156
28
      coap_add_data_large_response(resource, session, pdu, resp,
157
28
                                   NULL, COAP_MEDIATYPE_TEXT_PLAIN, -1, 0,
158
28
                                   data_len, test_data, NULL, NULL);
159
160
28
      coap_pdu_t *resp2 = coap_pdu_init(COAP_MESSAGE_ACK,
161
28
                                        COAP_RESPONSE_CODE(205),
162
28
                                        coap_new_message_id(session), 1152);
163
28
      if (resp2) {
164
28
        coap_add_data_blocked_response(pdu, resp2, COAP_MEDIATYPE_TEXT_PLAIN,
165
28
                                       -1, data_len, test_data);
166
28
        coap_delete_pdu(resp2);
167
28
      }
168
28
      coap_delete_pdu(resp);
169
28
    }
170
28
    coap_delete_pdu(pdu);
171
28
  }
172
173
  /* Large request with lock */
174
28
  pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_PUT,
175
28
                      coap_new_message_id(session),
176
28
                      coap_session_max_pdu_size(session));
177
28
  if (pdu) {
178
28
    coap_add_option(pdu, COAP_OPTION_URI_PATH, 4, (const uint8_t *)"test");
179
28
    coap_add_data_large_request_lkd(session, pdu, data_len, test_data, NULL,
180
28
                                    NULL);
181
28
    coap_delete_pdu(pdu);
182
28
  }
183
184
  /* Q-Block support check */
185
28
  (void)coap_q_block_is_supported();
186
187
  /* Observe cancellation */
188
28
  pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_GET,
189
28
                      coap_new_message_id(session),
190
28
                      coap_session_max_pdu_size(session));
191
28
  if (pdu) {
192
28
    coap_add_option(pdu, COAP_OPTION_OBSERVE, 0, NULL);
193
194
28
    uint8_t token_buf[8];
195
28
    coap_binary_t token;
196
28
    token.length = (size > 8) ? ((data[8] % 8) + 1) : 1;
197
28
    if (token.length > sizeof(token_buf)) {
198
0
      token.length = sizeof(token_buf);
199
0
    }
200
28
    memcpy(token_buf, (size > 16) ? (data + 12) : data, token.length);
201
28
    token.s = token_buf;
202
203
28
    coap_cancel_observe(session, &token, COAP_MESSAGE_CON);
204
28
    coap_cancel_observe_lkd(session, &token, COAP_MESSAGE_CON);
205
28
    coap_delete_pdu(pdu);
206
28
  }
207
208
  /* Lifecycle cleanup */
209
28
  coap_block_delete_lg_crcv(session, NULL);
210
28
  coap_block_delete_lg_xmit(session, NULL);
211
28
  coap_register_block_data_handler(ctx, NULL);
212
213
28
  coap_io_process(ctx, 1);
214
28
  coap_free_context(ctx);
215
28
  coap_cleanup();
216
217
28
  return 0;
218
28
}