Coverage Report

Created: 2026-06-30 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libcoap/tests/oss-fuzz/observe_target.c
Line
Count
Source
1
#include "coap3/coap_internal.h"
2
#include "coap_fuzz_helper.h"
3
#include <stdint.h>
4
#include <string.h>
5
6
static int
7
16
fuzz_event_handler(coap_session_t *session, const coap_event_t event) {
8
16
  (void)session;
9
16
  (void)event;
10
16
  return 0;
11
16
}
12
13
static void
14
fuzz_handler(coap_resource_t *resource, coap_session_t *session,
15
             const coap_pdu_t *request, const coap_string_t *query,
16
172
             coap_pdu_t *response) {
17
172
  (void)resource;
18
172
  (void)session;
19
172
  (void)request;
20
172
  (void)query;
21
172
  response->code = COAP_RESPONSE_CODE(205);
22
172
}
23
24
int
25
34
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
26
34
  if (size < 1)
27
0
    return 0;
28
29
34
  coap_startup();
30
34
  coap_set_log_level(COAP_LOG_EMERG);
31
34
  coap_debug_set_packet_loss("50%");
32
34
  coap_debug_set_packet_fail("100%");
33
34
34
  coap_context_t *ctx = coap_new_context(NULL);
35
34
  if (!ctx)
36
0
    goto cleanup;
37
34
  coap_register_event_handler(ctx, fuzz_event_handler);
38
39
34
  coap_resource_t *res = coap_resource_init(coap_make_str_const("obs"), 0);
40
34
  if (!res)
41
0
    goto cleanup;
42
34
  res->observable = 1;
43
34
  coap_register_request_handler(res, COAP_REQUEST_GET, fuzz_handler);
44
34
  coap_add_resource(ctx, res);
45
46
34
  coap_address_t addr;
47
34
  coap_address_init(&addr);
48
34
  addr.addr.sa.sa_family = AF_INET;
49
34
  coap_session_t *sess = coap_new_client_session(ctx, NULL, &addr, COAP_PROTO_UDP);
50
34
  if (!sess)
51
0
    goto cleanup;
52
34
  sess->state = COAP_SESSION_STATE_ESTABLISHED;
53
54
  /* Test observer functions with fuzzed data */
55
34
  size_t offset = 0;
56
34
  int iterations = 0;
57
131
  while (offset + 1 < size && iterations++ < 5) {
58
97
    coap_pdu_t *pdu = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_GET, 1, 128);
59
97
    if (!pdu)
60
0
      break;
61
62
    /* Fuzzed token */
63
97
    size_t tok_len = (data[offset] % 8) + 1;
64
97
    if (offset + tok_len < size) {
65
93
      coap_add_token(pdu, tok_len, data + offset);
66
93
      offset += tok_len;
67
93
    }
68
69
    /* Add Observe option */
70
97
    uint8_t obs_val = 0;
71
97
    coap_insert_option(pdu, COAP_OPTION_OBSERVE, 1, &obs_val);
72
97
    coap_add_option(pdu, COAP_OPTION_URI_PATH, 3, (const uint8_t *)"obs");
73
74
    /* Test coap_add_observer */
75
97
    coap_lock_lock(goto cleanup);
76
97
    coap_subscription_t *sub = coap_add_observer(res, sess, &pdu->actual_token, pdu);
77
97
    coap_lock_unlock();
78
79
97
    if (sub) {
80
      /* Test coap_find_observer */
81
97
      coap_find_observer(res, sess, &pdu->actual_token);
82
83
      /* Test coap_touch_observer */
84
97
      coap_touch_observer(ctx, sess, &pdu->actual_token);
85
86
      /* Test coap_resource_notify_observers*/
87
97
      coap_resource_notify_observers(res, NULL);
88
89
      /* Test coap_delete_observer */
90
97
      coap_lock_lock(goto cleanup);
91
97
      coap_delete_observer(res, sess, &pdu->actual_token);
92
97
      coap_lock_unlock();
93
97
    }
94
95
97
    coap_delete_pdu(pdu);
96
97
    offset += 8;
97
97
  }
98
99
  /* Dispatch GET+OBSERVE to exercise subscription paths in handle_request */
100
34
  {
101
34
    uint8_t obs_val;
102
102
    for (obs_val = 0; obs_val <= 1; obs_val++) {
103
68
      coap_pdu_t *op = coap_pdu_init(COAP_MESSAGE_CON, COAP_REQUEST_CODE_GET,
104
68
                                     coap_new_message_id(sess), 128);
105
68
      if (op) {
106
68
        coap_add_option(op, COAP_OPTION_OBSERVE, 1, &obs_val);
107
68
        coap_add_option(op, COAP_OPTION_URI_PATH, 3, (const uint8_t *)"obs");
108
68
        coap_lock_lock(goto cleanup);
109
68
        coap_dispatch(ctx, sess, op);
110
68
        coap_lock_unlock();
111
68
        coap_delete_pdu(op);
112
68
      }
113
68
    }
114
34
  }
115
116
  /* Dispatch with programmatic PDU and raw wire format */
117
34
  coap_fuzz_dispatch(ctx, sess, data, size, (const uint8_t *)"obs", 3);
118
119
34
cleanup:
120
34
  if (ctx)
121
34
    coap_free_context(ctx);
122
34
  coap_cleanup();
123
34
  return 0;
124
34
}