Coverage Report

Created: 2026-03-02 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nanopb/tests/build/fuzztest/validation.c
Line
Count
Source
1
#include "validation.h"
2
#include "malloc_wrappers.h"
3
#include <pb_common.h>
4
#include <assert.h>
5
6
void validate_static(pb_field_iter_t *iter)
7
844k
{
8
844k
    pb_size_t count = 1;
9
844k
    pb_size_t i;
10
844k
    bool truebool = true;
11
844k
    bool falsebool = false;
12
13
844k
    if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED && iter->pSize)
14
217k
    {
15
        /* Array count must be between 0 and statically allocated size */
16
217k
        count = *(pb_size_t*)iter->pSize;
17
217k
        assert(count <= iter->array_size);
18
217k
    }
19
626k
    else if (PB_HTYPE(iter->type) == PB_HTYPE_OPTIONAL && iter->pSize)
20
134k
    {
21
        /* Boolean has_ field must have a valid value */
22
134k
        assert(memcmp(iter->pSize, &truebool, sizeof(bool)) == 0 ||
23
134k
               memcmp(iter->pSize, &falsebool, sizeof(bool)) == 0);
24
134k
    }
25
491k
    else if (PB_HTYPE(iter->type) == PB_HTYPE_ONEOF)
26
46.8k
    {
27
46.8k
        if (*(pb_size_t*)iter->pSize != iter->tag)
28
43.9k
        {
29
            /* Some different field in oneof */
30
43.9k
            return;
31
43.9k
        }
32
46.8k
    }
33
34
1.50M
    for (i = 0; i < count; i++)
35
705k
    {
36
705k
        void *pData = (char*)iter->pData + iter->data_size * i;
37
38
705k
        if (PB_LTYPE(iter->type) == PB_LTYPE_STRING)
39
45.5k
        {
40
            /* String length must be at most statically allocated size */
41
45.5k
            assert(strlen(pData) + 1 <= iter->data_size);
42
45.5k
        }
43
660k
        else if (PB_LTYPE(iter->type) == PB_LTYPE_BYTES)
44
19.8k
        {
45
            /* Bytes length must be at most statically allocated size */
46
19.8k
            pb_bytes_array_t *bytes = pData;
47
19.8k
            assert(PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) <= iter->data_size);
48
19.8k
        }
49
640k
        else if (PB_LTYPE(iter->type) == PB_LTYPE_BOOL)
50
19.6k
        {
51
            /* Bool fields must have valid value */
52
19.6k
            assert(memcmp(pData, &truebool, sizeof(bool)) == 0 ||
53
19.6k
                   memcmp(pData, &falsebool, sizeof(bool)) == 0);
54
19.6k
        }
55
620k
        else if (PB_LTYPE_IS_SUBMSG(iter->type))
56
67.6k
        {
57
67.6k
            validate_message(pData, 0, iter->submsg_desc);
58
67.6k
        }
59
705k
    }
60
800k
}
61
62
void validate_pointer(pb_field_iter_t *iter)
63
7.55M
{
64
7.55M
    pb_size_t count = 1;
65
7.55M
    pb_size_t i;
66
7.55M
    bool truebool = true;
67
7.55M
    bool falsebool = false;
68
69
7.55M
    if (PB_HTYPE(iter->type) == PB_HTYPE_ONEOF)
70
28.2k
    {
71
28.2k
        if (*(pb_size_t*)iter->pSize != iter->tag)
72
26.8k
        {
73
            /* Some different field in oneof */
74
26.8k
            return;
75
26.8k
        }
76
28.2k
    }
77
7.53M
    else if (!iter->pData)
78
7.11M
    {
79
        /* Nothing allocated */
80
7.11M
        if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED && iter->pSize != &iter->array_size)
81
245k
        {
82
245k
            assert(*(pb_size_t*)iter->pSize == 0);
83
245k
        }
84
7.11M
        return;
85
7.11M
    }
86
87
416k
    if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED)
88
23.2k
    {
89
        /* Check that enough memory has been allocated for array */
90
23.2k
        size_t allocated_size = get_allocation_size(iter->pData);
91
23.2k
        count = *(pb_size_t*)iter->pSize;
92
23.2k
        assert(allocated_size >= count * iter->data_size);
93
23.2k
    }
94
393k
    else if (PB_LTYPE(iter->type) != PB_LTYPE_STRING && PB_LTYPE(iter->type) != PB_LTYPE_BYTES)
95
316k
    {
96
316k
        size_t allocated_size = get_allocation_size(iter->pData);
97
316k
        assert(allocated_size >= iter->data_size);
98
316k
    }
99
100
76.8M
    for (i = 0; i < count; i++)
101
76.4M
    {
102
76.4M
        void *pData = (char*)iter->pData + iter->data_size * i;
103
104
76.4M
        if (PB_LTYPE(iter->type) == PB_LTYPE_STRING)
105
127k
        {
106
            /* Check that enough memory is allocated for string and that
107
               the string is properly terminated. */
108
127k
            const char *str = pData;
109
110
127k
            if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED)
111
58.9k
            {
112
                /* String arrays are stored as array of pointers */
113
58.9k
                str = ((const char**)iter->pData)[i];
114
58.9k
            }
115
116
127k
            assert(strlen(str) + 1 <= get_allocation_size(str));
117
127k
        }
118
76.3M
        else if (PB_LTYPE(iter->type) == PB_LTYPE_BYTES)
119
1.33M
        {
120
            /* Bytes length must be at most statically allocated size */
121
1.33M
            const pb_bytes_array_t *bytes = pData;
122
123
1.33M
            if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED)
124
1.32M
            {
125
                /* Bytes arrays are stored as array of pointers */
126
1.32M
                bytes = ((const pb_bytes_array_t**)iter->pData)[i];
127
1.32M
            }
128
129
1.33M
            assert(PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) <= get_allocation_size(bytes));
130
1.33M
        }
131
74.9M
        else if (PB_LTYPE(iter->type) == PB_LTYPE_BOOL)
132
4.70M
        {
133
            /* Bool fields must have valid value */
134
4.70M
            assert(memcmp(pData, &truebool, sizeof(bool)) == 0 ||
135
4.70M
                   memcmp(pData, &falsebool, sizeof(bool)) == 0);
136
4.70M
        }
137
70.2M
        else if (PB_LTYPE_IS_SUBMSG(iter->type))
138
2.33M
        {
139
2.33M
            validate_message(pData, 0, iter->submsg_desc);
140
2.33M
        }
141
76.4M
    }
142
416k
}
143
144
void validate_message(const void *msg, size_t structsize, const pb_msgdesc_t *msgtype)
145
2.42M
{
146
2.42M
    pb_field_iter_t iter;
147
148
2.42M
    if (pb_field_iter_begin_const(&iter, msgtype, msg))
149
2.32M
    {
150
2.32M
        do
151
8.41M
        {
152
8.41M
            if (PB_ATYPE(iter.type) == PB_ATYPE_STATIC)
153
844k
            {
154
844k
                validate_static(&iter);
155
844k
            }
156
7.56M
            else if (PB_ATYPE(iter.type) == PB_ATYPE_POINTER)
157
7.55M
            {
158
7.55M
                validate_pointer(&iter);
159
7.55M
            }
160
8.41M
        } while (pb_field_iter_next(&iter));
161
2.32M
    }
162
2.42M
}
163