Coverage Report

Created: 2026-03-22 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pjsip/tests/fuzz/fuzz-presence.c
Line
Count
Source
1
#include <stdint.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#include <limits.h>
5
#include <pjsip.h>
6
#include <pjlib.h>
7
#include <pjsip-simple/pidf.h>
8
#include <pjsip-simple/xpidf.h>
9
#include <pjsip-simple/rpid.h>
10
#include <pjsip-simple/dialog_info.h>
11
#include <pjsip-simple/iscomposing.h>
12
13
3.31k
#define kMinInputLength 10
14
1.65k
#define kMaxInputLength 5120
15
16
static pj_caching_pool caching_pool;
17
static pj_pool_t *pool = NULL;
18
19
1.65k
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
20
1.65k
    char print_buf[2048];
21
1.65k
    pj_status_t status;
22
1.65k
    int doc_len;
23
24
1.65k
    if (Size < kMinInputLength || Size > kMaxInputLength) {
25
10
        return 0;
26
10
    }
27
28
1.64k
    status = pj_init();
29
1.64k
    if (status != PJ_SUCCESS) {
30
0
        return 0;
31
0
    }
32
33
1.64k
    pj_log_set_level(0);
34
1.64k
    pj_caching_pool_init(&caching_pool, &pj_pool_factory_default_policy, 0);
35
36
1.64k
    pool = pj_pool_create(&caching_pool.factory, "fuzz-presence", 4000, 4000, NULL);
37
1.64k
    if (!pool) {
38
0
        pj_caching_pool_destroy(&caching_pool);
39
0
        return 0;
40
0
    }
41
42
    /* Clamp size to INT_MAX to avoid truncation issues */
43
1.64k
    if (Size > INT_MAX) {
44
0
        Size = INT_MAX;
45
0
    }
46
1.64k
    doc_len = (int)Size;
47
48
1.64k
    char *doc = pj_pool_alloc(pool, Size + 1);
49
1.64k
    if (!doc) {
50
0
        pj_pool_release(pool);
51
0
        pj_caching_pool_destroy(&caching_pool);
52
0
        return 0;
53
0
    }
54
1.64k
    memcpy(doc, Data, Size);
55
1.64k
    doc[Size] = '\0';
56
57
    /* Test PIDF parser */
58
1.64k
    pjpidf_pres *pidf_pres = pjpidf_parse(pool, doc, doc_len);
59
1.64k
    if (pidf_pres) {
60
751
        pjpidf_print(pidf_pres, print_buf, sizeof(print_buf));
61
62
751
        pjpidf_tuple *tuple = pjpidf_pres_get_first_tuple(pidf_pres);
63
751
        if (tuple) {
64
            /* Call only safe accessor functions without assertions */
65
130
            pjpidf_tuple_get_contact(tuple);
66
130
            pjpidf_tuple_get_timestamp(tuple);
67
68
130
            pjpidf_note *note = pjpidf_tuple_get_first_note(tuple);
69
403
            while (note) {
70
273
                note = pjpidf_tuple_get_next_note(tuple, note);
71
273
            }
72
130
        }
73
74
751
        pjpidf_pres_get_first_note(pidf_pres);
75
76
        /* Test RPID within PIDF */
77
751
        pjrpid_element rpid_elem;
78
751
        if (pjrpid_get_element(pidf_pres, pool, &rpid_elem) == PJ_SUCCESS) {
79
287
            (void)rpid_elem.type;
80
287
            (void)rpid_elem.activity;
81
287
            if (rpid_elem.note.slen > 0) {
82
2
                (void)rpid_elem.note.ptr;
83
2
            }
84
287
        }
85
751
    }
86
87
    /* Test XPIDF parser */
88
1.64k
    pjxpidf_pres *xpidf_pres = pjxpidf_parse(pool, doc, (pj_size_t)Size);
89
1.64k
    if (xpidf_pres) {
90
35
        pjxpidf_print(xpidf_pres, print_buf, sizeof(print_buf));
91
35
        pjxpidf_get_uri(xpidf_pres);
92
35
        pjxpidf_get_status(xpidf_pres);
93
35
    }
94
95
    /* Test Dialog-Info parser */
96
1.64k
    pjsip_dlg_info_dialog *dlg_info = pjsip_dlg_info_parse(pool, doc, doc_len);
97
1.64k
    if (dlg_info) {
98
1
        pj_xml_attr *attr = dlg_info->attr_head.next;
99
1
        while (attr != &dlg_info->attr_head) {
100
0
            if (attr->name.slen > 0) (void)attr->name.ptr;
101
0
            if (attr->value.slen > 0) (void)attr->value.ptr;
102
0
            attr = attr->next;
103
0
        }
104
105
1
        pj_xml_node *child = dlg_info->node_head.next;
106
1
        while (child != (pj_xml_node*)&dlg_info->node_head) {
107
0
            if (child->name.slen > 0) (void)child->name.ptr;
108
0
            if (child->content.slen > 0) (void)child->content.ptr;
109
0
            child = child->next;
110
0
        }
111
1
    }
112
113
    /* Test Iscomposing parser */
114
1.64k
    pj_bool_t is_composing = PJ_FALSE;
115
1.64k
    pj_str_t *last_active = NULL;
116
1.64k
    pj_str_t *content_type = NULL;
117
1.64k
    int refresh = 0;
118
119
1.64k
    if (pjsip_iscomposing_parse(pool, doc, (pj_size_t)Size,
120
1.64k
                                &is_composing, &last_active,
121
1.64k
                                &content_type, &refresh) == PJ_SUCCESS) {
122
43
        (void)is_composing;
123
43
        (void)refresh;
124
43
        if (last_active && last_active->slen > 0) (void)last_active->ptr;
125
43
        if (content_type && content_type->slen > 0) (void)content_type->ptr;
126
43
    }
127
128
1.64k
    pj_pool_release(pool);
129
1.64k
    pj_caching_pool_destroy(&caching_pool);
130
1.64k
    return 0;
131
1.64k
}
132