/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 | 829k | { |
8 | 829k | pb_size_t count = 1; |
9 | 829k | pb_size_t i; |
10 | 829k | bool truebool = true; |
11 | 829k | bool falsebool = false; |
12 | | |
13 | 829k | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED && iter->pSize) |
14 | 214k | { |
15 | | /* Array count must be between 0 and statically allocated size */ |
16 | 214k | count = *(pb_size_t*)iter->pSize; |
17 | 214k | assert(count <= iter->array_size); |
18 | 214k | } |
19 | 615k | else if (PB_HTYPE(iter->type) == PB_HTYPE_OPTIONAL && iter->pSize) |
20 | 132k | { |
21 | | /* Boolean has_ field must have a valid value */ |
22 | 132k | assert(memcmp(iter->pSize, &truebool, sizeof(bool)) == 0 || |
23 | 132k | memcmp(iter->pSize, &falsebool, sizeof(bool)) == 0); |
24 | 132k | } |
25 | 483k | else if (PB_HTYPE(iter->type) == PB_HTYPE_ONEOF) |
26 | 46.6k | { |
27 | 46.6k | 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.6k | } |
33 | | |
34 | 1.46M | for (i = 0; i < count; i++) |
35 | 683k | { |
36 | 683k | void *pData = (char*)iter->pData + iter->data_size * i; |
37 | | |
38 | 683k | if (PB_LTYPE(iter->type) == PB_LTYPE_STRING) |
39 | 43.8k | { |
40 | | /* String length must be at most statically allocated size */ |
41 | 43.8k | assert(strlen(pData) + 1 <= iter->data_size); |
42 | 43.8k | } |
43 | 639k | else if (PB_LTYPE(iter->type) == PB_LTYPE_BYTES) |
44 | 18.6k | { |
45 | | /* Bytes length must be at most statically allocated size */ |
46 | 18.6k | pb_bytes_array_t *bytes = pData; |
47 | 18.6k | assert(PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) <= iter->data_size); |
48 | 18.6k | } |
49 | 620k | else if (PB_LTYPE(iter->type) == PB_LTYPE_BOOL) |
50 | 19.2k | { |
51 | | /* Bool fields must have valid value */ |
52 | 19.2k | assert(memcmp(pData, &truebool, sizeof(bool)) == 0 || |
53 | 19.2k | memcmp(pData, &falsebool, sizeof(bool)) == 0); |
54 | 19.2k | } |
55 | 601k | else if (PB_LTYPE_IS_SUBMSG(iter->type)) |
56 | 65.8k | { |
57 | 65.8k | validate_message(pData, 0, iter->submsg_desc); |
58 | 65.8k | } |
59 | 683k | } |
60 | 785k | } |
61 | | |
62 | | void validate_pointer(pb_field_iter_t *iter) |
63 | 4.48M | { |
64 | 4.48M | pb_size_t count = 1; |
65 | 4.48M | pb_size_t i; |
66 | 4.48M | bool truebool = true; |
67 | 4.48M | bool falsebool = false; |
68 | | |
69 | 4.48M | if (PB_HTYPE(iter->type) == PB_HTYPE_ONEOF) |
70 | 29.0k | { |
71 | 29.0k | if (*(pb_size_t*)iter->pSize != iter->tag) |
72 | 27.6k | { |
73 | | /* Some different field in oneof */ |
74 | 27.6k | return; |
75 | 27.6k | } |
76 | 29.0k | } |
77 | 4.45M | else if (!iter->pData) |
78 | 4.05M | { |
79 | | /* Nothing allocated */ |
80 | 4.05M | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED && iter->pSize != &iter->array_size) |
81 | 256k | { |
82 | 256k | assert(*(pb_size_t*)iter->pSize == 0); |
83 | 256k | } |
84 | 4.05M | return; |
85 | 4.05M | } |
86 | | |
87 | 402k | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED) |
88 | 19.9k | { |
89 | | /* Check that enough memory has been allocated for array */ |
90 | 19.9k | size_t allocated_size = get_allocation_size(iter->pData); |
91 | 19.9k | count = *(pb_size_t*)iter->pSize; |
92 | 19.9k | assert(allocated_size >= count * iter->data_size); |
93 | 19.9k | } |
94 | 382k | else if (PB_LTYPE(iter->type) != PB_LTYPE_STRING && PB_LTYPE(iter->type) != PB_LTYPE_BYTES) |
95 | 304k | { |
96 | 304k | size_t allocated_size = get_allocation_size(iter->pData); |
97 | 304k | assert(allocated_size >= iter->data_size); |
98 | 304k | } |
99 | | |
100 | 70.7M | for (i = 0; i < count; i++) |
101 | 70.3M | { |
102 | 70.3M | void *pData = (char*)iter->pData + iter->data_size * i; |
103 | | |
104 | 70.3M | if (PB_LTYPE(iter->type) == PB_LTYPE_STRING) |
105 | 98.1k | { |
106 | | /* Check that enough memory is allocated for string and that |
107 | | the string is properly terminated. */ |
108 | 98.1k | const char *str = pData; |
109 | | |
110 | 98.1k | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED) |
111 | 28.3k | { |
112 | | /* String arrays are stored as array of pointers */ |
113 | 28.3k | str = ((const char**)iter->pData)[i]; |
114 | 28.3k | } |
115 | | |
116 | 98.1k | assert(strlen(str) + 1 <= get_allocation_size(str)); |
117 | 98.1k | } |
118 | 70.2M | else if (PB_LTYPE(iter->type) == PB_LTYPE_BYTES) |
119 | 1.44M | { |
120 | | /* Bytes length must be at most statically allocated size */ |
121 | 1.44M | const pb_bytes_array_t *bytes = pData; |
122 | | |
123 | 1.44M | if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED) |
124 | 1.43M | { |
125 | | /* Bytes arrays are stored as array of pointers */ |
126 | 1.43M | bytes = ((const pb_bytes_array_t**)iter->pData)[i]; |
127 | 1.43M | } |
128 | | |
129 | 1.44M | assert(PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) <= get_allocation_size(bytes)); |
130 | 1.44M | } |
131 | 68.7M | else if (PB_LTYPE(iter->type) == PB_LTYPE_BOOL) |
132 | 5.76M | { |
133 | | /* Bool fields must have valid value */ |
134 | 5.76M | assert(memcmp(pData, &truebool, sizeof(bool)) == 0 || |
135 | 5.76M | memcmp(pData, &falsebool, sizeof(bool)) == 0); |
136 | 5.76M | } |
137 | 63.0M | else if (PB_LTYPE_IS_SUBMSG(iter->type)) |
138 | 1.29M | { |
139 | 1.29M | validate_message(pData, 0, iter->submsg_desc); |
140 | 1.29M | } |
141 | 70.3M | } |
142 | 402k | } |
143 | | |
144 | | void validate_message(const void *msg, size_t structsize, const pb_msgdesc_t *msgtype) |
145 | 1.38M | { |
146 | 1.38M | pb_field_iter_t iter; |
147 | | |
148 | 1.38M | if (pb_field_iter_begin_const(&iter, msgtype, msg)) |
149 | 1.29M | { |
150 | 1.29M | do |
151 | 5.32M | { |
152 | 5.32M | if (PB_ATYPE(iter.type) == PB_ATYPE_STATIC) |
153 | 829k | { |
154 | 829k | validate_static(&iter); |
155 | 829k | } |
156 | 4.49M | else if (PB_ATYPE(iter.type) == PB_ATYPE_POINTER) |
157 | 4.48M | { |
158 | 4.48M | validate_pointer(&iter); |
159 | 4.48M | } |
160 | 5.32M | } while (pb_field_iter_next(&iter)); |
161 | 1.29M | } |
162 | 1.38M | } |
163 | | |