/src/nanopb/tests/build/fuzztest/validation.c
Line | Count | Source (jump to first uncovered line) |
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 | 6.16k | { |
8 | 6.16k | pb_size_t count = 1; |
9 | 6.16k | pb_size_t i; |
10 | 6.16k | bool truebool = true; |
11 | 6.16k | bool falsebool = false; |
12 | | |
13 | 6.16k | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED && iter->pSize) |
14 | 0 | { |
15 | | /* Array count must be between 0 and statically allocated size */ |
16 | 0 | count = *(pb_size_t*)iter->pSize; |
17 | 0 | assert(count <= iter->array_size); |
18 | 0 | } |
19 | 6.16k | else if (PB_HTYPE(iter->type) == PB_HTYPE_OPTIONAL && iter->pSize) |
20 | 0 | { |
21 | | /* Boolean has_ field must have a valid value */ |
22 | 0 | assert(memcmp(iter->pSize, &truebool, sizeof(bool)) == 0 || |
23 | 0 | memcmp(iter->pSize, &falsebool, sizeof(bool)) == 0); |
24 | 0 | } |
25 | 6.16k | else if (PB_HTYPE(iter->type) == PB_HTYPE_ONEOF) |
26 | 6.16k | { |
27 | 6.16k | if (*(pb_size_t*)iter->pSize != iter->tag) |
28 | 6.00k | { |
29 | | /* Some different field in oneof */ |
30 | 6.00k | return; |
31 | 6.00k | } |
32 | 6.16k | } |
33 | | |
34 | 330 | for (i = 0; i < count; i++) |
35 | 165 | { |
36 | 165 | void *pData = (char*)iter->pData + iter->data_size * i; |
37 | | |
38 | 165 | if (PB_LTYPE(iter->type) == PB_LTYPE_STRING) |
39 | 0 | { |
40 | | /* String length must be at most statically allocated size */ |
41 | 0 | assert(strlen(pData) + 1 <= iter->data_size); |
42 | 0 | } |
43 | 165 | else if (PB_LTYPE(iter->type) == PB_LTYPE_BYTES) |
44 | 0 | { |
45 | | /* Bytes length must be at most statically allocated size */ |
46 | 0 | pb_bytes_array_t *bytes = pData; |
47 | 0 | assert(PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) <= iter->data_size); |
48 | 0 | } |
49 | 165 | else if (PB_LTYPE(iter->type) == PB_LTYPE_BOOL) |
50 | 0 | { |
51 | | /* Bool fields must have valid value */ |
52 | 0 | assert(memcmp(pData, &truebool, sizeof(bool)) == 0 || |
53 | 0 | memcmp(pData, &falsebool, sizeof(bool)) == 0); |
54 | 0 | } |
55 | 165 | else if (PB_LTYPE_IS_SUBMSG(iter->type)) |
56 | 165 | { |
57 | 165 | validate_message(pData, 0, iter->submsg_desc); |
58 | 165 | } |
59 | 165 | } |
60 | 165 | } |
61 | | |
62 | | void validate_pointer(pb_field_iter_t *iter) |
63 | 649k | { |
64 | 649k | pb_size_t count = 1; |
65 | 649k | pb_size_t i; |
66 | 649k | bool truebool = true; |
67 | 649k | bool falsebool = false; |
68 | | |
69 | 649k | if (PB_HTYPE(iter->type) == PB_HTYPE_ONEOF) |
70 | 12.3k | { |
71 | 12.3k | if (*(pb_size_t*)iter->pSize != iter->tag) |
72 | 11.8k | { |
73 | | /* Some different field in oneof */ |
74 | 11.8k | return; |
75 | 11.8k | } |
76 | 12.3k | } |
77 | 637k | else if (!iter->pData) |
78 | 278k | { |
79 | | /* Nothing allocated */ |
80 | 278k | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED && iter->pSize != &iter->array_size) |
81 | 107k | { |
82 | 107k | assert(*(pb_size_t*)iter->pSize == 0); |
83 | 107k | } |
84 | 278k | return; |
85 | 278k | } |
86 | | |
87 | 359k | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED) |
88 | 9.86k | { |
89 | | /* Check that enough memory has been allocated for array */ |
90 | 9.86k | size_t allocated_size = get_allocation_size(iter->pData); |
91 | 9.86k | count = *(pb_size_t*)iter->pSize; |
92 | 9.86k | assert(allocated_size >= count * iter->data_size); |
93 | 9.86k | } |
94 | 349k | else if (PB_LTYPE(iter->type) != PB_LTYPE_STRING && PB_LTYPE(iter->type) != PB_LTYPE_BYTES) |
95 | 294k | { |
96 | 294k | size_t allocated_size = get_allocation_size(iter->pData); |
97 | 294k | assert(allocated_size >= iter->data_size); |
98 | 294k | } |
99 | | |
100 | 36.8M | for (i = 0; i < count; i++) |
101 | 36.4M | { |
102 | 36.4M | void *pData = (char*)iter->pData + iter->data_size * i; |
103 | | |
104 | 36.4M | if (PB_LTYPE(iter->type) == PB_LTYPE_STRING) |
105 | 78.8k | { |
106 | | /* Check that enough memory is allocated for string and that |
107 | | the string is properly terminated. */ |
108 | 78.8k | const char *str = pData; |
109 | | |
110 | 78.8k | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED) |
111 | 30.4k | { |
112 | | /* String arrays are stored as array of pointers */ |
113 | 30.4k | str = ((const char**)iter->pData)[i]; |
114 | 30.4k | } |
115 | | |
116 | 78.8k | assert(strlen(str) + 1 <= get_allocation_size(str)); |
117 | 78.8k | } |
118 | 36.3M | else if (PB_LTYPE(iter->type) == PB_LTYPE_BYTES) |
119 | 538k | { |
120 | | /* Bytes length must be at most statically allocated size */ |
121 | 538k | const pb_bytes_array_t *bytes = pData; |
122 | | |
123 | 538k | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED) |
124 | 531k | { |
125 | | /* Bytes arrays are stored as array of pointers */ |
126 | 531k | bytes = ((const pb_bytes_array_t**)iter->pData)[i]; |
127 | 531k | } |
128 | | |
129 | 538k | assert(PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) <= get_allocation_size(bytes)); |
130 | 538k | } |
131 | 35.8M | else if (PB_LTYPE(iter->type) == PB_LTYPE_BOOL) |
132 | 2.27M | { |
133 | | /* Bool fields must have valid value */ |
134 | 2.27M | assert(memcmp(pData, &truebool, sizeof(bool)) == 0 || |
135 | 2.27M | memcmp(pData, &falsebool, sizeof(bool)) == 0); |
136 | 2.27M | } |
137 | 33.5M | else if (PB_LTYPE_IS_SUBMSG(iter->type)) |
138 | 136k | { |
139 | 136k | validate_message(pData, 0, iter->submsg_desc); |
140 | 136k | } |
141 | 36.4M | } |
142 | 359k | } |
143 | | |
144 | | void validate_message(const void *msg, size_t structsize, const pb_msgdesc_t *msgtype) |
145 | 142k | { |
146 | 142k | pb_field_iter_t iter; |
147 | | |
148 | 142k | if (pb_field_iter_begin_const(&iter, msgtype, msg)) |
149 | 66.6k | { |
150 | 66.6k | do |
151 | 662k | { |
152 | 662k | if (PB_ATYPE(iter.type) == PB_ATYPE_STATIC) |
153 | 6.16k | { |
154 | 6.16k | validate_static(&iter); |
155 | 6.16k | } |
156 | 656k | else if (PB_ATYPE(iter.type) == PB_ATYPE_POINTER) |
157 | 649k | { |
158 | 649k | validate_pointer(&iter); |
159 | 649k | } |
160 | 662k | } while (pb_field_iter_next(&iter)); |
161 | 66.6k | } |
162 | 142k | } |
163 | | |