/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 | 879k | { |
8 | 879k | pb_size_t count = 1; |
9 | 879k | pb_size_t i; |
10 | 879k | bool truebool = true; |
11 | 879k | bool falsebool = false; |
12 | | |
13 | 879k | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED && iter->pSize) |
14 | 227k | { |
15 | | /* Array count must be between 0 and statically allocated size */ |
16 | 227k | count = *(pb_size_t*)iter->pSize; |
17 | 227k | assert(count <= iter->array_size); |
18 | 227k | } |
19 | 652k | else if (PB_HTYPE(iter->type) == PB_HTYPE_OPTIONAL && iter->pSize) |
20 | 140k | { |
21 | | /* Boolean has_ field must have a valid value */ |
22 | 140k | assert(memcmp(iter->pSize, &truebool, sizeof(bool)) == 0 || |
23 | 140k | memcmp(iter->pSize, &falsebool, sizeof(bool)) == 0); |
24 | 140k | } |
25 | 512k | else if (PB_HTYPE(iter->type) == PB_HTYPE_ONEOF) |
26 | 48.6k | { |
27 | 48.6k | if (*(pb_size_t*)iter->pSize != iter->tag) |
28 | 45.7k | { |
29 | | /* Some different field in oneof */ |
30 | 45.7k | return; |
31 | 45.7k | } |
32 | 48.6k | } |
33 | | |
34 | 1.55M | for (i = 0; i < count; i++) |
35 | 725k | { |
36 | 725k | void *pData = (char*)iter->pData + iter->data_size * i; |
37 | | |
38 | 725k | if (PB_LTYPE(iter->type) == PB_LTYPE_STRING) |
39 | 46.5k | { |
40 | | /* String length must be at most statically allocated size */ |
41 | 46.5k | assert(strlen(pData) + 1 <= iter->data_size); |
42 | 46.5k | } |
43 | 678k | else if (PB_LTYPE(iter->type) == PB_LTYPE_BYTES) |
44 | 20.0k | { |
45 | | /* Bytes length must be at most statically allocated size */ |
46 | 20.0k | pb_bytes_array_t *bytes = pData; |
47 | 20.0k | assert(PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) <= iter->data_size); |
48 | 20.0k | } |
49 | 658k | else if (PB_LTYPE(iter->type) == PB_LTYPE_BOOL) |
50 | 20.1k | { |
51 | | /* Bool fields must have valid value */ |
52 | 20.1k | assert(memcmp(pData, &truebool, sizeof(bool)) == 0 || |
53 | 20.1k | memcmp(pData, &falsebool, sizeof(bool)) == 0); |
54 | 20.1k | } |
55 | 638k | else if (PB_LTYPE_IS_SUBMSG(iter->type)) |
56 | 69.9k | { |
57 | 69.9k | validate_message(pData, 0, iter->submsg_desc); |
58 | 69.9k | } |
59 | 725k | } |
60 | 833k | } |
61 | | |
62 | | void validate_pointer(pb_field_iter_t *iter) |
63 | 6.54M | { |
64 | 6.54M | pb_size_t count = 1; |
65 | 6.54M | pb_size_t i; |
66 | 6.54M | bool truebool = true; |
67 | 6.54M | bool falsebool = false; |
68 | | |
69 | 6.54M | if (PB_HTYPE(iter->type) == PB_HTYPE_ONEOF) |
70 | 29.1k | { |
71 | 29.1k | if (*(pb_size_t*)iter->pSize != iter->tag) |
72 | 27.7k | { |
73 | | /* Some different field in oneof */ |
74 | 27.7k | return; |
75 | 27.7k | } |
76 | 29.1k | } |
77 | 6.52M | else if (!iter->pData) |
78 | 6.09M | { |
79 | | /* Nothing allocated */ |
80 | 6.09M | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED && iter->pSize != &iter->array_size) |
81 | 254k | { |
82 | 254k | assert(*(pb_size_t*)iter->pSize == 0); |
83 | 254k | } |
84 | 6.09M | return; |
85 | 6.09M | } |
86 | | |
87 | 428k | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED) |
88 | 22.2k | { |
89 | | /* Check that enough memory has been allocated for array */ |
90 | 22.2k | size_t allocated_size = get_allocation_size(iter->pData); |
91 | 22.2k | count = *(pb_size_t*)iter->pSize; |
92 | 22.2k | assert(allocated_size >= count * iter->data_size); |
93 | 22.2k | } |
94 | 406k | else if (PB_LTYPE(iter->type) != PB_LTYPE_STRING && PB_LTYPE(iter->type) != PB_LTYPE_BYTES) |
95 | 330k | { |
96 | 330k | size_t allocated_size = get_allocation_size(iter->pData); |
97 | 330k | assert(allocated_size >= iter->data_size); |
98 | 330k | } |
99 | | |
100 | 73.8M | for (i = 0; i < count; i++) |
101 | 73.4M | { |
102 | 73.4M | void *pData = (char*)iter->pData + iter->data_size * i; |
103 | | |
104 | 73.4M | if (PB_LTYPE(iter->type) == PB_LTYPE_STRING) |
105 | 139k | { |
106 | | /* Check that enough memory is allocated for string and that |
107 | | the string is properly terminated. */ |
108 | 139k | const char *str = pData; |
109 | | |
110 | 139k | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED) |
111 | 71.6k | { |
112 | | /* String arrays are stored as array of pointers */ |
113 | 71.6k | str = ((const char**)iter->pData)[i]; |
114 | 71.6k | } |
115 | | |
116 | 139k | assert(strlen(str) + 1 <= get_allocation_size(str)); |
117 | 139k | } |
118 | 73.2M | else if (PB_LTYPE(iter->type) == PB_LTYPE_BYTES) |
119 | 1.23M | { |
120 | | /* Bytes length must be at most statically allocated size */ |
121 | 1.23M | const pb_bytes_array_t *bytes = pData; |
122 | | |
123 | 1.23M | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED) |
124 | 1.22M | { |
125 | | /* Bytes arrays are stored as array of pointers */ |
126 | 1.22M | bytes = ((const pb_bytes_array_t**)iter->pData)[i]; |
127 | 1.22M | } |
128 | | |
129 | 1.23M | assert(PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) <= get_allocation_size(bytes)); |
130 | 1.23M | } |
131 | 72.0M | else if (PB_LTYPE(iter->type) == PB_LTYPE_BOOL) |
132 | 3.69M | { |
133 | | /* Bool fields must have valid value */ |
134 | 3.69M | assert(memcmp(pData, &truebool, sizeof(bool)) == 0 || |
135 | 3.69M | memcmp(pData, &falsebool, sizeof(bool)) == 0); |
136 | 3.69M | } |
137 | 68.3M | else if (PB_LTYPE_IS_SUBMSG(iter->type)) |
138 | 1.98M | { |
139 | 1.98M | validate_message(pData, 0, iter->submsg_desc); |
140 | 1.98M | } |
141 | 73.4M | } |
142 | 428k | } |
143 | | |
144 | | void validate_message(const void *msg, size_t structsize, const pb_msgdesc_t *msgtype) |
145 | 2.07M | { |
146 | 2.07M | pb_field_iter_t iter; |
147 | | |
148 | 2.07M | if (pb_field_iter_begin_const(&iter, msgtype, msg)) |
149 | 1.97M | { |
150 | 1.97M | do |
151 | 7.44M | { |
152 | 7.44M | if (PB_ATYPE(iter.type) == PB_ATYPE_STATIC) |
153 | 879k | { |
154 | 879k | validate_static(&iter); |
155 | 879k | } |
156 | 6.56M | else if (PB_ATYPE(iter.type) == PB_ATYPE_POINTER) |
157 | 6.54M | { |
158 | 6.54M | validate_pointer(&iter); |
159 | 6.54M | } |
160 | 7.44M | } while (pb_field_iter_next(&iter)); |
161 | 1.97M | } |
162 | 2.07M | } |
163 | | |